Managing Environment Variables Safely in Dokploy
21 Oct 2025Environment variables are where most self-hosted setups leak secrets. Here is how to keep them contained in Dokploy.
Where variables live
Dokploy has three places that matter:
| Scope | Set in | Available |
|---|---|---|
| Project | Project → Environment | All services in the project |
| Service | Application → Environment | That one service, at runtime |
| Build | Application → Build Arguments | During docker build only |
Runtime variables do not reach your build. That catches people out constantly with frontend frameworks that inline config at build time.
Reference shared values instead of copying them
Set a value once at the project level, then reference it from a service:
DATABASE_URL=${{project.DATABASE_URL}}
Copy-pasting a database password into six services means six places to update when you rotate it. You will miss one.
Use the generated service variables
When you create a Postgres or Redis service in Dokploy, it exposes connection details you can reference rather than hardcode:
DATABASE_URL=${{postgres.DATABASE_URL}}
REDIS_URL=${{redis.REDIS_URL}}
These update automatically if the service password changes.
Keep secrets out of Git
Your repository should contain a .env.example with keys and blank values, and nothing else:
# .env.example
DATABASE_URL=
STRIPE_SECRET_KEY=
SESSION_SECRET=
Add .env to .gitignore on the first commit, not the fiftieth. If a secret has already been committed, rotating it is the only real fix — rewriting history does not help once it is on GitHub.
Separate environments properly
Do not run staging and production against the same variables with a flag. Create separate Dokploy environments. Each gets its own database, its own API keys, its own domain. Staging pointing at the production Stripe key has ended worse days than yours.
Rotate on a schedule you will keep
Quarterly is realistic. Annually is not. Put it in a calendar, and keep a short list of where each secret is used so rotation takes twenty minutes instead of an afternoon:
STRIPE_SECRET_KEY → api service, webhook worker
SESSION_SECRET → api service (rotating logs everyone out)
S3_ACCESS_KEY → api service, backup cron
One thing to check today
Open your Dokploy panel and look at your production service’s environment tab. If any value there is also sitting in a file in your repo, you have work to do this afternoon.