Skip to content

Install & run

DioscHub ships as a single Docker image. The image is the distribution artifact: it carries the backend, the admin portal, and the web server that fronts them. You give it a Postgres database and a set of environment variables, and it serves. This page covers that path start to finish. The full set of security-sensitive settings lives on the Production hardening checklist — work through that before you expose the deployment to real users.

One image runs the whole product. Inside it, a web server listens on port 80 and reverse-proxies API and WebSocket traffic to the backend on an internal port; the admin portal is served as static assets from the same origin. You map a host port to 80 and route everything through it — there is no second service to run.

The container runs as a non-root user (UID 1000), and the process supervisor shuts the backend and web server down cleanly on SIGTERM. There is no supported bare-metal or non-Docker production path: the image is how DioscHub is meant to run in production.

  • A PostgreSQL database. DioscHub owns its schema and applies it on boot (see below). The database needs two extensions available: uuid-ossp and vector (pgvector). If you run your own Postgres, the image can create them on first start; on managed Postgres where extension creation is restricted, enable both before pointing DioscHub at the database.
  • The boot-required environment. DioscHub refuses to start if a security-sensitive setting is missing or left at a published dev default. The complete list — session and token secrets, the three credential master keys, the database password, and the admin token — is on the Production hardening checklist. Set every one of them before you start the container.
  • Persistent storage if you use the local file store. Uploaded and generated files are written under a storage path inside the container; mount a volume there so they survive a restart. (You can instead point DioscHub at S3-compatible object storage — see Upgrades, backup & DR.)

You do not need Redis for a single instance. Redis only enters the picture when you run more than one instance — see Deployment topologies.

DioscHub reaches Postgres two ways, and in production you set both, pointing at the same database:

VariablePurpose
DB_HOST, DB_PORT, DB_USERNAME, DB_PASSWORD, DB_DATABASEThe primary connection the application and its schema migrations use.
DATABASE_URLA libpq-style URL (postgresql://user:pass@host:5432/diosc_hub) that the chat-session store reads separately.

If only one is set, part of the application cannot connect. Set both to the same Postgres instance and credentials.

DB_PASSWORD must not be the default postgres; the boot gate treats that as an insecure default and refuses to start.

Run the image with your environment injected and a host port mapped to the container’s port 80. In production, inject environment variables through your orchestrator’s secret mechanism rather than a committed file — the boot secrets are credentials.

Terminal window
docker run \
-p 8080:80 \
-e DB_HOST=... -e DB_PORT=5432 -e DB_USERNAME=... -e DB_PASSWORD=... -e DB_DATABASE=diosc_hub \
-e DATABASE_URL=postgresql://user:pass@host:5432/diosc_hub \
-e JWT_SECRET=... -e SESSION_TOKEN_SECRET=... -e ERASURE_HASH_PEPPER=... \
-e CREDENTIALS_MASTER_KEY=... -e LLM_API_KEY_MASTER_KEY=... -e MCP_AUTH_MASTER_KEY=... \
-e ADMIN_API_TOKEN=... \
-v diosc-storage:/data/storage \
<your-dioschub-image>

The value placeholders above are illustrative; generate real secrets as described on the hardening checklist. The volume line is only needed if you use the local file store.

The container brings itself up in order, and each step gates the next:

  1. It waits for the database to accept connections before doing anything else.
  2. It checks the environment. The production-safety gate runs first. If any boot-required setting is missing or left at a dev default, it prints the offending settings and exits — it will not serve traffic in an unsafe state.
  3. It applies the schema. Migrations are bundled into the image and run automatically. On a fresh database they create the schema; on an existing one they adopt it in place and apply only what is new. There is no manual migrate step to run inside the container.
  4. It starts the backend, waits for it to report healthy, then starts the web server. Only after the backend passes its own health check does the front-end server begin accepting traffic on port 80.
DioscHub boot sequence: the container starts, waits for the database, then checks that required secrets and settings are valid. If they are missing or left at an insecure default it prints the offending settings and exits (fail closed); otherwise it applies schema migrations, starts the backend and waits for its health check, starts the web server on port 80, and begins serving traffic.

A healthy start ends with the backend reporting it is listening and the web server coming up on port 80. Probe it from outside:

Terminal window
curl -f http://localhost:8080/api/health

/api/health returns success once the backend is up and can reach the database. /api/health/live and /api/health/ready are also available for orchestrator liveness and readiness probes.

If instead the container exits during startup and the logs show a line about refusing to start over insecure production settings, the boot gate has stopped it on purpose. It lists exactly which settings are at fault — fix those environment values and restart. This is the fail-closed behavior working as intended, not a crash.

For working on DioscHub locally, the repository has dev scripts that are not the production container:

  • npm run start:hub runs the backend directly on port 3333.
  • npm run start:admin runs the admin portal on a Vite dev server on port 7001.

These run the two halves separately with dev tooling. Production is always the single image described above — reach for the container path, not the dev scripts, when you deploy.