Server Settings Management#
Server settings in Dokploy are managed through two layers: a service layer (web-server-settings.ts) that abstracts singleton read/write access to the database, and a tRPC router (settings.ts) that exposes those operations as access-controlled API procedures.
All global server configuration — domain, TLS, SSH keys, Docker cleanup schedules, build concurrency, SSO enforcement, and more — is stored in a single webServerSettings row in the database . The singleton pattern is enforced in the service layer: getWebServerSettings fetches the first row by createdAt ASC and auto-creates a default row if none exists . updateWebServerSettings always resolves the singleton first, then applies a partial update by ID .
Key Files#
| File | Role |
|---|---|
packages/server/src/services/web-server-settings.ts | Singleton service — getWebServerSettings / updateWebServerSettings |
packages/server/src/db/schema/web-server-settings.ts | Drizzle ORM schema — all columns and Zod validators |
apps/dokploy/server/api/routers/settings.ts | tRPC settingsRouter — all settings procedures |
apps/dokploy/server/api/trpc.ts | Procedure type definitions (adminProcedure, enterpriseProcedure) |
Access Control Tiers#
Most mutations in settingsRouter are gated behind one of three procedure types :
| Procedure | Who Can Call | Extra Check |
|---|---|---|
protectedProcedure | Any authenticated user | — |
adminProcedure | Roles owner or admin only | — |
enterpriseProcedure | Roles owner or admin only | Valid enterprise license via hasValidLicense() |
All destructive or system-impacting mutations — including domain assignment, SSH key management, Traefik configuration, Docker cleanup, and server reload — require adminProcedure . enterpriseProcedure gates features like updateRemoteServersOnly and updateEnforceSSO, which are also explicitly unavailable on cloud deployments .
Domain & TLS Configuration#
The assignDomainServer mutation is the primary entry point for domain setup. It:
- Persists
host,letsEncryptEmail,certificateType("letsencrypt"|"none"|"custom"), andhttpsto thewebServerSettingssingleton viaupdateWebServerSettings. - Calls
updateServerTraefik(settings, host)to rewrite Traefik routing rules. - Calls
updateLetsEncryptEmail(email)if an email was provided.
The certificateType column defaults to "none" in the schema .
Notable Settings Procedures#
| Procedure | Type | What it does |
|---|---|---|
getWebServerSettings | protectedProcedure query | Returns the singleton row; always null on cloud |
saveSSHPrivateKey / cleanSSHPrivateKey | adminProcedure mutation | Writes/clears sshPrivateKey on the singleton |
updateServerIp / getIp | adminProcedure / protectedProcedure | Manages serverIp field |
updateDockerCleanup | adminProcedure mutation | Toggles enableDockerCleanup; schedules/cancels a node-schedule cron job |
updateBuildsConcurrency | adminProcedure mutation | Sets buildsConcurrency (1–100 per Zod validator) |
updateRemoteServersOnly | enterpriseProcedure mutation | Toggles remoteServersOnly; self-hosted only |
updateEnforceSSO | enterpriseProcedure mutation | Toggles enforceSSO; self-hosted only |
reloadServer / reloadTraefik / reloadRedis | adminProcedure mutations | Restarts Docker services; no-ops on cloud |
checkInfrastructureHealth | adminProcedure query | Checks Postgres, Redis, Traefik health; returns "healthy" on cloud |
Cloud vs. Self-Hosted Behavior#
Every procedure that writes system state checks the IS_CLOUD flag and short-circuits with a no-op or error. Read operations on cloud return null or "" for fields that only apply to self-hosted instances . Features requiring enterprise licensing (remoteServersOnly, enforceSSO) throw BAD_REQUEST on cloud regardless of license status .
Audit Trail#
Every mutation in settingsRouter calls audit(ctx, { action, resourceType: "settings", resourceName }) before returning, recording who changed what . The resourceName values map directly to the feature being changed (e.g., "assign-domain-server", "ssh-private-key", "docker-cleanup").