Appearance
Environment Variables
All configuration is supplied via environment variables. No config files need to be edited manually — the setup wizard and admin UI write to /app/config/appsettings.Production.json automatically.
Database
| Variable | Required | Default | Description |
|---|---|---|---|
SETUP_DB_HOST | Yes | — | PostgreSQL hostname or IP |
SETUP_DB_PORT | No | 5432 | PostgreSQL port |
SETUP_DB_NAME | Yes | — | Database name |
SETUP_DB_USERNAME | Yes | — | Database user |
SETUP_DB_PASSWORD | Yes | — | Database password |
First-run admin account
Providing these variables skips the setup wizard entirely and configures the app on first boot.
| Variable | Required | Description |
|---|---|---|
SETUP_ADMIN_EMAIL | Yes (for auto-setup) | Admin account email address |
SETUP_ADMIN_PASSWORD | Yes (for auto-setup) | Admin account password — must meet complexity requirements (8+ chars, uppercase, digit) |
SETUP_ADMIN_DISPLAY_NAME | No | Display name shown in the UI (defaults to email if omitted) |
TIP
If you omit the SETUP_* variables, the app starts in setup-wizard mode and walks you through configuration in the browser. Either approach works — env vars are more convenient for Docker/automated deployments.
Application
| Variable | Example | Description |
|---|---|---|
App__BaseUrl | https://tasks.example.com | Public-facing URL. Used in email links and CORS origin validation. |
CORS__AdditionalOrigins | http://localhost:6274 | Comma-separated extra origins for CORS (e.g. a local dev client or MCP Inspector) |
Networking
Exactly one of the following modes should be active. See Reverse Proxy and Direct TLS for full setup guides.
Mode 1 — Reverse proxy (recommended)
| Variable | Value | Description |
|---|---|---|
PROXY_ENABLED | true | Trust X-Forwarded-For and X-Forwarded-Proto from the upstream proxy |
Mode 2 — Direct TLS
| Variable | Example | Description |
|---|---|---|
TLS_ENABLED | true | Enable Kestrel HTTPS — Kestrel terminates TLS directly |
TLS_CERT_PATH | /certs/cert.pem | Path to certificate file inside the container |
TLS_KEY_PATH | /certs/key.pem | Path to private key file (PEM only — omit for PFX) |
TLS_CERT_PASSWORD | secret | PFX password (optional) |
TLS_PORT | 8443 | HTTPS port (default: 8443) |
Mounting your certificate
The paths above refer to locations inside the container. Mount your certificate directory from the host using -v:
bash
docker run \
-p 443:8443 \
-v /etc/ssl/apimeld:/certs:ro \
-e TLS_ENABLED=true \
-e TLS_CERT_PATH=/certs/cert.pem \
-e TLS_KEY_PATH=/certs/key.pem \
apimeldThe :ro flag mounts the directory read-only — the app only needs to read the cert, not write to it.
WARNING
Do not set both PROXY_ENABLED=true and TLS_ENABLED=true at the same time. The app will log a warning and behaviour will be unpredictable.
Ports
These are the ports the container listens on internally. Map them to any external port you like with Docker's -p flag — or don't expose a port at all if your reverse proxy handles it via a shared network.
| Container port | Protocol | When active |
|---|---|---|
8080 | HTTP | Always |
8443 | HTTPS | Only when TLS_ENABLED=true |
bash
# Expose on the same ports
docker run -p 8080:8080 apimeld
# Expose on standard ports externally
docker run -p 80:8080 -p 443:8443 apimeld
# Reverse proxy on a shared Docker network — no ports exposed to the host
docker run --network my-proxy-network apimeld