A team lead told me: 'We had 47 .env files across 12 services. When we rotated the database password, we missed 3 services. Production was down for 2 hours.' Doppler solved this — one source of truth for all secrets.
What Doppler Offers for Free
Doppler free tier:
- 5 team members
- Unlimited projects and secrets
- All environments — dev, staging, production
- CLI and REST API
- Integrations — Vercel, Netlify, AWS, GCP, GitHub Actions, Docker
- Secret references — share secrets between projects
- Audit logs — who accessed what, when
- Automatic restarts — when secrets change
Quick Start
# Install CLI
brew install dopplerhq/cli/doppler
# Login
doppler login
# Setup in your project
doppler setup
# Run your app with secrets injected
doppler run -- node server.js
# DATABASE_URL, API_KEY, etc. are now environment variables
REST API
# List secrets
curl 'https://api.doppler.com/v3/configs/config/secrets' \
-u 'dp.st.YOUR_SERVICE_TOKEN:' \
--data-urlencode 'project=myapp' \
--data-urlencode 'config=prd'
# Get a specific secret
curl 'https://api.doppler.com/v3/configs/config/secret' \
-u 'dp.st.YOUR_TOKEN:' \
--data-urlencode 'project=myapp' \
--data-urlencode 'config=prd' \
--data-urlencode 'name=DATABASE_URL'
# Set a secret
curl -X POST 'https://api.doppler.com/v3/configs/config/secrets' \
-u 'dp.st.YOUR_TOKEN:' \
-H 'Content-Type: application/json' \
-d '{
"project": "myapp",
"config": "prd",
"secrets": {
"DATABASE_URL": "postgres://user:pass@host:5432/db",
"REDIS_URL": "redis://host:6379"
}
}'
Node.js SDK
// With Doppler CLI — secrets are env vars, no code change needed
const dbUrl = process.env.DATABASE_URL;
const apiKey = process.env.API_KEY;
// That's it. Doppler injects them via `doppler run`.
// Or use the REST API for dynamic secret fetching
async function getSecret(name) {
const res = await fetch(
`https://api.doppler.com/v3/configs/config/secret?project=myapp&config=prd&name=${name}`,
{ headers: { 'Authorization': `Bearer dp.st.${process.env.DOPPLER_TOKEN}` } }
);
const { value } = await res.json();
return value.raw;
}
Docker Integration
# Install Doppler CLI in Docker
RUN apt-get update && apt-get install -y curl gnupg && \
curl -sLf --retry 3 --tlsv1.2 --proto "=https" 'https://packages.doppler.com/public/cli/gpg.DE2A7741A397C129.key' | gpg --dearmor -o /usr/share/keyrings/doppler-archive-keyring.gpg && \
echo "deb [signed-by=/usr/share/keyrings/doppler-archive-keyring.gpg] https://packages.doppler.com/public/cli/deb/debian any-version main" > /etc/apt/sources.list.d/doppler-cli.list && \
apt-get update && apt-get install -y doppler
CMD ["doppler", "run", "--", "node", "server.js"]
GitHub Actions
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dopplerhq/secrets-fetch-action@v1
id: secrets
with:
doppler-token: ${{ secrets.DOPPLER_TOKEN }}
doppler-project: myapp
doppler-config: prd
- run: npm run deploy
env:
DATABASE_URL: ${{ steps.secrets.outputs.DATABASE_URL }}
Secret References (Share Between Projects)
# In project 'shared', config 'prd':
# DATABASE_URL = postgres://...
# In project 'api', config 'prd':
# DATABASE_URL = ${shared.prd.DATABASE_URL}
# One source of truth — change it once, propagates everywhere
Need secure web scraping? Check out my web scraping actors on Apify — managed and secure data collection.
Need help with secrets management? Email me at spinov001@gmail.com.
Top comments (0)