Skip to content

Configuration ​

Most of DockPod's day-to-day configuration happens in the UI under Settings, not in a config file.

Data Directory Layout ​

Everything DockPod persists lives under --data-dir (default ./data):

data/
├── dockpod.db          # SQLite — users, deploy apps, build logs, audit log, etc.
├── repos/              # git clones for Git Deployment apps, one folder per app ID
├── ssh-keys/           # per-app Ed25519 deploy keys (0600 permissions)
├── paste/              # saved compose files + env files for Paste & Deploy and 1-Click Deploy
├── local-ca/           # self-generated CA cert+key for .test/.local custom domains (see Custom Domains)
└── traefik-dynamic/    # per-domain Traefik routing config + certs, generated as domains are added

Back up dockpod.db (and ssh-keys/ if you use private repos) to preserve your install's state — and back up the secrets encryption key described below, which lives outside this directory.

Secrets Encryption at Rest ​

Reversible secrets in dockpod.db — provisioned-database passwords, git-provider tokens, webhook secrets, TOTP secrets, the SMTP password, the JWT signing secret — are encrypted with AES-256-GCM. (Login passwords, API keys, and 2FA backup codes aren't here: those are one-way bcrypt hashes, never decrypted.)

The encryption key is managed for you, no configuration required:

  • On first start DockPod generates a random key and writes it to /etc/dockpod/data.key (permissions 0600), then reuses it on every restart. If /etc/dockpod isn't writable (e.g. running as a non-root dev process), it falls back to <data-dir>/data.key and logs a warning.
  • The key lives outside the data directory on purpose: a leaked data-dir backup then can't decrypt anything without the separately-stored key. That separation is the whole point — so for disaster recovery you must back up both the data directory and /etc/dockpod/data.key.
  • Losing the key after secrets are encrypted makes them unrecoverable — there is no recovery path. Treat data.key as critically as the data itself.

Existing installs upgrade transparently: the key is generated on the first start after upgrading, and a one-time backfill encrypts any secrets that were previously stored in plaintext.

Honest scope: this protects against the database file (or a data-dir backup) leaking without the key. It does not protect against someone who already has root/host access (the running process must read the key), and the same database password is independently visible via docker inspect on the running database container. Secure the host and restrict access to /etc/dockpod and the data directory accordingly.

License ​

DockPod ships fully functional on the Free tier — no license required. To unlock Pro features (rollback, unlimited Git Deployment/database provisioning, Telegram/Slack/Discord notifications, scheduled tasks, multi-user), go to Settings → General → License and paste your license key. See Pricing for the full Free vs Pro breakdown.

Licenses are Ed25519-signed, verified offline (no phone-home required after activation), and locked to a specific machine — Settings → General → License shows this server's Machine ID; send it to whoever issues your license before it can be minted for this install.

Let's Encrypt (ACME) Email ​

Set this once under Settings → General → Reverse Proxy → ACME email (Let's Encrypt), then click Save. It's the account address Let's Encrypt registers your certificates against and where it sends expiry and renewal notices, so use an address someone actually reads. A single address covers the whole install — deployed app domains, the panel domain, and the MCP domain all share one Let's Encrypt account.

When it's required. Before you can save any domain that needs a real public certificate. Attempting one without it is rejected outright rather than left to fail later at issuance time:

configure an ACME email under Settings > Reverse Proxy before adding a public domain

The reverse proxy's Start button is likewise disabled until an address is set.

When it isn't. Local development domains (.test, .local, .localhost, .example, .invalid) get a certificate DockPod issues from its own local CA — Let's Encrypt can never issue for IANA-reserved names, so no account is involved. Domains saved with skip_tls get no certificate at all. Both are exempt, and either one can start the reverse proxy without an email ever being set.

Changing it takes a proxy restart. The address is baked into Traefik's start-up arguments when its container is created, not read live from the database:

[email protected]
--certificatesresolvers.letsencrypt.acme.httpchallenge=true
--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web
--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json

Saving a new address updates the setting but leaves the running container on the old one. DockPod reconciles this automatically the next time the panel restarts. To apply it immediately, use Stop then Start on the same screen — while it's stopped, every app and the panel itself are unreachable through their domains, though direct IP and published ports keep working throughout.

This matters most in one specific order of operations: a .test domain starts the reverse proxy without an email, so if you add the address afterwards, the container is still running without a Let's Encrypt resolver configured at all. A public domain added at that point will never get its certificate, however correct its DNS is. Restart the proxy after setting the address and before adding the domain.

Restarting is safe with respect to certificates already issued. They live in the dockpod-traefik-certs volume mounted at /letsencrypt, which survives the container being recreated — nothing is re-requested, so this can't push you toward Let's Encrypt's rate limits.

What issuance still needs. The email alone doesn't produce a certificate. The domain's DNS A/AAAA record has to resolve to this host, and port 80 must be reachable from the internet — Let's Encrypt validates over the HTTP-01 challenge, which it serves on the web entrypoint. A firewall that only allows 443 will fail every issuance while looking perfectly configured.

Panel Domain ​

Settings → General → Domain lets you access the panel itself at a custom domain over HTTPS instead of http://server-ip:8080. It reuses the exact same shared Traefik instance and Let's Encrypt account as your deployed apps' domains — see Custom Domains for how certificate issuance works (real domain vs. local .test/.local vs. plain HTTP), the same logic applies here. The first save takes a few seconds while the reverse proxy restarts to pick up the new route; existing app domains keep working throughout.

MCP Domain ​

The same screen has a separate MCP Domain field, and it exists to solve one problem: the MCP listener is the only part of DockPod that isn't behind HTTPS by default.

MCP runs on its own port (--mcp-addr, default 8090) rather than on the panel's port — see Why a Separate Port. Nothing fronts that port, so out of the box the only address a client can use is plain HTTP, and an MCP client authenticates with a Bearer API key on every request. Over a network you don't control, that key is sent in the clear.

Setting an MCP Domain — a hostname of its own, such as mcp.example.com — puts the shared Traefik instance in front of it. You get https://mcp.example.com/mcp on the standard port 443, TLS terminated at the proxy and forwarded to the MCP listener with response buffering disabled so streaming still works. It must be a different hostname from the panel domain.

What you get with and without it:

MCP DomainAddress clients useEncrypted
Sethttps://mcp.example.com/mcpYes
Not sethttp://<panel-domain-or-ip>:8090/mcpNo — the API key travels in the clear

Settings → API Keys shows whichever address currently applies, and the dialog that appears when you generate a key shows it again alongside a ready-to-paste client config. If you have no MCP Domain, both places say so.

Setting an MCP Domain doesn't remove or redirect the direct port. http://localhost:8090/mcp stays available to clients running on the DockPod host itself, which is often what you want for local development, and removing the domain later only removes its Traefik route.

Both fields accept hostnames only — no http:// or https://, path, port, wildcard, underscore, raw IP address, or trailing dot. DockPod lowercases the hostname and rejects it if the same hostname is already assigned to the panel, MCP, a Git Deployment, Paste & Deploy, or 1-Click Deploy.

Profile — Password & Two-Factor Authentication ​

Click your username (top right) → Profile for account-level settings that apply to you specifically, not the whole install — unlike Settings, this page has no admin gate, so it's where a non-admin team member's own account settings will live too.

Change Password updates the password you sign in with — requires your current password, not just an active session.

Two-Factor Authentication adds a TOTP second factor (Google Authenticator, 1Password, Authy, etc.) to your login. It's per-user, opt-in, and not Pro-gated — available on a Free-tier single-admin install too. Enrolling shows a QR code to scan and, once you confirm a code from your app, 10 backup codes — save them somewhere safe, each is single-use and meant for when you lose access to your authenticator device. Once enabled, logging in becomes a two-step flow: password first, then the 6-digit code (or a backup code). Disabling requires re-entering your password, not just being logged in.

Environment Variables Summary ​

See Installation for the full flag/env-var table.

Released under a commercial-friendly freemium license.