diff --git a/bootstrap/development/docker/README.md b/bootstrap/development/docker/README.md index 6826973a3e..921dced968 100644 --- a/bootstrap/development/docker/README.md +++ b/bootstrap/development/docker/README.md @@ -119,3 +119,47 @@ Note that these steps must be run from the root directory of the repo. user.is_superuser = True user.save() ``` + +### Enabling the debugger for the web service + +The web service may be augmented to allow a debugger to be attached to it. Below are instructions on this for Visual Studio Code, although the process should be similar for other IDEs that support the Debug Adapter Protocol: + +1. In the `.vscode` directory, add or update a file named `launch.json`: + + ```json + { + "version": "0.2.0", + "configurations": [ + { + "name": "Attach to Docker Django", + "type": "python", + "request": "attach", + "connect": { + "host": "localhost", + "port": 5678 + }, + "pathMappings": [ + { + "localRoot": "${workspaceFolder}/coldfront", + "remoteRoot": "/var/www/coldfront_app/coldfront" + } + ] + } + ] + } + ``` + + This file configures how Visual Studio Code attaches its debugger to the running Django application inside the Docker `web` container, specifying the connection details and mapping local source files to their locations inside the container. + + Notes: + - In the above example, `localRoot` assumes that `.vscode` is in the parent directory of the repository. Adjust the key as needed. + +2. Set the `DEBUGPY` environment variable to `1` on the host. + + ```bash + export DEBUGPY=1 + ``` + +3. Bring up Docker Compose as specified above in the same session where the environment variable is set. + +4. In Visual Studio Code, select "Run and Debug" in the left pane. At the top of the component, select "Attach to Docker Django" and click the play button ("Start debugging" button) to start the debugger. Note: When `DEBUGPY=1`, the web server will not run until the play button is clicked, because it waits for a client to attach first. diff --git a/bootstrap/development/docker/docker-compose.yml b/bootstrap/development/docker/docker-compose.yml index 74d8e863bf..cb10b49d41 100644 --- a/bootstrap/development/docker/docker-compose.yml +++ b/bootstrap/development/docker/docker-compose.yml @@ -25,10 +25,12 @@ services: - ./config/redis.conf:/usr/local/etc/redis/redis.conf email-server: - image: coldfront-email-server:${IMAGE_TAG:-latest} + image: coldfront-app-base:${IMAGE_TAG:-latest} + command: ["python3", "-m", "smtpd", "-d", "-n", "-c", "DebuggingServer", "0.0.0.0:1025"] db-postgres-shell: image: coldfront-db-postgres-shell:${IMAGE_TAG:-latest} + command: ["sleep", "infinity"] environment: POSTGRES_HOST: db-postgres POSTGRES_DB: ${DB_NAME} @@ -42,19 +44,25 @@ services: - ../../..:/var/www/coldfront_app/coldfront app-shell: - image: coldfront-app-shell:${IMAGE_TAG:-latest} + image: coldfront-app-base:${IMAGE_TAG:-latest} + command: ["sleep", "infinity"] volumes: - ../../..:/var/www/coldfront_app/coldfront web: - image: coldfront-web:${IMAGE_TAG:-latest} + image: coldfront-app-base:${IMAGE_TAG:-latest} + command: ["/var/www/coldfront_app/coldfront/bootstrap/development/docker/scripts/web_entrypoint.sh"] + environment: + - DEBUGPY=${DEBUGPY:-0} ports: - ${WEB_PORT}:80 + - 5678:5678 volumes: - ../../..:/var/www/coldfront_app/coldfront qcluster: - image: coldfront-qcluster:${IMAGE_TAG:-latest} + image: coldfront-app-base:${IMAGE_TAG:-latest} + command: ["python3", "manage.py", "qcluster"] volumes: - ../../..:/var/www/coldfront_app/coldfront diff --git a/bootstrap/development/docker/images/app-base.Dockerfile b/bootstrap/development/docker/images/app-base.Dockerfile index e87a2d861c..d46c2ca4e0 100644 --- a/bootstrap/development/docker/images/app-base.Dockerfile +++ b/bootstrap/development/docker/images/app-base.Dockerfile @@ -11,4 +11,6 @@ RUN /var/www/coldfront_app/venv/bin/pip install --upgrade pip wheel && \ /var/www/coldfront_app/venv/bin/pip install setuptools==68.2.2 && \ /var/www/coldfront_app/venv/bin/pip install -r requirements.txt +RUN /var/www/coldfront_app/venv/bin/pip install debugpy + ENV PATH="/var/www/coldfront_app/venv/bin:$PATH" diff --git a/bootstrap/development/docker/images/web.Dockerfile b/bootstrap/development/docker/images/web.Dockerfile index b0cc6df546..687c612c24 100644 --- a/bootstrap/development/docker/images/web.Dockerfile +++ b/bootstrap/development/docker/images/web.Dockerfile @@ -1,4 +1,4 @@ ARG BASE_IMAGE_TAG=latest FROM coldfront-app-base:${BASE_IMAGE_TAG} -CMD ["python3", "manage.py", "runserver", "0.0.0.0:80"] +CMD ["python3", "-m", "debugpy", "--listen", "0.0.0.0:5678", "--wait-for-client", "manage.py", "runserver", "0.0.0.0:80"] diff --git a/bootstrap/development/docker/scripts/build_images.sh b/bootstrap/development/docker/scripts/build_images.sh index dbc671c134..3bcb2a0083 100755 --- a/bootstrap/development/docker/scripts/build_images.sh +++ b/bootstrap/development/docker/scripts/build_images.sh @@ -20,27 +20,7 @@ docker build \ --build-arg BASE_IMAGE_TAG=$IMAGE_TAG \ -t coldfront-app-base:$IMAGE_TAG . -docker build \ - -f bootstrap/development/docker/images/app-shell.Dockerfile \ - --build-arg BASE_IMAGE_TAG=$IMAGE_TAG \ - -t coldfront-app-shell:$IMAGE_TAG . - -docker build \ - -f bootstrap/development/docker/images/web.Dockerfile \ - --build-arg BASE_IMAGE_TAG=$IMAGE_TAG \ - -t coldfront-web:$IMAGE_TAG . - -docker build \ - -f bootstrap/development/docker/images/email-server.Dockerfile \ - --build-arg BASE_IMAGE_TAG=$IMAGE_TAG \ - -t coldfront-email-server:$IMAGE_TAG . - docker build \ -f bootstrap/development/docker/images/db-postgres-shell.Dockerfile \ --build-arg BASE_IMAGE_TAG=$IMAGE_TAG \ -t coldfront-db-postgres-shell:$IMAGE_TAG . - -docker build \ - -f bootstrap/development/docker/images/qcluster.Dockerfile \ - --build-arg BASE_IMAGE_TAG=$IMAGE_TAG \ - -t coldfront-qcluster:$IMAGE_TAG . diff --git a/bootstrap/development/docker/scripts/web_entrypoint.sh b/bootstrap/development/docker/scripts/web_entrypoint.sh new file mode 100644 index 0000000000..af87867ece --- /dev/null +++ b/bootstrap/development/docker/scripts/web_entrypoint.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +if [ "$DEBUGPY" = "1" ]; then + exec python3 -m debugpy --listen 0.0.0.0:5678 --wait-for-client manage.py runserver 0.0.0.0:80 +else + exec python3 manage.py runserver 0.0.0.0:80 +fi