From 065c831cdecefa517a0208ae765a047f28aef896 Mon Sep 17 00:00:00 2001 From: Tobias Quadfasel Date: Thu, 29 Aug 2024 16:28:21 +0200 Subject: [PATCH 1/3] feat(base-app): Add base dash app file This commit adds a file that contains a standard 'Hello World' example of a plotly dash app. --- app/app.py | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 app/app.py diff --git a/app/app.py b/app/app.py new file mode 100644 index 0000000..b758c56 --- /dev/null +++ b/app/app.py @@ -0,0 +1,8 @@ +from dash import Dash, html + +app = Dash() + +app.layout = [html.Div(children="Hello World")] + +if __name__ == "__main__": + app.run(debug=True) -- 2.49.1 From 25aeb62951c70d8f3ec8cc6324c8e9e67973669a Mon Sep 17 00:00:00 2001 From: Tobias Quadfasel Date: Thu, 29 Aug 2024 17:34:04 +0200 Subject: [PATCH 2/3] feat(base-app): Add gunicorn to dependencies --- app/app.py | 2 ++ poetry.lock | 23 ++++++++++++++++++++++- pyproject.toml | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/app/app.py b/app/app.py index b758c56..a83c9fc 100644 --- a/app/app.py +++ b/app/app.py @@ -4,5 +4,7 @@ app = Dash() app.layout = [html.Div(children="Hello World")] +server = app.server + if __name__ == "__main__": app.run(debug=True) diff --git a/poetry.lock b/poetry.lock index 42afb00..481b420 100644 --- a/poetry.lock +++ b/poetry.lock @@ -401,6 +401,27 @@ python-dateutil = ">=2.8.1" [package.extras] dev = ["flake8", "markdown", "twine", "wheel"] +[[package]] +name = "gunicorn" +version = "23.0.0" +description = "WSGI HTTP Server for UNIX" +optional = false +python-versions = ">=3.7" +files = [ + {file = "gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d"}, + {file = "gunicorn-23.0.0.tar.gz", hash = "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec"}, +] + +[package.dependencies] +packaging = "*" + +[package.extras] +eventlet = ["eventlet (>=0.24.1,!=0.36.0)"] +gevent = ["gevent (>=1.4.0)"] +setproctitle = ["setproctitle"] +testing = ["coverage", "eventlet", "gevent", "pytest", "pytest-cov"] +tornado = ["tornado (>=0.2)"] + [[package]] name = "identify" version = "2.6.0" @@ -1577,4 +1598,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "c0d0425486e160e85f7ee57c17e73f63d433313ccf6c980197258518427ae125" +content-hash = "1ace87aaeab8e9964d3f2e843eb5a0d15c1506bb0d1871dc41a9a38f5ed3a352" diff --git a/pyproject.toml b/pyproject.toml index ff83d4f..8d6ecb6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,7 @@ wrap-summaries = 100 python = "^3.10" plotly = "^5.23.0" dash = "^2.17.1" +gunicorn = "^23.0.0" [tool.poetry.group.docs.dependencies] mkdocs = "^1.6.0" -- 2.49.1 From 5a5f41246d4f41f3ded634ff3fc92df554f4df1c Mon Sep 17 00:00:00 2001 From: Tobias Quadfasel Date: Thu, 29 Aug 2024 17:35:14 +0200 Subject: [PATCH 3/3] feat(base-app): Add docker setup Adding a dockerfile as well as an `entrypoint.sh` file for deployment using `gunicorn`. --- .docker/entrypoint.sh | 5 +++++ Dockerfile | 45 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 .docker/entrypoint.sh create mode 100644 Dockerfile diff --git a/.docker/entrypoint.sh b/.docker/entrypoint.sh new file mode 100644 index 0000000..210c1fe --- /dev/null +++ b/.docker/entrypoint.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +# Start Dash and run in background +echo "Starting Dash app..." +poetry run gunicorn app:server -b 0.0.0.0:8000 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1b4dcf2 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,45 @@ +ARG PYTHON_VERSION_TAG=3.12 +ARG PYTHON_VARIANT_TAG=slim + +# Use official Python image as base +# ${PYTHON_VARIANT_TAG:+-${PYTHON_VARIANT_TAG}} is a conditional expansion +# that adds a dash before the variant tag if it is not empty +FROM python:${PYTHON_VERSION_TAG}${PYTHON_VARIANT_TAG:+-${PYTHON_VARIANT_TAG}} + +# Set up poetry environment +ARG POETRY_VERSION=1.8.3 + +ENV POETRY_HOME=/opt/poetry +ENV POETRY_VENV=/opt/poetry-venv +ENV POETRY_CACHE_DIR=/opt/.cache + +# Install poetry separated from system interpreter +RUN python3 -m venv $POETRY_VENV \ + && $POETRY_VENV/bin/pip install -U pip setuptools \ + && $POETRY_VENV/bin/pip install poetry==${POETRY_VERSION} + +# Add `poetry` to PATH +ENV PATH="${POETRY_VENV}/bin:${PATH}" + +RUN poetry config virtualenvs.in-project true + +# Export in first position so that "python" calls are from .venv +ENV PATH="/app/.venv/bin:${PATH}" +ENV PYTHONPATH="/app/:${PYTHONPATH}" + +COPY pyproject.toml . +COPY poetry.lock . +COPY app/ app/ + +RUN poetry install --no-interaction --no-dev + +COPY ./.docker/entrypoint.sh /app/entrypoint.sh +RUN chmod +x /app/entrypoint.sh + +WORKDIR /app + + +EXPOSE 80 +EXPOSE 8000 + +ENTRYPOINT ["./entrypoint.sh"] -- 2.49.1