diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..fbfa7d1 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +**/*.pyc diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d3150aa --- /dev/null +++ b/Dockerfile @@ -0,0 +1,51 @@ +FROM python:3.11-slim-bookworm AS env-builder + +WORKDIR /app + +COPY pyproject.toml . +COPY poetry.lock . + +# create virtual environment +RUN python -m venv /venv + +# set python thingies, set environment variables and activate virtual environment +ENV \ + PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + PATH="/venv/bin:$PATH" + +RUN \ + pip install poetry && \ + # dump python dependencies into requirements file + poetry export --without-hashes --format=requirements.txt > requirements.txt && \ + # install python libs + pip install -r requirements.txt --no-cache-dir --prefer-binary --no-deps --no-compile + + +FROM python:3.11-slim-bookworm + +WORKDIR /app + +COPY --from=env-builder /venv /venv + +# set python thingies and activate virtual environment +ENV \ + PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + PATH="/venv/bin:$PATH" + +COPY manage.py . +COPY pyproject.toml . +COPY poetry.lock . +COPY db.template.sqlite3 db.sqlite3 +COPY ./project ./project + +# run as user www-data +USER 33 + +ENTRYPOINT [ "/venv/bin/gunicorn" ] +CMD [ \ + "--bind", "0.0.0.0:8000", \ + "--workers", "4", \ + "project.wsgi" \ +] diff --git a/Makefile b/Makefile index c9d9c37..97b6f3c 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,7 @@ +CONTAINER_NAME=django-htmx +IMAGE_NAME=django-htmx + + ifeq ($(VIRTUAL_ENV),) RUN_IN_ENV=poetry run else @@ -19,3 +23,20 @@ migrations: migrate: @ $(RUN_IN_ENV) python manage.py migrate + + +docker-build: + - @docker image rm $(IMAGE_NAME) --force + @docker \ + build . \ + -t $(IMAGE_NAME) + @docker \ + build . \ + -t $(IMAGE_NAME) + + +docker-run: + @docker run \ + --publish 8000:8000 \ + --name $(CONTAINER_NAME) \ + $(IMAGE_NAME) diff --git a/README.md b/README.md index e8edad4..cf1357a 100644 --- a/README.md +++ b/README.md @@ -1 +1,36 @@ # Django-htmx demo + +## Run demo + +### As docker container + +``` +make docker-build +make docker-run +``` + +Browse to [localhost:8000](http://localhost:8000). + +Later, start and stop docker container using: + +``` +docker start django-htmx +``` + +and + +``` +docker stop django-htmx +``` + +### As standard local Django app + +- requirements: Python 3.10 or 3.11 +- [poetry](https://python-poetry.org) + +``` +poetry install +make run +``` + +Browse to [localhost:8000](http://localhost:8000). diff --git a/poetry.lock b/poetry.lock index e00db63..f011264 100644 --- a/poetry.lock +++ b/poetry.lock @@ -19,13 +19,13 @@ tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] [[package]] name = "django" -version = "5.0.4" +version = "5.0.6" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." optional = false python-versions = ">=3.10" files = [ - {file = "Django-5.0.4-py3-none-any.whl", hash = "sha256:916423499d75d62da7aa038d19aef23d23498d8df229775eb0a6309ee1013775"}, - {file = "Django-5.0.4.tar.gz", hash = "sha256:4bd01a8c830bb77a8a3b0e7d8b25b887e536ad17a81ba2dce5476135c73312bd"}, + {file = "Django-5.0.6-py3-none-any.whl", hash = "sha256:8363ac062bb4ef7c3f12d078f6fa5d154031d129a15170a1066412af49d30905"}, + {file = "Django-5.0.6.tar.gz", hash = "sha256:ff1b61005004e476e0aeea47c7f79b85864c70124030e95146315396f1e7951f"}, ] [package.dependencies] @@ -74,13 +74,13 @@ tornado = ["tornado (>=0.2)"] [[package]] name = "jinja2" -version = "3.1.3" +version = "3.1.4" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, - {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, ] [package.dependencies] @@ -171,19 +171,18 @@ files = [ [[package]] name = "sqlparse" -version = "0.4.4" +version = "0.5.0" description = "A non-validating SQL parser." optional = false -python-versions = ">=3.5" +python-versions = ">=3.8" files = [ - {file = "sqlparse-0.4.4-py3-none-any.whl", hash = "sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3"}, - {file = "sqlparse-0.4.4.tar.gz", hash = "sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c"}, + {file = "sqlparse-0.5.0-py3-none-any.whl", hash = "sha256:c204494cd97479d0e39f28c93d46c0b2d5959c7b9ab904762ea6c7af211c8663"}, + {file = "sqlparse-0.5.0.tar.gz", hash = "sha256:714d0a4932c059d16189f58ef5411ec2287a4360f17cdd0edd2d09d4c5087c93"}, ] [package.extras] -dev = ["build", "flake8"] +dev = ["build", "hatch"] doc = ["sphinx"] -test = ["pytest", "pytest-cov"] [[package]] name = "typing-extensions" @@ -209,5 +208,5 @@ files = [ [metadata] lock-version = "2.0" -python-versions = "^3.10" -content-hash = "6c86d5721314c92afa919983780e664a1573ebb7c25a8b54622393b97990e509" +python-versions = ">= 3.10, < 3.12" +content-hash = "26984438b0e835c052014186db2a76cbe044e19fd5b56ba3fc3d642b2ed530dc" diff --git a/pyproject.toml b/pyproject.toml index c612ab4..4c24ab2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ authors = ["Eden Kirin "] readme = "README.md" [tool.poetry.dependencies] -python = "^3.10" +python = ">= 3.10, < 3.12" django = "^5.0.4" django-jinja = "^2.11.0" gunicorn = "^21.2.0"