Files
proxy/docs/docker.md
T
wmantly 94ad6143cc Dockerize the proxy (all-in-one image) + Docker docs
All-in-one Dockerfile bundling OpenResty + the Node mgmt app + Redis in one
container, mirroring the bare-metal ops/install.sh layout:
- Dockerfile (openresty/openresty:1.31.1.1-2-bookworm-fat base; dumb-init PID 1;
  luarocks install lua-resty-auto-ssl/luasocket/lua-resty-ipmatcher; node 22.x;
  npm ci --omit=dev; OpenResty confs + lua copied into place).
- docker-entrypoint.sh: fallback cert, sed-parameterize RESOLVER/REAL_IP_FROM,
  start bundled redis + node app, exec openresty foreground.
- docker-compose.yml (standalone), .dockerignore, DEPLOYMENT.md.
- nodejs/routes/render.js: /health endpoint for healthchecks.
- nodejs/models/user_ldap.js: tlsOptions forwarded to ldapts Client so the
  proxy can bind ldaps:// with a self-signed cert (app_ldap__tlsOptions__*).
- nodejs/package.json: bump @simpleworkjs/conf to ^1.1.0 (app_* env overrides).
- docs/docker.md + index.md: Docker deployment guide + fronting an SSO Manager.
- ops/proxy.service: add WorkingDirectory=/var/www/proxy/nodejs (bare-metal
  cwd fix so relative conf/ paths resolve).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-11 17:02:52 -04:00

4.8 KiB

layout, title
layout title
default Docker

Docker Deployment

← Back to Home

The proxy ships as a single all-in-one Docker image bundling OpenResty + the Node management app + Redis in one container, mirroring the bare-metal ops/install.sh layout. This is the easiest way to run the proxy standalone, or as part of the unified theta-env stack.

Quick start (standalone)

git clone https://github.com/theta42/proxy.git
cd proxy
cp .env.example .env   # optional: set OIDC/LDAP wiring + ports
docker compose up -d --build
  • Proxy (public, auto-SSL): https://<host>/
  • Management UI / API: http://127.0.0.1:3000/ (bound to localhost)
  • Health: http://127.0.0.1:3000/health{"status":"ok"}

How configuration works

The app loads config via @simpleworkjs/conf, which deep-merges, in order:

  1. conf/base.js (committed defaults)
  2. conf/<NODE_ENV>.js (optional)
  3. conf/secrets.js (gitignored)
  4. app_* environment variables — the highest-precedence layer

Any env var starting with app_ overrides the merged config; the rest of the name splits on double-underscore (__) into a nested path. Values are JSON.parse-coerced when possible, kept as strings otherwise.

Requires @simpleworkjs/conf >= 1.1.0. The app_* env layer is not honored on 1.0.0. The lock is already on ^1.1.0.

Key app_* variables

Env var Sets
app_oidc__issuer conf.oidc.issuer (browser-facing SSO URL)
app_oidc__authorizationEndpoint conf.oidc.authorizationEndpoint
app_oidc__tokenEndpoint conf.oidc.tokenEndpoint (server-to-server; can be internal)
app_oidc__userinfoEndpoint conf.oidc.userinfoEndpoint (server-to-server)
app_oidc__endSessionEndpoint conf.oidc.endSessionEndpoint
app_oidc__clientId / app_oidc__clientSecret OIDC client creds
app_oidc__redirectUri conf.oidc.redirectUri (must match the SSO client)
app_oidc__enabled conf.oidc.enabled (boolean)
app_ldap__url conf.ldap.url (ldaps://…:636 or ldap://…:389)
app_ldap__bindDN / app_ldap__bindPassword LDAP service account
app_ldap__searchBase / app_ldap__userFilter user search
app_ldap__tlsOptions__rejectUnauthorized false for self-signed LDAPS
app_ldap__tlsOptions__ca path to a CA cert for strict trust
app_auth__adminUsers local anti-lockout admin (uid)
app_auth__adminGroups SSO/LDAP groups that are global admin (JSON array)
app_redis__prefix conf.redis.prefix (default proxy_)

See DEPLOYMENT.md for the complete reference.

OpenResty runtime env

Variable Default Description
RESOLVER 127.0.0.11 DNS for upstream names in Host records (Docker's embedded DNS)
REAL_IP_FROM empty Trusted CIDR for X-Real-IP. Empty = the proxy is the front (removes the real_ip block). Set to an upstream proxy's CIDR if one sits in front.

Auto-SSL / Let's Encrypt

lua-resty-auto-ssl stores certs in the bundled Redis (in-memory by default — lost on container recreation). For cert persistence, mount a Redis AOF/RDB volume. Port 80 is required for HTTP-01 challenges (mapped in the compose).

Fronting an SSO Manager

The proxy is a natural front for theta42/sso-manager-node: it terminates TLS for the SSO's UI and protects it with OIDC login, while also binding to the SSO's LDAP directly for user lookups. To run both together:

  1. One Docker network so the proxy reaches the SSO internally at http://sso-manager:3001 (token/userinfo) and ldaps://sso-manager:636.
  2. Set the SSO's app_oauth__issuer to the browser-facing HTTPS URL the proxy serves the SSO at (e.g. https://sso.example.com).
  3. Register the proxy as an OIDC client in the SSO, with redirectUri matching https://proxy.example.com/api/auth/oidc/callback.
  4. LDAP: point app_ldap__url at ldaps://sso-manager:636, create a dedicated service account (cn=ldapclient,ou=people,…), and for the SSO's self-signed LDAPS cert set app_ldap__tlsOptions__rejectUnauthorized=false (or mount the cert and use app_ldap__tlsOptions__ca=<path>).

The theta42/theta-env unified repo automates all four steps with ./setup.sh — see theta-env docs.

Bare metal

Prefer a systemd install? See the Installation Guide for the ops/install.sh automated installer on Debian/Ubuntu.

← Back to Home