fe9b7c168b
All-in-one Dockerfile.openldap bundling the app + OpenLDAP + Redis in one container, plus an idempotent bare-metal install.sh, and a Jekyll docs site for GitHub Pages: - Dockerfile.openldap (node:20-alpine; openldap + pw-sha2/ppolicy/memberof/ refint; dumb-init PID 1; npm ci --omit=dev; tos.md copied to /). - docker-entrypoint.sh: generate slapd.conf (mdb + overlays + TLS + indexes + access), self-signed LDAPS cert, seed directory tree + required groups, bundled redis, export app_* config, exec node. - docker-compose.yml, .dockerignore, DEPLOYMENT.md, secrets.js.example. - install.sh: idempotent Debian/Ubuntu bare-metal installer (Node 20.x, OpenLDAP, Redis, systemd unit) with flags + --dry-run/--skip-ldap/--skip-app. - ops/ldif/: memberof/refint/tls/index/nodes/logging LDIFs. - nodejs/conf/base.js: generic defaults (dc=example,dc=com / localhost / SSO Manager) so per-deployment values move to secrets.js or app_* env. - nodejs/package.json: bump @simpleworkjs/conf to ^1.1.0 (app_* env overrides). - nodejs/routes/index.js: /health endpoint for healthchecks. - docs/: _config.yml + index/deployment/configuration/oauth/ldap pages (jekyll-theme-cayman) for GitHub Pages from /docs. Co-Authored-By: Claude <noreply@anthropic.com>
93 lines
4.5 KiB
YAML
93 lines
4.5 KiB
YAML
# Docker Compose for the SSO Manager all-in-one image (app + OpenLDAP in one container).
|
|
#
|
|
# The image (Dockerfile.openldap) bundles a slapd that the app talks to over
|
|
# localhost. Configuration is supplied to the app via `app_*` environment
|
|
# variables — the highest-precedence config layer in @simpleworkjs/conf. Any
|
|
# `app_*` var not set here falls back to a sensible default baked into
|
|
# docker-entrypoint.sh (e.g. app_ldap__url -> ldap://localhost:389).
|
|
#
|
|
# Copy this file to .env (or export the vars) to set the secrets below, or
|
|
# set them inline on the command line:
|
|
# LDAP_ADMIN_PASS=... JWT_SECRET=... docker compose up -d
|
|
#
|
|
# Requires @simpleworkjs/conf >= 1.1.0 in the image (env overrides). Refresh
|
|
# nodejs/package-lock.json with `npm install @simpleworkjs/conf@^1.1.0` before
|
|
# building, so the image actually contains the env-override feature.
|
|
|
|
services:
|
|
sso-manager:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile.openldap
|
|
container_name: sso-manager
|
|
restart: unless-stopped
|
|
ports:
|
|
# SSO Manager web UI (HTTP inside the container; terminate TLS at the
|
|
# front proxy — e.g. the theta42/proxy). Don't expose 3001 to the open
|
|
# internet; bind it to localhost or leave it on the docker network only.
|
|
- "${PORT:-3001}:3001"
|
|
# LDAPS — direct LDAP binds from legacy apps / the proxy over the network
|
|
# (TLS, self-signed cert by default; mount your own at LDAP_CERT_DIR).
|
|
- "${LDAPS_PORT:-636}:636"
|
|
# LDAP plain (389) is NOT mapped to the host by default — it would allow
|
|
# cleartext password binds over the LAN. Uncomment to permit StartTLS or
|
|
# plain binds from the LAN (not recommended):
|
|
# - "${LDAP_PORT:-389}:389"
|
|
environment:
|
|
# ── LDAP server-side (configures the bundled slapd) ──
|
|
- LDAP_BASE_DN=${LDAP_BASE_DN:-dc=example,dc=com}
|
|
- LDAP_DOMAIN=${LDAP_DOMAIN:-example.com}
|
|
- LDAP_ADMIN_PASS=${LDAP_ADMIN_PASS:-admin} # slapd root + app bind password
|
|
- ORG_NAME=${ORG_NAME:-SSO Manager}
|
|
# CN on the LDAP TLS cert. Clients verify against this hostname. Leave
|
|
# empty to default to LDAP_DOMAIN; set to the public hostname clients
|
|
# connect over (computed in docker-entrypoint.sh, not here, to avoid
|
|
# nested-variable interpolation limitations in compose v1).
|
|
- LDAP_CERT_CN=${LDAP_CERT_CN:-}
|
|
|
|
# ── App config overrides (app_* -> @simpleworkjs/conf) ──
|
|
# Defaults come from docker-entrypoint.sh; set these to override.
|
|
# - app_oauth__issuer=https://sso.example.com
|
|
# - app_ldap__url=ldap://localhost:389 # default; points at bundled slapd
|
|
# - app_ldap__bindDN=cn=admin,${LDAP_BASE_DN}
|
|
# - app_ldap__bindPassword=${LDAP_ADMIN_PASS}
|
|
# - app_ldap__userBase=ou=people,${LDAP_BASE_DN}
|
|
# - app_ldap__groupBase=ou=groups,${LDAP_BASE_DN}
|
|
- app_oauth__jwtSecret=${JWT_SECRET} # falls back to an auto-generated secret
|
|
# OIDC issuer advertised in /.well-known/openid-configuration. This is the
|
|
# browser-facing URL the front proxy serves the SSO at — the theta42/proxy
|
|
# (an OIDC client) and other apps use it for discovery. Server-to-server
|
|
# token/userinfo calls from the proxy can go to http://sso-manager:3001
|
|
# over the docker network; only the issuer/redirect URLs must be public.
|
|
# Leave empty to default to https://sso.<LDAP_DOMAIN> (set in the entrypoint).
|
|
- app_oauth__issuer=${OAUTH_ISSUER:-}
|
|
- app_name=${ORG_NAME:-SSO Manager}
|
|
|
|
# ── Optional SMTP (outbound email) ──
|
|
- app_smtp__host=${SMTP_HOST:-localhost}
|
|
- app_smtp__port=${SMTP_PORT:-587}
|
|
- app_smtp__user=${SMTP_USER:-}
|
|
- app_smtp__pass=${SMTP_PASS:-}
|
|
- app_smtp__from=${SMTP_FROM:-SSO Manager <noreply@example.com>}
|
|
|
|
- NODE_ENV=production
|
|
- NODE_PORT=3001
|
|
volumes:
|
|
# Persist the LDAP database across container recreation.
|
|
- ldap-data:/var/lib/ldap
|
|
# Persist the auto-generated self-signed TLS cert so clients don't have to
|
|
# re-trust it on every rebuild. To use your own CA-signed cert instead,
|
|
# replace this with a bind mount of your cert dir, e.g.:
|
|
# - ./certs:/etc/openldap/certs
|
|
# (must contain ldap.crt + ldap.key; the entrypoint leaves them untouched).
|
|
- ldap-certs:/etc/openldap/certs
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3001/health"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 30s
|
|
|
|
volumes:
|
|
ldap-data:
|
|
ldap-certs: |