Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
62ad5f8
build: Create dockerfile without
crosspolar Nov 20, 2025
1b5f41b
move drf-spectacular and icecream to prod
crosspolar Nov 20, 2025
3509e63
add dockerfile for prod
crosspolar Nov 20, 2025
d5bf3b8
Revert "build: Create dockerfile without"
crosspolar Nov 20, 2025
590468e
remove poetry and initiate first-attempt of multi-stage and add user...
crosspolar Nov 24, 2025
8b3d1c1
linux reduce installed packages
crosspolar Nov 24, 2025
a14ec3c
comments
crosspolar Nov 24, 2025
5548afd
use python-slim with weasyprint-dependencies
crosspolar Nov 24, 2025
cef345a
set DEV in Dockerfile to decide whether to install dev-dependencies o…
crosspolar Nov 26, 2025
629e4f0
install poetry the curl-way (more recommended)
crosspolar Nov 26, 2025
16b6f71
remove unneeded COPY
crosspolar Nov 26, 2025
8f1735d
smaller apt-get in second layer
crosspolar Nov 26, 2025
6e36394
remove \
crosspolar Dec 16, 2025
3a823cb
remove obsolete prod reference
crosspolar Dec 16, 2025
c64a61e
compilemessages in dockerfile
crosspolar Dec 17, 2025
33b7099
Merge branch 'master' into dockerfile_without_poetry_dev_dependencies
crosspolar Feb 1, 2026
01fd77f
poetry lock
crosspolar Feb 1, 2026
97dc198
use uid 1000
crosspolar Feb 1, 2026
ca31ccb
have git installed in container
crosspolar Feb 1, 2026
47184be
update translation
crosspolar Feb 1, 2026
17716db
fix: reintroduce cd
crosspolar Feb 1, 2026
4af8d73
test if adding user 1000 to compose-run helps
crosspolar Feb 1, 2026
7c7f53d
temp add ls -la
crosspolar Feb 1, 2026
70bab2b
temp add ls -la 2
crosspolar Feb 1, 2026
23c804d
$(id -u):$(id -g)
crosspolar Feb 1, 2026
8312b7a
fix $(id -u):$(id -g)
crosspolar Feb 1, 2026
5faddcf
add $(id -u):$(id -g) to test
crosspolar Feb 1, 2026
f771e9c
add $(id -u):$(id -g) to to documentation
crosspolar Feb 1, 2026
a9d7a20
Make sure no write permissions are assigned to the copied resource.
crosspolar Feb 1, 2026
ab98ef8
username nonroot
crosspolar Feb 1, 2026
b4e167b
Revert "Make sure no write permissions are assigned to the copied res…
crosspolar Feb 1, 2026
393cd13
username nonroot
crosspolar Feb 1, 2026
1e3e0ac
copy only specific files, loose general writing-permission and hence …
crosspolar Feb 1, 2026
44fb9de
create volume only here to get coverage.xml
crosspolar Feb 1, 2026
7526e13
chown app before writing
crosspolar Feb 1, 2026
facc760
use env, if available
crosspolar Feb 3, 2026
ebcd700
Merge branch 'master' into dockerfile_without_poetry_dev_dependencies
crosspolar Feb 7, 2026
245c7d7
poetry lock: only changed content hash
crosspolar Feb 7, 2026
bd48180
remove auto-purge (same as removing lists it seems)
crosspolar Feb 8, 2026
ee3c379
give nonroot-user full permission of app-directory, otherwise thos jo…
crosspolar Feb 8, 2026
eee1c6f
remove comment
crosspolar Feb 8, 2026
d509691
remove chown -R $USERNAME:$USERNAME /app
crosspolar Feb 8, 2026
075358b
use tempfile-package
crosspolar Feb 8, 2026
d097d31
mock tempfile
crosspolar Feb 8, 2026
684744d
add prexix -
crosspolar Feb 8, 2026
bbead6b
Merge branch 'master' into dockerfile_without_poetry_dev_dependencies
crosspolar Feb 21, 2026
d9171ed
omit -L when installing poetry
crosspolar Feb 21, 2026
ce7efda
merge tests
crosspolar Feb 22, 2026
7be9980
remove unlink
crosspolar Feb 22, 2026
e7fd7d5
remove tmp
crosspolar Feb 22, 2026
a88b14f
make sure members-current is written to correct target file
crosspolar Feb 22, 2026
9f9f62b
remove unused EXPORT_FILE
crosspolar Feb 22, 2026
0d214f7
use tempfile.TemporaryFile
crosspolar Feb 22, 2026
3389b9f
Update django.Dockerfile
crosspolar Feb 27, 2026
afcf5e2
Merge branch 'master' into dockerfile_without_poetry_dev_dependencies
crosspolar Mar 28, 2026
dd04093
poetry lock
crosspolar Mar 28, 2026
0ca6877
use TapirUserFactory.create()
crosspolar Mar 28, 2026
a26ee07
fix: duplicated args in compose
crosspolar Mar 28, 2026
76a6dea
remove --user=$(id -u):$(id -g)
crosspolar Mar 29, 2026
30cf98f
you need to export GID AND UID
crosspolar Mar 29, 2026
a23c0d6
you need to export GID AND UID to checks.yml too
crosspolar Mar 29, 2026
a24d3e5
set default in compose not in dockerfile
crosspolar Mar 29, 2026
9426724
set USER_UID and USER_GID
crosspolar Mar 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ jobs:
- uses: actions/checkout@v6
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Export runner UID/GID
run: |
echo "USER_UID=$(id -u)" >> $GITHUB_ENV
echo "USER_GID=$(id -g)" >> $GITHUB_ENV
- name: Check formatting
run: docker compose run web make check-formatting
- name: Check translations
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ jobs:
- uses: actions/checkout@v6
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Export runner UID/GID
run: |
echo "USER_UID=$(id -u)" >> $GITHUB_ENV
echo "USER_GID=$(id -g)" >> $GITHUB_ENV
- name: Run Test
run: docker compose run web make test
run: docker compose run -v .:/app --rm web make test
- name: Upload coverage
uses: actions/upload-artifact@master
with:
Expand Down
12 changes: 6 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ The class name is the convention for the word in texts, followed by how to write
### Django Shell

```sh
docker compose exec web poetry run python manage.py shell_plus
docker compose exec web python manage.py shell_plus
```

### LDAP
Expand All @@ -129,7 +129,7 @@ docker compose up -d openldap
Then, run the tests.

```sh
docker compose run --rm web poetry run pytest
docker compose run --rm web pytest
```

The `--rm` option will delete the temporary containers created to run the tests. Omit it if you want to keep the
Expand All @@ -145,8 +145,8 @@ secret
To generate the translation files, first use "makemessages" and specify the language you want to generate:

```sh
docker compose exec -w /app/tapir web poetry run python ../manage.py makemessages --no-wrap -l de
docker compose run --rm -w /app web poetry run python manage.py makemessages --no-wrap -l de -d djangojs
docker compose exec -w /app/tapir web python ../manage.py makemessages --no-wrap -l de
docker compose run --rm -w /app web python manage.py makemessages --no-wrap -l de -d djangojs
```

Update tapir/translations/locale/de/LC_MESSAGES/django.po with your translations.
Expand Down Expand Up @@ -180,7 +180,7 @@ All changes must be done in the docker container. Since our development environm
docker container, you must run djangos makemigrations on docker. You can do this with this command:

```sh
docker compose exec web poetry run python manage.py makemigrations
docker compose exec web python manage.py makemigrations
```

Please check the migration script. It might contain unwished changes. There seems to be a bug in ldpa migrations.
Expand All @@ -190,7 +190,7 @@ Please check the migration script. It might contain unwished changes. There seem
Last step is to update the database. this is done with this command:

```sh
docker compose exec web poetry run python manage.py migrate
docker compose exec web python manage.py migrate
```

Please check, if applications runs (again).
Expand Down
11 changes: 6 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
lint:
poetry run black .
black .

check-formatting:
poetry run black --check .
black --check .

test:
poetry run pytest --cov-report xml:coverage.xml --cov=tapir --cov-config=pyproject.toml
pytest --cov-report xml:coverage.xml --cov=tapir --cov-config=pyproject.toml

check-translations:
ls -la /app
cp tapir/translations/locale/de/LC_MESSAGES/django.po tapir/translations/locale/de/LC_MESSAGES/django-old.po
cd tapir && poetry run python ../manage.py makemessages --no-wrap -l de
cd tapir && python ../manage.py makemessages --no-wrap -l de
git diff --ignore-matching-lines=POT-Creation-Date --exit-code --no-index tapir/translations/locale/de/LC_MESSAGES/django.po tapir/translations/locale/de/LC_MESSAGES/django-old.po
rm tapir/translations/locale/de/LC_MESSAGES/django-old.po

check-migrations:
poetry run python manage.py makemigrations --check
python manage.py makemigrations --check
96 changes: 81 additions & 15 deletions django.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,18 +1,84 @@
FROM python:3.13
ENV PYTHONUNBUFFERED=1
# syntax=docker/dockerfile:1
ARG USER_UID
ARG USER_GID


FROM python:3.13-slim AS build
ARG DEV=false
ENV POETRY_VERSION=2.2.1 \
PYTHONUNBUFFERED=1 \
# prevents python creating .pyc files
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=off \
PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=100 \
# make poetry install to this location
POETRY_HOME="/opt/poetry" \
# make poetry create the virtual environment in the project's root
# it gets named `.venv`
POETRY_VIRTUALENVS_IN_PROJECT=true \
# do not ask any interactive question
POETRY_NO_INTERACTION=1 \
# this is where our requirements + virtual environment will live
PYSETUP_PATH="/opt/pysetup" \
VENV_PATH="/opt/pysetup/.venv"

ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH"


RUN apt-get update \
&& apt-get install --no-install-recommends -y \
build-essential curl \
# psycopg2 dependencies
libpq-dev \
# Translations dependencies
gettext \
# LDAP dependencies
libldap2-dev libsasl2-dev \
# cleaning up unused files
&& rm -rf /var/lib/apt/lists/*

RUN curl -sS https://install.python-poetry.org | POETRY_HOME=$POETRY_HOME python3 - && \
ln -s $POETRY_HOME/bin/poetry /usr/local/bin/poetry

WORKDIR $PYSETUP_PATH

COPY poetry.lock pyproject.toml ./

RUN if [ "$DEV" = "true" ]; then \
poetry install --with dev --no-root; \
else \
poetry install --without dev --no-root; \
fi


FROM python:3.13-slim AS runtime
ARG USERNAME=nonroot
ARG ARG_VERSION
ARG USER_UID
ARG USER_GID
ENV TAPIR_VERSION=${ARG_VERSION}
ENV VENV_PATH="/opt/pysetup/.venv" \
PATH="/opt/pysetup/.venv/bin:$PATH"

RUN apt-get update \
&& apt-get install --no-install-recommends -y libpq-dev gettext libldap2-dev libsasl2-dev \
libpango-1.0-0 libpangoft2-1.0-0 libharfbuzz-subset0 \
make git \
&& rm -rf /var/lib/apt/lists/*

RUN groupadd --gid $USER_GID $USERNAME && \
useradd --uid $USER_UID --gid $USER_GID -m $USERNAME

WORKDIR /app
COPY . /app

RUN apt-get update -y \
&& apt-get --no-install-recommends install -y \
gettext \
libldap2-dev \
libsasl2-dev \
postgresql-client \
postgresql-client-common \
&& rm -rf /var/lib/apt/lists/* \
&& pip install poetry \
&& poetry install \
&& poetry run python manage.py compilemessages

COPY --from=build /opt/pysetup/.venv /opt/pysetup/.venv
COPY --from=build /opt/pysetup/ ./

COPY tapir /app/tapir
COPY manage.py /app/manage.py
COPY Makefile /app/Makefile

RUN python manage.py compilemessages

USER $USERNAME
21 changes: 11 additions & 10 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,17 @@ services:
web:
build:
context: .
args:
ARG_VERSION: ""
dockerfile: ./django.Dockerfile
command: bash -c "poetry install &&
poetry run python manage.py compilemessages --ignore \".venv\" &&
poetry run python manage.py runserver_plus 0.0.0.0:80"
args:
DEV: true
ARG_VERSION: ""
USER_UID: ${USER_UID:-1000}
USER_GID: ${USER_GID:-1000}
command: bash -c "python manage.py runserver_plus 0.0.0.0:80"
volumes:
- .:/app
- ./tapir:/app/tapir
- ./manage.py:/app/manage.py
- ./Makefile:/app/Makefile
environment:
VIRTUAL_HOST: localhost
DEBUG: 1
Expand Down Expand Up @@ -69,17 +72,15 @@ services:
celery:
extends:
service: web
command: bash -c "poetry install &&
poetry run celery -A tapir worker -l info"
command: bash -c "celery -A tapir worker -l info"
depends_on:
- redis

celery-beat:
extends:
service: web
# --schedule to avoid polluting the app directory
command: bash -c "poetry install &&
poetry run celery -A tapir beat -l info --schedule /tmp/celerybeat-schedule"
command: bash -c "celery -A tapir beat -l info --schedule /tmp/celerybeat-schedule"
depends_on:
- redis

Expand Down
31 changes: 15 additions & 16 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading