From f9bcd2abfa8f9ff2fa39463ffbd00bbf84716962 Mon Sep 17 00:00:00 2001 From: Henning Schiebenhoefer Date: Sat, 25 Oct 2025 11:48:22 +0200 Subject: [PATCH 01/10] add basic devcontainer setup --- .devcontainer/Dockerfile | 55 +++++++++++++++++++++++++++++++++ .devcontainer/devcontainer.json | 34 ++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 000000000..2e8c20395 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,55 @@ +# Minimal Dockerfile for a Python 3.13 devcontainer with Poetry installed. +FROM python:3.13-slim + +ARG USERNAME=vscode +ARG USER_UID=1000 +ARG USER_GID=1000 + +ENV DEBIAN_FRONTEND=noninteractive \ + PATH=/root/.local/bin:$PATH \ + POETRY_HOME=/opt/poetry + +# Install system dependencies commonly required for building packages used in this repo +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + build-essential \ + curl \ + git \ + ca-certificates \ + gcc \ + libpq-dev \ + libjpeg-dev \ + zlib1g-dev \ + libxml2-dev \ + libxslt1-dev \ + libffi-dev \ + libssl-dev \ + libcairo2 \ + libpango-1.0-0 \ + shared-mime-info \ + poppler-utils \ + fonts-liberation \ + && rm -rf /var/lib/apt/lists/* + +# Install Poetry (official installer) +RUN curl -sSL https://install.python-poetry.org | python3 - \ + && ln -s /opt/poetry/bin/poetry /usr/local/bin/poetry \ + && chmod -R a+rx /opt/poetry \ + && chmod a+rx /usr/local/bin/poetry \ + && poetry --version + +# Set poetry to not create virtualenvs by default (so dependencies go into the container python) +RUN poetry config virtualenvs.create false + +# Create a non-root user to match VS Code's default "vscode" username +RUN groupadd --gid ${USER_GID} ${USERNAME} \ + && useradd -s /bin/bash --uid ${USER_UID} --gid ${USER_GID} -m ${USERNAME} \ + && mkdir -p /workspace && chown ${USERNAME}:${USERNAME} /workspace + +WORKDIR /workspace + +# Switch to non-root user +USER ${USERNAME} + +# By default don't run anything - postCreateCommand will run when container is created +CMD [ "bash" ] \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..19bd16d2d --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,34 @@ +{ + "name": "tapir (Python 3.13)", + "build": { + "dockerfile": "Dockerfile", + "context": ".." + }, + "workspaceFolder": "/workspace", + "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached", + "remoteUser": "vscode", + "forwardPorts": [8000], + "containerEnv": { + "PYTHONFAULTHANDLER": "1", + "POETRY_NO_INTERACTION": "1" + }, + "customizations": { + "vscode": { + "extensions": [ + "ms-python.python", + "ms-python.vscode-pylance", + "ms-python.black-formatter", + "njpwerner.autodocstring", + "ms-azuretools.vscode-docker", + "ms-python.isort" + ] + } + }, + "settings": { + "python.defaultInterpreterPath": "/usr/local/bin/python", + "python.formatting.provider": "black", + "editor.formatOnSave": true + }, + "postCreateCommand": "poetry config virtualenvs.create false && poetry install --no-interaction", + "shutdownAction": "stopContainer" +} \ No newline at end of file From e954a3b112c9399c3bd297a27a44bbe4d65400d5 Mon Sep 17 00:00:00 2001 From: Henning Schiebenhoefer Date: Sat, 25 Oct 2025 12:22:30 +0200 Subject: [PATCH 02/10] install poetry via apt --- .devcontainer/Dockerfile | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 2e8c20395..cbbefc7a9 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -26,18 +26,12 @@ RUN apt-get update \ libssl-dev \ libcairo2 \ libpango-1.0-0 \ + python3-poetry \ shared-mime-info \ poppler-utils \ fonts-liberation \ && rm -rf /var/lib/apt/lists/* -# Install Poetry (official installer) -RUN curl -sSL https://install.python-poetry.org | python3 - \ - && ln -s /opt/poetry/bin/poetry /usr/local/bin/poetry \ - && chmod -R a+rx /opt/poetry \ - && chmod a+rx /usr/local/bin/poetry \ - && poetry --version - # Set poetry to not create virtualenvs by default (so dependencies go into the container python) RUN poetry config virtualenvs.create false From 9f1fd93c9a4690520e6f99f8359e0a56db9fc4a7 Mon Sep 17 00:00:00 2001 From: Henning Schiebenhoefer Date: Sat, 25 Oct 2025 14:43:19 +0200 Subject: [PATCH 03/10] WIP --- .devcontainer/Dockerfile | 8 +++----- .devcontainer/devcontainer.json | 4 ++-- .github/workflows/devcontainer-ci.yml | 29 +++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/devcontainer-ci.yml diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index cbbefc7a9..8fbe71acd 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -6,8 +6,7 @@ ARG USER_UID=1000 ARG USER_GID=1000 ENV DEBIAN_FRONTEND=noninteractive \ - PATH=/root/.local/bin:$PATH \ - POETRY_HOME=/opt/poetry + PATH=/root/.local/bin:$PATH # Install system dependencies commonly required for building packages used in this repo RUN apt-get update \ @@ -19,6 +18,8 @@ RUN apt-get update \ gcc \ libpq-dev \ libjpeg-dev \ + libldap2-dev \ + libsasl2-dev \ zlib1g-dev \ libxml2-dev \ libxslt1-dev \ @@ -32,9 +33,6 @@ RUN apt-get update \ fonts-liberation \ && rm -rf /var/lib/apt/lists/* -# Set poetry to not create virtualenvs by default (so dependencies go into the container python) -RUN poetry config virtualenvs.create false - # Create a non-root user to match VS Code's default "vscode" username RUN groupadd --gid ${USER_GID} ${USERNAME} \ && useradd -s /bin/bash --uid ${USER_UID} --gid ${USER_GID} -m ${USERNAME} \ diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 19bd16d2d..e79037c13 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -25,10 +25,10 @@ } }, "settings": { - "python.defaultInterpreterPath": "/usr/local/bin/python", + "python.defaultInterpreterPath": "/workspace/.venv/bin/python", "python.formatting.provider": "black", "editor.formatOnSave": true }, - "postCreateCommand": "poetry config virtualenvs.create false && poetry install --no-interaction", + "postCreateCommand": "poetry config virtualenvs.create true --local && poetry config virtualenvs.in-project true --local && poetry install --no-interaction --with dev", "shutdownAction": "stopContainer" } \ No newline at end of file diff --git a/.github/workflows/devcontainer-ci.yml b/.github/workflows/devcontainer-ci.yml new file mode 100644 index 000000000..336f9cb43 --- /dev/null +++ b/.github/workflows/devcontainer-ci.yml @@ -0,0 +1,29 @@ +# Example: build your devcontainer and run poetry install + tests in CI +on: + push: + branches: [ main ] + pull_request: + +jobs: + devcontainer-ci: + runs-on: ubuntu-latest + name: Build devcontainer image and run tests + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Build devcontainer and run commands + # Official devcontainers CI action builds the image from .devcontainer and runs commands inside it. + # You can use a stable tag from the devcontainers/ci repo (check their README for the recommended tag). + uses: devcontainers/ci@main + with: + # Path to the folder that contains devcontainer.json (default is root) + # here it is the repository root which includes .devcontainer/ + repo: ${{ github.repository }} + # N.B. runCmd will be executed inside the devcontainer. Use multiline commands as below. + runCmd: | + set -eux + # make sure poetry is non-interactive and doesn't create venvs in CI environment + poetry config virtualenvs.create false --local || true + poetry install --no-interaction + poetry run pytest -q \ No newline at end of file From 53c89151c7e254f272b5d37b7b92c6d2b099f341 Mon Sep 17 00:00:00 2001 From: Henning Schiebenhoefer Date: Sat, 25 Oct 2025 16:34:24 +0200 Subject: [PATCH 04/10] adapt devcontainers Dockerfile to be in sync with django.Dockerfile --- .devcontainer/Dockerfile | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 8fbe71acd..5f5f2febd 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Minimal Dockerfile for a Python 3.13 devcontainer with Poetry installed. -FROM python:3.13-slim +FROM python:3.13 ARG USERNAME=vscode ARG USER_UID=1000 @@ -10,27 +10,13 @@ ENV DEBIAN_FRONTEND=noninteractive \ # Install system dependencies commonly required for building packages used in this repo RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - build-essential \ - curl \ - git \ - ca-certificates \ - gcc \ - libpq-dev \ - libjpeg-dev \ - libldap2-dev \ - libsasl2-dev \ - zlib1g-dev \ - libxml2-dev \ - libxslt1-dev \ - libffi-dev \ - libssl-dev \ - libcairo2 \ - libpango-1.0-0 \ - python3-poetry \ - shared-mime-info \ - poppler-utils \ - fonts-liberation \ + && apt-get --no-install-recommends install -y \ + gettext \ + libldap2-dev \ + libsasl2-dev \ + postgresql-client \ + postgresql-client-common \ + python3-poetry \ && rm -rf /var/lib/apt/lists/* # Create a non-root user to match VS Code's default "vscode" username From 22bf0aac12cf584ff7edd18d5ec68a3a7544528b Mon Sep 17 00:00:00 2001 From: Henning Schiebenhoefer Date: Sat, 25 Oct 2025 16:36:56 +0200 Subject: [PATCH 05/10] delete devcontainer ci action --- .github/workflows/devcontainer-ci.yml | 29 --------------------------- 1 file changed, 29 deletions(-) delete mode 100644 .github/workflows/devcontainer-ci.yml diff --git a/.github/workflows/devcontainer-ci.yml b/.github/workflows/devcontainer-ci.yml deleted file mode 100644 index 336f9cb43..000000000 --- a/.github/workflows/devcontainer-ci.yml +++ /dev/null @@ -1,29 +0,0 @@ -# Example: build your devcontainer and run poetry install + tests in CI -on: - push: - branches: [ main ] - pull_request: - -jobs: - devcontainer-ci: - runs-on: ubuntu-latest - name: Build devcontainer image and run tests - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Build devcontainer and run commands - # Official devcontainers CI action builds the image from .devcontainer and runs commands inside it. - # You can use a stable tag from the devcontainers/ci repo (check their README for the recommended tag). - uses: devcontainers/ci@main - with: - # Path to the folder that contains devcontainer.json (default is root) - # here it is the repository root which includes .devcontainer/ - repo: ${{ github.repository }} - # N.B. runCmd will be executed inside the devcontainer. Use multiline commands as below. - runCmd: | - set -eux - # make sure poetry is non-interactive and doesn't create venvs in CI environment - poetry config virtualenvs.create false --local || true - poetry install --no-interaction - poetry run pytest -q \ No newline at end of file From b04ac79a04c540d6c648b49aaee490f3624ec65d Mon Sep 17 00:00:00 2001 From: Henning Schiebenhoefer Date: Tue, 28 Oct 2025 21:42:08 +0100 Subject: [PATCH 06/10] move copying of files into docker container behind dependency installation to make use of dockers caching, add non-root user --- django.Dockerfile | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/django.Dockerfile b/django.Dockerfile index 2f2a5a4f9..3adb9f63c 100644 --- a/django.Dockerfile +++ b/django.Dockerfile @@ -1,7 +1,5 @@ FROM python:3.13 ENV PYTHONUNBUFFERED=1 -WORKDIR /app -COPY . /app RUN apt-get update -y \ && apt-get --no-install-recommends install -y \ @@ -9,8 +7,15 @@ RUN apt-get update -y \ libldap2-dev \ libsasl2-dev \ postgresql-client \ - postgresql-client-common \ - && rm -rf /var/lib/apt/lists/* \ - && pip install poetry \ - && poetry install \ + postgresql-client-common \ + python3-poetry \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app +COPY . /app + +RUN useradd -m developer && chown -R developer /app +USER developer + +RUN poetry install \ && poetry run python manage.py compilemessages From 3e573246f7694420e54ea610017441642d50bb34 Mon Sep 17 00:00:00 2001 From: Henning Schiebenhoefer Date: Tue, 28 Oct 2025 21:42:48 +0100 Subject: [PATCH 07/10] replace custom docker file with compose override --- .devcontainer/Dockerfile | 33 ------------ .devcontainer/devcontainer.json | 53 ++++++++----------- .devcontainer/docker-compose.dev.override.yml | 7 +++ 3 files changed, 28 insertions(+), 65 deletions(-) delete mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/docker-compose.dev.override.yml diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index 5f5f2febd..000000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,33 +0,0 @@ -# Minimal Dockerfile for a Python 3.13 devcontainer with Poetry installed. -FROM python:3.13 - -ARG USERNAME=vscode -ARG USER_UID=1000 -ARG USER_GID=1000 - -ENV DEBIAN_FRONTEND=noninteractive \ - PATH=/root/.local/bin:$PATH - -# Install system dependencies commonly required for building packages used in this repo -RUN apt-get update \ - && apt-get --no-install-recommends install -y \ - gettext \ - libldap2-dev \ - libsasl2-dev \ - postgresql-client \ - postgresql-client-common \ - python3-poetry \ - && rm -rf /var/lib/apt/lists/* - -# Create a non-root user to match VS Code's default "vscode" username -RUN groupadd --gid ${USER_GID} ${USERNAME} \ - && useradd -s /bin/bash --uid ${USER_UID} --gid ${USER_GID} -m ${USERNAME} \ - && mkdir -p /workspace && chown ${USERNAME}:${USERNAME} /workspace - -WORKDIR /workspace - -# Switch to non-root user -USER ${USERNAME} - -# By default don't run anything - postCreateCommand will run when container is created -CMD [ "bash" ] \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e79037c13..6a55cdabe 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,34 +1,23 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-docker-compose { - "name": "tapir (Python 3.13)", - "build": { - "dockerfile": "Dockerfile", - "context": ".." - }, - "workspaceFolder": "/workspace", - "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached", - "remoteUser": "vscode", - "forwardPorts": [8000], - "containerEnv": { - "PYTHONFAULTHANDLER": "1", - "POETRY_NO_INTERACTION": "1" - }, - "customizations": { - "vscode": { - "extensions": [ - "ms-python.python", - "ms-python.vscode-pylance", - "ms-python.black-formatter", - "njpwerner.autodocstring", - "ms-azuretools.vscode-docker", - "ms-python.isort" - ] - } - }, - "settings": { - "python.defaultInterpreterPath": "/workspace/.venv/bin/python", - "python.formatting.provider": "black", - "editor.formatOnSave": true - }, - "postCreateCommand": "poetry config virtualenvs.create true --local && poetry config virtualenvs.in-project true --local && poetry install --no-interaction --with dev", - "shutdownAction": "stopContainer" + "name": "tapir", + + // Update the 'dockerComposeFile' list if you have more compose files or use different names. + // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make. + "dockerComposeFile": [ + "../docker-compose.yml", + "docker-compose.dev.override.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "web", + + // The optional 'workspaceFolder' property is the path VS Code should open by default when + // connected. This is typically a file mount in .devcontainer/docker-compose.yml + "workspaceFolder": "/app", + "remoteUser": "developer", + "postCreateCommand": "poetry install --with dev", + "shutdownAction": "stopCompose", } \ No newline at end of file diff --git a/.devcontainer/docker-compose.dev.override.yml b/.devcontainer/docker-compose.dev.override.yml new file mode 100644 index 000000000..933b6082e --- /dev/null +++ b/.devcontainer/docker-compose.dev.override.yml @@ -0,0 +1,7 @@ +services: + web: + volumes: + - .:/app:cached + command: bash -c "git config --global --add safe.directory /app" + environment: + - PYTHONUNBUFFERED=1 From a8b31554b4a5ddfa9696322b31028fce95bee4d5 Mon Sep 17 00:00:00 2001 From: Henning Schiebenhoefer Date: Tue, 28 Oct 2025 22:13:06 +0100 Subject: [PATCH 08/10] fix path to venv created during container build --- .devcontainer/devcontainer.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 6a55cdabe..54108b9bc 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,6 +18,9 @@ // connected. This is typically a file mount in .devcontainer/docker-compose.yml "workspaceFolder": "/app", "remoteUser": "developer", + "remoteEnv": { + "POETRY_CACHE_DIR": "/home/developer/.cache/pypoetry" + }, "postCreateCommand": "poetry install --with dev", "shutdownAction": "stopCompose", } \ No newline at end of file From 5f3286e89079c99867e0748fde24122ca293da29 Mon Sep 17 00:00:00 2001 From: Henning Schiebenhoefer Date: Tue, 28 Oct 2025 22:20:41 +0100 Subject: [PATCH 09/10] remove coverage, clean up docker user switch --- .coverage | Bin 69632 -> 0 bytes django.Dockerfile | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 .coverage diff --git a/.coverage b/.coverage deleted file mode 100644 index 6b67013423ef953a639a8bbc69e1d0ee6a15d59d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 69632 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 diff --git a/django.Dockerfile b/django.Dockerfile index 3adb9f63c..d65dcc195 100644 --- a/django.Dockerfile +++ b/django.Dockerfile @@ -11,10 +11,10 @@ RUN apt-get update -y \ python3-poetry \ && rm -rf /var/lib/apt/lists/* +RUN useradd -m developer WORKDIR /app -COPY . /app +COPY --chown=developer:developer . /app -RUN useradd -m developer && chown -R developer /app USER developer RUN poetry install \ From 4eed96f341815d1f1a208df975b602ea3cf9cece Mon Sep 17 00:00:00 2001 From: Henning Schiebenhoefer Date: Tue, 11 Nov 2025 20:23:08 +0000 Subject: [PATCH 10/10] cleanup --- .devcontainer/devcontainer.json | 6 +----- .devcontainer/docker-compose.dev.override.yml | 8 +++---- django.Dockerfile | 21 ++++++++++++++----- docker-compose.yml | 5 ++--- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 54108b9bc..d8e071531 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -17,10 +17,6 @@ // The optional 'workspaceFolder' property is the path VS Code should open by default when // connected. This is typically a file mount in .devcontainer/docker-compose.yml "workspaceFolder": "/app", - "remoteUser": "developer", - "remoteEnv": { - "POETRY_CACHE_DIR": "/home/developer/.cache/pypoetry" - }, - "postCreateCommand": "poetry install --with dev", + "remoteUser": "noroot", "shutdownAction": "stopCompose", } \ No newline at end of file diff --git a/.devcontainer/docker-compose.dev.override.yml b/.devcontainer/docker-compose.dev.override.yml index 933b6082e..e45129bae 100644 --- a/.devcontainer/docker-compose.dev.override.yml +++ b/.devcontainer/docker-compose.dev.override.yml @@ -1,7 +1,5 @@ services: web: - volumes: - - .:/app:cached - command: bash -c "git config --global --add safe.directory /app" - environment: - - PYTHONUNBUFFERED=1 + build: + args: + UID: 1000 diff --git a/django.Dockerfile b/django.Dockerfile index d65dcc195..5c79ca255 100644 --- a/django.Dockerfile +++ b/django.Dockerfile @@ -1,6 +1,10 @@ FROM python:3.13 ENV PYTHONUNBUFFERED=1 +ARG UID=1000 +ARG GID=$UID +ARG USERNAME=noroot + RUN apt-get update -y \ && apt-get --no-install-recommends install -y \ gettext \ @@ -11,11 +15,18 @@ RUN apt-get update -y \ python3-poetry \ && rm -rf /var/lib/apt/lists/* -RUN useradd -m developer +RUN if [ "$UID" -ne 0 ]; then \ + addgroup --gid "$GID" "$USERNAME" \ + && adduser --disabled-password --gecos "" --uid "$UID" --gid "$GID" "$USERNAME"; \ + fi + WORKDIR /app -COPY --chown=developer:developer . /app +COPY --chown=$UID:$GID . /app +# change ownership of the app dir itself +RUN chown $UID:$GID /app + +USER ${UID}:${GID} -USER developer +RUN poetry config virtualenvs.in-project true -RUN poetry install \ - && poetry run python manage.py compilemessages +CMD bash -c "poetry install && poetry run python manage.py compilemessages --ignore '.venv' && poetry run python manage.py runserver_plus 0.0.0.0:80" diff --git a/docker-compose.yml b/docker-compose.yml index 325bc90c4..6c0bc2ff3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,9 +17,8 @@ services: build: context: . 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: + UID: 0 volumes: - .:/app environment: