Skip to content

Fix Docker deployment: Add dedicated nginx static-server and frontend health checks#9

Merged
pirus99 merged 7 commits intomainfrom
copilot/recheck-docker-deployment
Nov 22, 2025
Merged

Fix Docker deployment: Add dedicated nginx static-server and frontend health checks#9
pirus99 merged 7 commits intomainfrom
copilot/recheck-docker-deployment

Conversation

Copy link
Copy Markdown

Copilot AI commented Nov 22, 2025

Django admin and DRF static files were collected but not served. Frontend containers failed health checks due to missing wget in nginx:alpine.

Changes

Dedicated static file server

  • Created new static-server service with nginx to serve Django admin and DRF static files
  • Static files collected during backend Docker build via collectstatic
  • Shared backend-static volume between backend and static-server (read-only mount)
  • Includes health check endpoint and optimized caching/compression
  • Fixed STATIC_URL to use absolute path /static/ (added leading slash for proper URL resolution)

Backend cleanup

  • Reverted backend/core/urls.py to original state (removed static() helper)
  • Reverted backend/entrypoint.sh to original state (removed collectstatic command)
  • Backend no longer serves static files - handled by dedicated static-server

Traefik routing

  • Backend routes: /api and /admin only (priority 100)
  • Static-server routes: /static with priority 110 (higher for correct routing)
  • Both HTTP and HTTPS routes configured for all services
  • Frontend remains at priority 1 as catch-all

Frontend health check

  • Installed wget in nginx:alpine container
  • Health check endpoint /health already configured in nginx.conf

Documentation

  • Updated deployment guides and helper script to reflect /static endpoint availability

Architecture

Traefik Reverse Proxy
├── /static (priority 110) → static-server (nginx)
├── /api, /admin (priority 100) → backend (Django + Gunicorn)
└── /* (priority 1) → frontend (Angular)

How It Works

  1. Backend Dockerfile runs collectstatic during build → files go to /app/staticfiles
  2. Volume backend-static is mounted at /app/staticfiles in backend container
  3. Same volume mounted (read-only) at /usr/share/nginx/html/static in static-server
  4. Traefik routes /static requests to static-server on port 80
  5. nginx efficiently serves static files with proper caching and compression
# docker-compose.yml - static-server service
static-server:
  build:
    context: ./static-server
    dockerfile: Dockerfile
  volumes:
    - backend-static:/usr/share/nginx/html/static:ro
  labels:
    - "traefik.http.routers.static-server.rule=Host(`${DOMAIN:-localhost}`) && PathPrefix(`/static`)"
    - "traefik.http.routers.static-server.priority=110"
# backend/core/settings.py
STATIC_URL = '/static/'  # Changed from 'static/' to fix URL resolution
STATIC_ROOT = BASE_DIR / 'staticfiles'

This approach follows best practices by separating concerns - Django handles the API while nginx efficiently serves static files.

Original prompt

Recheck whole docker deployment progress, backend seems to work so far, but also needs endpoint /static
Frontend container does build but does not pass health checks also rechcek ngingx


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits November 22, 2025 06:57
- Add /static URL configuration to Django backend
- Update Traefik routing to include /static path
- Install wget in frontend container for health checks

Co-authored-by: pirus99 <206077632+pirus99@users.noreply.github.com>
Co-authored-by: pirus99 <206077632+pirus99@users.noreply.github.com>
Copilot AI changed the title [WIP] Recheck whole Docker deployment progress Fix Docker deployment: Add /static endpoint and frontend health checks Nov 22, 2025
Copilot AI requested a review from pirus99 November 22, 2025 07:04
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot this does not seem correct, we want to use the global static files endpoint to serve instead of creating a new one ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you clarify what you mean by "global static files endpoint"? Should I:

  1. Revert the Django URL changes and serve static files directly from the volume using nginx/Traefik?
  2. Use WhiteNoise middleware instead of Django's static() helper?
  3. Something else?

Currently, Traefik routes /static to the backend container (port 8000), and Django serves the files from the volume. What approach would you prefer?

Copy link
Copy Markdown
Author

Copilot AI commented Nov 22, 2025

@copilot backend reports Refused to apply style from '' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
Refused to apply style fr...

Your comment appears to be cut off. Could you provide the complete error message? It looks like there's a "Refused to apply style from..." error. This is typically a CORS or MIME type issue. The full error message would help me diagnose the problem.

Copilot AI requested a review from pirus99 November 22, 2025 07:18
@pirus99
Copy link
Copy Markdown
Owner

pirus99 commented Nov 22, 2025

@copilot i mean the static endpoint serverd within runserver command configured in settings.py

Copy link
Copy Markdown
Author

Copilot AI commented Nov 22, 2025

@copilot i mean the static endpoint serverd within runserver command configured in settings.py

The runserver static file serving only works in development (DEBUG=True). Your Docker setup uses Gunicorn with DEBUG=False, so Django doesn't automatically serve static files.

The static() helper in urls.py is the Django-recommended way to serve static files in production when not using a separate web server. The settings.py configuration (STATIC_URL, STATIC_ROOT) defines where files are collected and the URL path, but doesn't serve them.

If you prefer a different approach, I can:

  1. Keep current implementation (Django's static() helper - simple, works)
  2. Add WhiteNoise middleware (more efficient, Django-recommended for production)
  3. Create a separate nginx container to serve the static volume

Which would you prefer?

Co-authored-by: pirus99 <206077632+pirus99@users.noreply.github.com>
@pirus99
Copy link
Copy Markdown
Owner

pirus99 commented Nov 22, 2025

@copilot would it make sense to serve static files via nginx frontend container ? but can we copy the static files from backend to frontend ? is therse something to copy ?
I wold generally prefer to keep static() but i got those errors: login/?next=/admin/:9 GET https://join.pickull.de/static/admin/js/theme.js net::ERR_ABORTED 404 (Not Found)Understand this error
login/?next=/admin/:1 Refused to execute script from 'https://join.pickull.de/static/admin/js/theme.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.Understand this error
login/?next=/admin/:13 GET https://join.pickull.de/static/admin/js/nav_sidebar.js net::ERR_ABORTED 404 (Not Found)Understand this error
login/?next=/admin/:1 Refused to execute script from 'https://join.pickull.de/static/admin/js/nav_sidebar.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.

…ectory

The static files were collected during Docker build but the volume mount was overwriting them with an empty directory. Now collectstatic runs on container startup after the volume is mounted.

Co-authored-by: pirus99 <206077632+pirus99@users.noreply.github.com>
Copy link
Copy Markdown
Author

Copilot AI commented Nov 22, 2025

@copilot would it make sense to serve static files via nginx frontend container ? but can we copy the static files from backend to frontend ? is therse something to copy ?
I wold generally prefer to k...

The 404 errors were caused by the volume mount overwriting static files collected during build. Fixed in commit 8e8cf24 by running collectstatic in the entrypoint script after the volume is mounted.

The static files now populate to /app/staticfiles on container startup and Django serves them via the /static URL. The current approach (serving via Django) is simpler than copying files to the frontend container and keeps the architecture clean.

Try restarting the containers - the static files should now load correctly.

@pirus99
Copy link
Copy Markdown
Owner

pirus99 commented Nov 22, 2025

@copilot static files get not served correctly, plese try to spin up another nginx container that serves the static files for the backend admin panel and the rest framework. After backend build, copy the needed static files to the new container use collect static command to gather the static files.
Also change the needed traefik configuration. And clean up urs.py in Django project and also all other previous changes that aren't any more needed.

Copilot AI and others added 2 commits November 22, 2025 11:58
- Created static-server with nginx to serve /static files
- Reverted urls.py to remove static() helper (Django no longer serves static files)
- Reverted entrypoint.sh to remove collectstatic command
- Updated Traefik routing: /static now routes to static-server instead of backend
- Backend routes only /api and /admin paths
- Static files collected during backend build and shared via volume
- Added wget to static-server for health checks

Co-authored-by: pirus99 <206077632+pirus99@users.noreply.github.com>
- Set static-server priority to 110 (higher than backend's 100)
- Ensures /static requests are routed to static-server correctly
- Added comment explaining 1-year cache is safe due to Django content hashing

Co-authored-by: pirus99 <206077632+pirus99@users.noreply.github.com>
Copy link
Copy Markdown
Author

Copilot AI commented Nov 22, 2025

@copilot static files get not served correctly, plese try to spin up another nginx container that serves the static files for the backend admin panel and the rest framework. After backend build, copy ...

Implemented as requested in commits a52652b and 695160b:

✅ Created dedicated nginx static-server container for Django admin/DRF static files
✅ Static files collected during backend build via existing collectstatic in Dockerfile
✅ Static files shared between backend and static-server via backend-static volume
✅ Updated Traefik: /static routes to static-server (priority 110), backend handles only /api and /admin (priority 100)
✅ Cleaned up urls.py - removed static() helper
✅ Cleaned up entrypoint.sh - removed collectstatic command

The static-server is now a separate service that efficiently serves static files via nginx, while Django focuses only on the API and admin interface.

Copilot AI changed the title Fix Docker deployment: Add /static endpoint and frontend health checks Fix Docker deployment: Add dedicated nginx static-server and frontend health checks Nov 22, 2025
@pirus99 pirus99 marked this pull request as ready for review November 22, 2025 12:11
@pirus99 pirus99 merged commit 44c22fc into main Nov 22, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants