Skip to main content

Architecture

Topology

A single hostname serves both the UI and the API (same origin → no CORS needed).

Arrows show traffic/data flow; backend, ocs-init and automation are the same image (grouped), not connected to each other.

URL mapping

Public URLHandled by
/nginx → redirect to the UI base path
/front/, /front/ocsreports/...SPA (index.html, try_files fallback)
/front/assets/..., /front/config/config.jsonSPA static assets
/api/...proxy_pass to backend:8000 (the /api prefix is stripped)
/api/static/...backend → WhiteNoise
/api/media/...nginx serves the shared media volume directly
/api/asset/legacy/, /api/asset/collection/OCS agent endpoints

Both base paths are configurable — see Base paths.

How requests reach Django (the /api prefix)

nginx strips the API prefix before proxying, so the backend receives /user/, /asset/legacy/, … . Django is told it lives under that prefix with FORCE_SCRIPT_NAME (derived from API_BASE_PATH), so every URL it generates (static, redirects, DRF browsable API) carries the prefix. WhiteNoise is told to match the stripped prefix it actually receives. Details in Django settings overlay.

Startup order

ocs-init runs first and to completion (migrations). backend and automation start only after it succeeds (depends_on: service_completed_successfully), so there is never a migration race. db has a healthcheck the others wait on.

Each arrow means "must be ready before" (depends_on): the database before ocs-init, ocs-init before backend/automation, and backend before frontend.

Runtime-rendered frontend config

The frontend image is built once with a sentinel base path. On every container start, its entrypoint:

  1. materializes the SPA under the requested base segment from an immutable master copy, rebasing the sentinel to FRONTEND_BASE_PATH;
  2. writes config/config.json (the backend URL the browser calls);
  3. renders the nginx config from a template (envsubst) using the base paths, ports, and backend upstream.

So the UI base path, API prefix, public ports and backend address are runtime settings — no rebuild to change them. See Base paths and TLS & networking.

Images

  • backend, ocs-init, automationghcr.io/vdeville/ocsinventory-backend (one image, selected role via OCS_ROLE).
  • frontendghcr.io/vdeville/ocsinventory-frontend (Vue build + nginx).
  • dbpostgres:16-alpine.

Images are built from pinned OCS tags and published per version (:<version>). See Releasing a version.

Persistence

VolumeUsed byHolds
ocs-pgdatadbPostgreSQL data
ocs-mediabackend (rw), frontend (ro)uploads: deployment packages, filemanager

Static files are not a volume — they are baked into the backend image at build time and served by WhiteNoise.