From 69bbea0060fdcd285264fdce1d9b7bf0f416fb20 Mon Sep 17 00:00:00 2001 From: neilcroft Date: Fri, 20 Mar 2026 08:04:21 +0100 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=94=A7(devops)=20add=20devcontainer?= =?UTF-8?q?=20configuration=20for=20Zed=20and=20VS=20Code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a .devcontainer setup that extends the backend-development image with nodejs/npm/bash (needed for basedpyright LSP) and a named "default" user with a valid shell and writable HOME. The containerUser is set to "default" (a named user) to work around a devcontainer CLI bug that serializes numeric UIDs as YAML integers, which Docker Compose rejects. On startup, any existing app-dev container from `make run` is automatically replaced. The Django runserver starts in background via postStartCommand. --- .devcontainer/Dockerfile | 15 ++++++++++++ .devcontainer/devcontainer.json | 28 +++++++++++++++++++++++ .devcontainer/docker-compose.override.yml | 12 ++++++++++ .gitignore | 1 - README.md | 13 +++++++++++ 5 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/docker-compose.override.yml diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 000000000..c7135fac8 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,15 @@ +ARG BASE_IMAGE=drive:backend-development +FROM ${BASE_IMAGE} + +USER root + +# Install tools needed by Zed (basedpyright LSP requires node) +RUN apk add --no-cache nodejs npm bash + +# Create a writable home and register the dev user with a valid shell +ARG DEV_UID=1000 +RUN mkdir -p /tmp/dev-home && chown ${DEV_UID}:0 /tmp/dev-home \ + && echo "default:x:${DEV_UID}:0:default user:/tmp/dev-home:/bin/sh" >> /etc/passwd + +USER default +ENV HOME=/tmp/dev-home diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..ed4e5d51c --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,28 @@ +{ + "name": "Drive - La Suite Numerique", + "dockerComposeFile": [ + "../compose.yaml", + "docker-compose.override.yml" + ], + "service": "app-dev", + "workspaceFolder": "/workspace", + "overrideCommand": true, + "shutdownAction": "stopCompose", + "containerUser": "default", + "updateRemoteUserUID": false, + "initializeCommand": { + "network": "docker network create lasuite-network || true", + "envfiles": "touch env.d/development/crowdin.local env.d/development/common.local env.d/development/postgresql.local env.d/development/kc_postgresql.local", + "dirs": "mkdir -p data/media data/static", + "clean-app-dev": "docker compose stop app-dev && docker compose rm -f app-dev || true" + }, + "postCreateCommand": { + "migrate": "cd /app && python manage.py migrate", + "i18n": "cd /app && python manage.py compilemessages --ignore='.venv/**/*'", + "wopi": "cd /app && python manage.py trigger_wopi_configuration" + }, + "postStartCommand": { + "runserver": "cd /app && python manage.py runserver 0.0.0.0:8000 &" + }, + "forwardPorts": [3000, 8071, 8080, 8083, 9000, 9001, 9980, 9981] +} diff --git a/.devcontainer/docker-compose.override.yml b/.devcontainer/docker-compose.override.yml new file mode 100644 index 000000000..a43db4b74 --- /dev/null +++ b/.devcontainer/docker-compose.override.yml @@ -0,0 +1,12 @@ +services: + app-dev: + user: "default" + build: + context: . + dockerfile: .devcontainer/Dockerfile + target: "" + args: + BASE_IMAGE: drive:backend-development + DEV_UID: ${DOCKER_USER:-1000} + volumes: + - ..:/workspace:cached diff --git a/.gitignore b/.gitignore index 2f9a22de8..4713d3591 100644 --- a/.gitignore +++ b/.gitignore @@ -79,7 +79,6 @@ db.sqlite3 .idea/ .vscode/ *.iml -.devcontainer # Various .turbo diff --git a/README.md b/README.md index 91d03d21f..11f778720 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,19 @@ To start all the services, except the frontend container, you can use the follow $ make run-backend ``` +### Dev Container (Zed / VS Code) + +You can develop inside a container using the [Dev Containers](https://containers.dev/) specification. +This is supported by **Zed** and **VS Code** out of the box. + +1. Open the project in your IDE — it will detect `.devcontainer/devcontainer.json` and offer to reopen in a container. +2. The first launch builds a custom image, starts all Compose services, runs migrations and compiles translations. +3. The Django development server starts automatically on `http://localhost:8071`. + +> **Note:** If containers are already running from `make run`, the dev container will +> automatically stop and replace the `app-dev` service. Other services (PostgreSQL, +> Redis, Keycloak…) keep running. + ### Django admin You can access the Django admin site at From 8982430c167fb9f0cbf1da27b139031169fe69ed Mon Sep 17 00:00:00 2001 From: neilcroft Date: Fri, 20 Mar 2026 11:00:36 +0100 Subject: [PATCH 2/3] =?UTF-8?q?fixup!=20=F0=9F=94=A7(devops)=20add=20devco?= =?UTF-8?q?ntainer=20configuration=20for=20Zed=20and=20VS=20Code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .devcontainer/devcontainer.json | 15 +++------------ .devcontainer/docker-compose.override.yml | 5 ++--- README.md | 11 +++++------ 3 files changed, 10 insertions(+), 21 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ed4e5d51c..d7292d9c2 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -4,25 +4,16 @@ "../compose.yaml", "docker-compose.override.yml" ], - "service": "app-dev", + "service": "devcontainer", "workspaceFolder": "/workspace", "overrideCommand": true, - "shutdownAction": "stopCompose", + "shutdownAction": "none", "containerUser": "default", "updateRemoteUserUID": false, "initializeCommand": { "network": "docker network create lasuite-network || true", "envfiles": "touch env.d/development/crowdin.local env.d/development/common.local env.d/development/postgresql.local env.d/development/kc_postgresql.local", - "dirs": "mkdir -p data/media data/static", - "clean-app-dev": "docker compose stop app-dev && docker compose rm -f app-dev || true" - }, - "postCreateCommand": { - "migrate": "cd /app && python manage.py migrate", - "i18n": "cd /app && python manage.py compilemessages --ignore='.venv/**/*'", - "wopi": "cd /app && python manage.py trigger_wopi_configuration" - }, - "postStartCommand": { - "runserver": "cd /app && python manage.py runserver 0.0.0.0:8000 &" + "dirs": "mkdir -p data/media data/static" }, "forwardPorts": [3000, 8071, 8080, 8083, 9000, 9001, 9980, 9981] } diff --git a/.devcontainer/docker-compose.override.yml b/.devcontainer/docker-compose.override.yml index a43db4b74..d4c56a736 100644 --- a/.devcontainer/docker-compose.override.yml +++ b/.devcontainer/docker-compose.override.yml @@ -1,12 +1,11 @@ services: - app-dev: - user: "default" + devcontainer: build: context: . dockerfile: .devcontainer/Dockerfile - target: "" args: BASE_IMAGE: drive:backend-development DEV_UID: ${DOCKER_USER:-1000} + user: "default" volumes: - ..:/workspace:cached diff --git a/README.md b/README.md index 11f778720..405d8b912 100644 --- a/README.md +++ b/README.md @@ -126,13 +126,12 @@ $ make run-backend You can develop inside a container using the [Dev Containers](https://containers.dev/) specification. This is supported by **Zed** and **VS Code** out of the box. -1. Open the project in your IDE — it will detect `.devcontainer/devcontainer.json` and offer to reopen in a container. -2. The first launch builds a custom image, starts all Compose services, runs migrations and compiles translations. -3. The Django development server starts automatically on `http://localhost:8071`. +1. Start the project with `make run` (or `make bootstrap` on first use). +2. Open the project in your IDE — it will detect `.devcontainer/devcontainer.json` and offer to reopen in a container. -> **Note:** If containers are already running from `make run`, the dev container will -> automatically stop and replace the `app-dev` service. Other services (PostgreSQL, -> Redis, Keycloak…) keep running. +The dev container runs alongside `app-dev` as a dedicated IDE workspace with +Python dependencies and LSP support. It shares the same source files via volume +mounts, so your changes are immediately reflected in the running application. ### Django admin From b7e3e811cbe5dfa518b4c569a9c8684b5687a919 Mon Sep 17 00:00:00 2001 From: neilcroft Date: Wed, 25 Mar 2026 10:23:45 +0100 Subject: [PATCH 3/3] =?UTF-8?q?fixup!=20=F0=9F=94=A7(devops)=20add=20devco?= =?UTF-8?q?ntainer=20configuration=20for=20Zed=20and=20VS=20Code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 86f7f1454..756d67855 100644 --- a/Makefile +++ b/Makefile @@ -113,7 +113,7 @@ build-frontend: ## build the frontend container @$(COMPOSE) build frontend-dev $(cache) .PHONY: build-frontend-development -down: ## stop and remove containers, networks, images, and volumes +down: stop-devcontainer ## stop and remove containers, networks, images, and volumes @$(COMPOSE) down rm -rf data/postgresql.* .PHONY: down @@ -171,10 +171,18 @@ status: ## an alias for "docker compose ps" @$(COMPOSE) ps .PHONY: status -stop: ## stop the development server using Docker +stop: stop-devcontainer ## stop the development server using Docker @$(COMPOSE) stop .PHONY: stop +COMPOSE_DEVCONTAINER = docker compose -f compose.yaml -f .devcontainer/docker-compose.override.yml + +stop-devcontainer: ## stop the devcontainer service if running + @if $(COMPOSE_DEVCONTAINER) ps devcontainer --status running -q 2>/dev/null | grep -q .; then \ + $(COMPOSE_DEVCONTAINER) stop devcontainer; \ + fi +.PHONY: stop-devcontainer + # -- Backend demo: ## flush db then create a demo for load testing purpose