Files
altstack-data/docs/app/concepts/env-secrets/page.mdx
2026-02-25 22:36:27 +05:30

154 lines
4.1 KiB
Plaintext

---
title: "Environment Variables & Secrets"
description: "How to manage .env files, Docker secrets, and sensitive configuration for self-hosted tools. Stop hardcoding passwords."
---
# Environment Variables & Secrets
Every self-hosted tool needs configuration: database passwords, API keys, admin emails. The **wrong** way is hardcoding them in `docker-compose.yml`. The **right** way is environment variables.
## The Basics: `.env` Files
Docker Compose automatically reads a `.env` file in the same directory as your `docker-compose.yml`:
```bash
# .env
POSTGRES_PASSWORD=super_secret_password_123
ADMIN_EMAIL=you@yourdomain.com
SECRET_KEY=a1b2c3d4e5f6g7h8i9j0
```
```yaml
# docker-compose.yml
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
```
Docker Compose substitutes `${POSTGRES_PASSWORD}` with the value from `.env`. Your secrets stay out of your Compose file.
> ⚠️ **Critical:** Add `.env` to your `.gitignore` immediately. Never commit secrets to Git.
```bash
echo ".env" >> .gitignore
```
## Generating Strong Passwords
Don't use `password123`. Generate proper secrets:
```bash
# Generate a 32-character random string
openssl rand -base64 32
# Generate a hex string (great for SECRET_KEY)
openssl rand -hex 32
# Generate a URL-safe string
python3 -c "import secrets; print(secrets.token_urlsafe(32))"
```
### Template for Common Tools
Most self-hosted tools need similar variables. Here's a reusable `.env` template:
```bash
# .env template — generate all values before first run
# Database
POSTGRES_USER=app
POSTGRES_PASSWORD= # openssl rand -base64 32
POSTGRES_DB=app_db
# App
SECRET_KEY= # openssl rand -hex 32
ADMIN_EMAIL=you@yourdomain.com
ADMIN_PASSWORD= # openssl rand -base64 24
BASE_URL=https://app.yourdomain.com
# SMTP (for email notifications)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=you@gmail.com
SMTP_PASSWORD= # Use app-specific password
```
## Default Values (Fallbacks)
Use the `:-` syntax for non-sensitive defaults:
```yaml
environment:
NODE_ENV: ${NODE_ENV:-production} # Defaults to "production"
LOG_LEVEL: ${LOG_LEVEL:-info} # Defaults to "info"
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} # No default — MUST be set
```
## Docker Secrets (Advanced)
For production setups, Docker Secrets are more secure than environment variables — they're stored encrypted and mounted as files:
```yaml
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
secrets:
db_password:
file: ./secrets/db_password.txt
```
```bash
# Create the secret file
mkdir -p secrets
openssl rand -base64 32 > secrets/db_password.txt
chmod 600 secrets/db_password.txt
```
> 💡 Not all images support `_FILE` suffix variables. Check the image's documentation on Docker Hub.
## Multiple Environments
Keep separate `.env` files for different environments:
```bash
.env # Production (default)
.env.local # Local development
.env.staging # Staging server
```
Use them explicitly:
```bash
# Use a specific env file
docker compose --env-file .env.staging up -d
```
## Security Checklist
- [ ] `.env` is in `.gitignore`
- [ ] No secrets are hardcoded in `docker-compose.yml`
- [ ] All passwords are randomly generated (32+ characters)
- [ ] Database ports are NOT exposed to the internet
- [ ] Secret files have `chmod 600` permissions
- [ ] Default passwords from docs have been changed
## Common Mistakes
**"Variable is empty in the container"** → Check for typos. Variable names are case-sensitive. `POSTGRES_password` ≠ `POSTGRES_PASSWORD`.
**"Changes to .env aren't applying"** → You need to recreate the container: `docker compose up -d --force-recreate`.
**"I committed my .env to Git"** → Even after removing it, it's in Git history. Rotate ALL secrets immediately and use `git filter-branch` or BFG Repo Cleaner.
## Next Steps
→ [Monitoring & Observability](/concepts/monitoring) — Know when things break
→ [Docker in 10 Minutes](/concepts/docker-basics) — Review the fundamentals