Files
2026-09-22 00:50:30 +05:00

2.5 KiB

Production deployment

One compose.yml builds every service from the repo root:

  • backend/ — Django API on gunicorn :5000, static via WhiteNoise
  • frontend/ — Vite SPA, built to static files at image build time
  • web — the only published container: nginx serving the SPA and reverse proxying the API. No node or bun at runtime.
host.com/          -> nginx   (SPA, history fallback to index.html)
host.com/api/      -> backend (Django REST API)
host.com/admin/    -> backend (Django admin)
host.com/static/   -> backend (WhiteNoise: admin/DRF assets)
host.com/media/    -> nginx   (shared `media` volume)

Because nginx fronts both, the browser sees one origin and there is no CORS in production.

Files

File Purpose
compose.yml database + backend + worker + web
api.Dockerfile Django image (collectstatic at build)
web.Dockerfile node builds frontend/dist, nginx serves it
nginx.conf SPA + API/admin/static/media routing, asset cache headers
entrypoint.sh backend: wait for postgres, migrate, then gunicorn

Configure

Fill backend/.env (copy from backend/.env.example). For the compose network:

DJANGO_DEBUG=False
SECRET_KEY=<generate one>
POSTGRES_HOST=database
POSTGRES_PORT=5432
POSTGRES_DATABASE=sarlink
POSTGRES_USER=sarlink
POSTGRES_PASSWORD=<strong>
ALLOWED_HOSTS=localhost,127.0.0.1,backend,portal.sarlink.net
CSRF_TRUSTED_ORIGINS=https://portal.sarlink.net
FRONTEND_URL=https://portal.sarlink.net
SMS_API_URL=...
SMS_API_KEY=...

The POSTGRES_* values also feed the database service through compose defaults, so keep them in sync or export them before up.

The frontend needs no runtime configuration: it calls a relative /api/... which nginx routes to the backend.

Build & run

docker compose -f .build/prod/compose.yml up -d --build
docker compose -f .build/prod/compose.yml exec backend python manage.py createsuperuser

The site is on http://localhost:8080; remap the web port behind your TLS terminator. Migrations run on backend startup.

Running from published images

The build pushes git.shihaam.dev/sarlink/sarlinkportal/{backend,web}. To deploy without building, replace each service's build: block with its image: and keep database, the volumes, env_file and the web port mapping.