Skip to content

46858 backend [ Configuration ] Add COPY instruction to backend Dockerfile for Railway deployment#216

Open
EBirkenfeld wants to merge 1 commit into
masterfrom
backend/configuration/46858_add_copy_instruction_backend_dockerfile
Open

46858 backend [ Configuration ] Add COPY instruction to backend Dockerfile for Railway deployment#216
EBirkenfeld wants to merge 1 commit into
masterfrom
backend/configuration/46858_add_copy_instruction_backend_dockerfile

Conversation

@EBirkenfeld
Copy link
Copy Markdown
Collaborator

@EBirkenfeld EBirkenfeld commented May 22, 2026

1. Problem

The backend Dockerfile was missing a COPY . . command to copy application source code into the Docker image. Only poetry dependencies were installed — the actual application code was never included. As a result, Railway deployments failed with ModuleNotFoundError because the image had no source files to run.

Where it manifested: Railway deployment — backend, celery, and celery-beat services failed to start.

2. Context

Historically, the project ran exclusively via docker-compose with volume mounts (./backend:/pneumatic_backend), which overlaid the container's filesystem with local source code. The missing COPY . . went unnoticed. When deploying to Railway (no volume mounts), the built image was essentially "empty" — dependencies only, no application code.

Additionally, .dockerignore only had 3 entries. Adding COPY . . without expanding it would have copied unwanted files into the image (.env, __pycache__, .venv, logs, credentials, etc.).

3. Solution

  1. Add COPY . . to the Dockerfile after poetry install — preserves optimal Docker layer caching (dependency layer only invalidates when pyproject.toml/poetry.lock change).
  2. Expand .dockerignore from 3 to 55 entries to exclude dev artifacts, secrets, and build noise.
  3. No changes needed in docker-compose files — volume mounts correctly override the COPY layer in local development, preserving hot-reload.

4. Implementation Details

File Change
backend/Dockerfile Added COPY . . (line 31) after poetry install with explanatory comments
backend/.dockerignore Expanded from 3 to 55 lines — comprehensive exclusion list

.dockerignore exclusion categories: VCS (.git), IDE configs, Python caches, virtual environments, Docker files (avoid recursion), logs, secrets/env files (.env, google_api_credentials.json), build artifacts (staticfiles/, tmp/), database files.

Intentionally unchanged: All three docker-compose files — volume mounts (./backend:/pneumatic_backend) correctly override COPY in local dev.

5. Testing

5.1 Preconditions

  • Access to Railway project or local Docker for image builds
  • Working docker-compose stack for local dev verification

5.2 Positive Scenarios

  1. Production image build:

    • Build image: docker build -t pneumatic-backend-test ./backend
    • Verify source code: docker run --rm pneumatic-backend-test ls -la /pneumatic_backend/src/
    • Verify Django: docker run --rm pneumatic-backend-test python manage.py --help
    • Expected: image contains full source code, Django commands work
  2. Local dev via docker-compose:

    • Run docker-compose up backend
    • Modify any .py file in backend/
    • Restart container — changes should be picked up (volume mount overrides COPY)
  3. Verify .dockerignore:

    • Build image, check excluded files are absent:
      docker run --rm pneumatic-backend-test sh -c "ls -la .env 2>&1; ls -la .git 2>&1; ls -la __pycache__ 2>&1"
    • Expected: all .dockerignore entries are absent from image

5.3 Negative Scenarios & Edge Cases

  1. Image without volume mountdocker run --rm pneumatic-backend-test python -c "import src; print('OK')" → should succeed
  2. Secrets not in image.env and google_api_credentials.json should be absent
  3. Celery/Celery-beat — same Dockerfile, verify worker starts with code present

5.4 Verification Points

  • In image: src/, manage.py, pyproject.toml present in /pneumatic_backend/
  • In image: .env, .git, __pycache__, .venv, *.log absent
  • Locally: docker-compose stack starts, hot-reload works as before
  • Railway: deploy succeeds, services start without ModuleNotFoundError

5.5 API Checks

Not applicable — infrastructure-only changes, no API impact.

5.6 What Was NOT Tested

  • Not tested on Railway (verified locally via docker build only)
  • Not tested in production environment
  • deploy-config repository compatibility not verified (may need analogous patch if it exists separately)

6. Affected Areas

The Dockerfile is used to build images for three services: backend, celery, celery-beat. All use build: context: ./backend in docker-compose. Changes do not break local development — volume mounts override the COPY layer.

7. Refactoring

.dockerignore was essentially rewritten from scratch (3 → 55 lines). Test via image content verification (sections 5.2–5.3).

8. Commits

  • dc9af48446858 fix(docker): add source code copy to backend Dockerfile

9. Release Notes

Docker: Fixed backend Docker image build — application source code is now properly included in the image, enabling successful deployments on Railway and other container platforms without volume mounts.


Note

Low Risk
Low risk infrastructure-only change; main risk is unintended build-context exclusions or slightly different image contents affecting deployments.

Overview
Fixes backend container builds for non-volume-mounted environments (e.g., Railway) by copying the application source into the image after dependency installation.

Expands backend/.dockerignore to exclude VCS/IDE files, Python caches, virtualenvs, logs, env/secrets (including Google credentials), build artifacts, and local DB files so COPY . . doesn’t bake unnecessary or sensitive files into the image.

Reviewed by Cursor Bugbot for commit dc9af48. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add COPY instruction and expand .dockerignore in backend Dockerfile for Railway deployment

  • Adds a COPY . . step to Dockerfile after dependency installation, so the application source code is included in the built image under /pneumatic_backend.
  • Expands .dockerignore to exclude VCS files, IDE configs, Python caches, virtualenv directories, Docker artifacts, logs, env files, and build artifacts from the build context.

Macroscope summarized dc9af48.

@EBirkenfeld EBirkenfeld self-assigned this May 22, 2026
@EBirkenfeld EBirkenfeld added Backend API changes request DevOps Infrastructure and installation changes labels May 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Backend API changes request DevOps Infrastructure and installation changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants