Recommended shape
Run two TaskBandit containers behind your proxy:
taskbandit-server:8080for API, auth, realtime sync, uploads, health, and notification delivery.taskbandit-web:80for the client UI/PWA at/and the admin UI at/admin.
Use HTTPS at the proxy. The containers do not need to terminate TLS themselves.
Important .env values
For a normal dedicated web origin plus a separate API origin, use values like these:
TASKBANDIT_PUBLIC_WEB_BASE_URL=https://taskbandit.example.com
TASKBANDIT_PUBLIC_API_BASE_URL=https://api.taskbandit.example.com
TASKBANDIT_SERVE_EMBEDDED_WEB=false
TaskBandit derives the admin URL automatically as <web-base-url>/admin. In most domain-based installs, you do not need to set separate admin/client URL overrides or explicit CORS values.
Only set TASKBANDIT_REVERSE_PROXY_PATH_BASE if you intentionally mount the API under a subpath. For most domain-based setups, leave it blank.
Headers to preserve
The server needs the original browser-facing host and scheme so auth callbacks, generated URLs, and secure-cookie decisions stay correct.
HostX-Forwarded-HostX-Forwarded-ProtoX-Forwarded-ForUpgradeandConnectionfor live sync/WebSocket-style traffic.
Nginx Proxy Manager UI example
If you use the Nginx Proxy Manager web UI, create exactly two proxy hosts:
taskbandit.example.com->taskbandit-web:80if NPM is on the same Docker network, or your Docker host IP on port4173.api.taskbandit.example.com->taskbandit-server:8080if NPM is on the same Docker network, or your Docker host IP on port8080.
Keep /admin on the web host. Do not create a third proxy host just for the admin UI.
After saving the proxy hosts, verify these URLs:
https://taskbandit.example.com/https://taskbandit.example.com/admin/https://api.taskbandit.example.com/health
Nginx example
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443 ssl http2;
server_name api.taskbandit.example.com;
location / {
proxy_pass http://taskbandit-server:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
server {
listen 443 ssl http2;
server_name taskbandit.example.com;
location / {
proxy_pass http://taskbandit-web:80;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Traefik labels example
services:
server:
labels:
- traefik.enable=true
- traefik.http.routers.taskbandit-api.rule=Host(`api.taskbandit.example.com`)
- traefik.http.routers.taskbandit-api.entrypoints=websecure
- traefik.http.routers.taskbandit-api.tls=true
- traefik.http.services.taskbandit-api.loadbalancer.server.port=8080
web:
labels:
- traefik.enable=true
- traefik.http.routers.taskbandit-web.rule=Host(`taskbandit.example.com`)
- traefik.http.routers.taskbandit-web.entrypoints=websecure
- traefik.http.routers.taskbandit-web.tls=true
- traefik.http.services.taskbandit-web.loadbalancer.server.port=80
Subpath hosting notes
Prefer dedicated hostnames when possible. If you must mount the API under a subpath, set TASKBANDIT_REVERSE_PROXY_PATH_BASE to that subpath and keep /health routed separately or use Docker health checks instead.
TASKBANDIT_REVERSE_PROXY_PATH_BASE=/taskbandit