Skip to content

Commit

Permalink
chore(api): use multi stage docker build
Browse files Browse the repository at this point in the history
  • Loading branch information
open-dynaMIX committed Aug 26, 2024
1 parent 737bef9 commit b9153ee
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 38 deletions.
8 changes: 6 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@ jobs:
- name: Set UID
run: echo "UID=$(id --user)" > .env
- name: Build the containers
run: docker compose up -d --build api db
run: docker compose build --pull --force-rm api db
- name: Run the containers
run: docker compose up -d api db
- name: Lint the code
run: make api-lint
- name: logging
run: docker compose logs api
- name: Check for missing migrations
run: docker compose exec -T api poetry run ./manage.py makemigrations --check --dry-run --no-input
run: docker compose exec -T api ./manage.py makemigrations --check --dry-run --no-input
- name: Run test suite
run: make api-test
caluma-tests:
Expand Down
12 changes: 6 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,32 @@ start: ## Start the development server

.PHONY: api-test
api-test: ## Test the backend
@docker compose run --rm api poetry run pytest --no-cov-on-fail --cov -vv
@docker compose run --rm api pytest --no-cov-on-fail --cov -vv

.PHONY: api-lint
api-lint: ## Lint the backend
@docker compose run --rm api sh -c "poetry run ruff format --diff . && poetry run ruff check ."
@docker compose run --rm api sh -c "ruff format --diff . && ruff check ."

.PHONY: api-bash
api-bash: ## Shell into the backend
@docker compose run --rm api bash

.PHONY: api-shell_plus
api-shell_plus: ## Run shell_plus
@docker compose run --rm api poetry run ./manage.py shell_plus
@docker compose run --rm api ./manage.py shell_plus

.PHONY: api-dev-server
api-dev-server: ## Start backend dev server
@docker compose stop api
@docker compose run --user root --use-aliases --service-ports api bash -c 'pip install pdbpp && poetry run ./manage.py runserver 0.0.0.0:8000'
@docker compose run --user root --use-aliases --service-ports api bash -c 'pip install pdbpp && ./manage.py runserver 0.0.0.0:8000'

.PHONY: makemigrations
makemigrations: ## Make django migrations
@docker compose run --rm api poetry run ./manage.py makemigrations
@docker compose run --rm api ./manage.py makemigrations

.PHONY: migrate
migrate: ## Migrate django
@docker compose run --rm api poetry run ./manage.py migrate
@docker compose run --rm api ./manage.py migrate

.PHONY: dbshell
dbshell: ## Start a psql shell
Expand Down
80 changes: 54 additions & 26 deletions api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,38 +1,66 @@
FROM python:3.9
FROM python:3.12-alpine AS base

# needs to be set for users with manually set UID
ENV HOME=/home/mysagw
RUN apk update --no-cache && \
apk upgrade --no-cache && \
apk add wait4ports shadow libpq-dev --no-cache && \
useradd -m -r -u 1001 mysagw && \
apk del shadow && \
rm -rf /var/cache/apk/*

ENV PYTHONUNBUFFERED=1
ENV DJANGO_SETTINGS_MODULE mysagw.settings
ENV APP_HOME=/app
ENV DJANGO_SETTINGS_MODULE=mysagw.settings \
PYTHONFAULTHANDLER=1 \
PYTHONHASHSEED=random \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=off \
PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=100

RUN mkdir -p /app \
&& useradd -u 901 -r mysagw --create-home \
# all project specific folders need to be accessible by newly created user but also for unknown users (when UID is set manually). Such users are in group root.
&& chown -R mysagw:root /home/mysagw \
&& chmod -R 770 /home/mysagw \
&& apt-get update && apt-get install -y --no-install-recommends \
wait-for-it \
# needed for psycopg2
libpq-dev \
&& pip install -U poetry
EXPOSE 8000

USER mysagw
FROM base AS build

WORKDIR $APP_HOME
WORKDIR /app

ARG INSTALL_DEV_DEPENDENCIES=false
COPY pyproject.toml poetry.lock $APP_HOME/
RUN if [ "$INSTALL_DEV_DEPENDENCIES" = "true" ]; then poetry install --with dev; else poetry install; fi
COPY . ./

COPY . $APP_HOME
ENV POETRY_NO_INTERACTION=1 \
POETRY_VIRTUALENVS_CREATE=false

EXPOSE 8000
RUN pip install -U poetry

FROM build AS wheel

WORKDIR /app

RUN poetry build -f wheel && mv ./dist/*.whl /tmp/ && pip uninstall -y poetry

FROM build AS dev

WORKDIR /app

RUN poetry install --no-root

USER 1001

CMD [\
"/bin/sh", "-c", \
"wait4ports -s 15 tcp://${DATABASE_HOST:-db}:${DATABASE_PORT:-5432} && \
./manage.py migrate --no-input && \
./manage.py runserver 0.0.0.0:8000 -v 3" \
]

FROM base AS prod

COPY manage.py /usr/local/bin
COPY --from=wheel /tmp/*.whl /tmp/

RUN pip install /tmp/*.whl && rm /tmp/*.whl

USER 1001

CMD [\
"/bin/sh", "-c", \
"wait-for-it $DATABASE_HOST:${DATABASE_PORT:-5432} -- \
poetry run ./manage.py migrate && \
exec poetry run gunicorn --workers 10 --access-logfile - --limit-request-line 16384 --bind 0.0.0.0:8000 mysagw.wsgi" \
"wait4ports -s 15 tcp://${DATABASE_HOST:-db}:${DATABASE_PORT:-5432} && \
manage.py migrate --no-input && \
gunicorn --workers 10 --access-logfile - --limit-request-line 16384 --bind :8000 mysagw.wsgi" \
]
5 changes: 3 additions & 2 deletions api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ description = "Application management for SAGW"
repository = "https://github.com/adfinis/mySAGW"
authors = ["Adfinis"]
license = "GPL-3.0-or-later"
readme = "../README.md"

[tool.poetry.dependencies]
python = "^3.9"
Expand Down Expand Up @@ -132,7 +131,9 @@ filterwarnings = [
"ignore:distutils Version classes are deprecated. Use packaging.version instead.:DeprecationWarning", # issue in pytest-freezegun
"ignore:LocalizedAutoSlug is deprecated and will be removed in the next major version:DeprecationWarning",
"ignore:'django_extensions' defines default_app_config:PendingDeprecationWarning", # deprecation in django_extensions
"ignore:CSR support in pyOpenSSL is deprecated. You should use the APIs in cryptography.:DeprecationWarning", # deprecation in mozilla-django-oidc
"ignore:CSR support in pyOpenSSL is deprecated. You should use the APIs in cryptography.:DeprecationWarning", # deprecation in a dependency of mozilla-django-oidc
"ignore:ast.NameConstant is deprecated and will be removed in Python 3.14; use ast.Constant instead:DeprecationWarning", # deprecation from reportlab
"ignore:.*Use timezone-aware objects to represent datetimes in UTC.*:DeprecationWarning", # deprecation in openpyxl
]

[tool.coverage.run]
Expand Down
3 changes: 1 addition & 2 deletions docker-compose.override.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ services:
api:
build:
context: ./api/
args:
INSTALL_DEV_DEPENDENCIES: "true"
target: dev
user: "${UID:?Set UID env variable to your user id}"
volumes:
- ./api:/app
Expand Down

0 comments on commit b9153ee

Please sign in to comment.