Self-Hosting Infisical with Docker Compose
What Is Infisical?
Infisical is an open-source secrets management platform. It stores API keys, database credentials, tokens, and environment variables in an encrypted vault with team-based access control, versioning, and automatic syncing to your applications. It replaces Doppler, HashiCorp Vault (for simple use cases), and scattered .env files. Official site
The Problem It Solves
Every self-hosted service needs credentials — database passwords, API keys, SMTP settings. Most people manage these in .env files scattered across servers, copy-pasted between services, with no version history and no access control. Infisical centralizes all of that:
| Without Infisical | With Infisical |
|---|---|
.env files on each server | Single encrypted vault |
| Copy-paste credentials | Sync to applications automatically |
| No audit trail | Full version history and access logs |
| Everyone has all secrets | Role-based access per project |
| No rotation | Secret rotation workflows |
| Plain text on disk | End-to-end encrypted |
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 1 GB of free RAM
- A domain name (recommended for team access)
Docker Compose Configuration
services:
infisical-db:
image: postgres:16-alpine
container_name: infisical-db
environment:
POSTGRES_DB: infisical
POSTGRES_USER: infisical
POSTGRES_PASSWORD: change-this-db-password
volumes:
- infisical-db:/var/lib/postgresql/data
networks:
- infisical
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U infisical"]
interval: 10s
timeout: 5s
retries: 5
infisical-redis:
image: redis:7.4-alpine
container_name: infisical-redis
volumes:
- infisical-redis:/data
networks:
- infisical
restart: unless-stopped
infisical:
image: infisical/infisical:v0.158.13
container_name: infisical
ports:
- "8080:8080"
environment:
# Encryption key (generate with: openssl rand -hex 16)
ENCRYPTION_KEY: generate-a-32-char-hex-string
# Auth secret (generate with: openssl rand -base64 32)
AUTH_SECRET: generate-a-random-base64-string
# Database
DB_CONNECTION_URI: postgresql://infisical:change-this-db-password@infisical-db:5432/infisical
# Redis
REDIS_URL: redis://infisical-redis:6379
# Application
SITE_URL: https://secrets.example.com
TELEMETRY_ENABLED: "false"
# SMTP (optional — for invitations and 2FA recovery)
SMTP_HOST: smtp.example.com
SMTP_PORT: 587
SMTP_USERNAME: [email protected]
SMTP_PASSWORD: change-this-mail-password
SMTP_FROM_ADDRESS: [email protected]
SMTP_FROM_NAME: Infisical
networks:
- infisical
depends_on:
infisical-db:
condition: service_healthy
infisical-redis:
condition: service_started
restart: unless-stopped
networks:
infisical:
volumes:
infisical-db:
infisical-redis:
Generate Required Keys
Before starting, generate the encryption and auth keys:
# Encryption key (32-character hex)
echo "ENCRYPTION_KEY: $(openssl rand -hex 16)"
# Auth secret (base64)
echo "AUTH_SECRET: $(openssl rand -base64 32)"
Replace the placeholder values in docker-compose.yml, then:
docker compose up -d
Access the web UI at http://your-server:8080 and create your admin account.
Core Concepts
| Concept | Description |
|---|---|
| Organization | Top-level group (your company or homelab) |
| Project | A set of related secrets (e.g., “Production Stack”, “Dev Environment”) |
| Environment | Dev, staging, production — each has its own secret values |
| Folder | Organize secrets within an environment |
| Secret | Key-value pair (e.g., DB_PASSWORD=hunter2) |
| Service token | Machine-readable token for automated secret fetching |
Setting Up Your First Project
- Create an organization (done during signup)
- Create a project — e.g., “Homelab Production”
- Add secrets — click + to add key-value pairs
- Create environments — default: Development, Staging, Production
- Invite team members — by email, with role-based access
Injecting Secrets into Applications
Using the Infisical CLI
# Install CLI
curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | bash
apt-get install infisical
# Login
infisical login
# Run a command with secrets injected as environment variables
infisical run --env=prod -- docker compose up -d
# Export secrets to .env file
infisical export --env=prod > .env
Using Service Tokens (for CI/CD and automation)
- In the Infisical dashboard, create a Service Token for your project
- Set the token as an environment variable:
INFISICAL_TOKEN - Use the CLI or API to fetch secrets:
export INFISICAL_TOKEN="st.xxxx..."
infisical export --env=prod --format=dotenv > .env
Using the REST API
curl -X GET "https://secrets.example.com/api/v3/secrets/raw?workspaceSlug=homelab&environment=prod" \
-H "Authorization: Bearer $INFISICAL_TOKEN"
Integration with Docker Compose
Infisical can inject secrets directly into Docker Compose workflows:
# Instead of maintaining .env files, run:
infisical run --env=prod -- docker compose up -d
This passes all secrets from the Infisical project as environment variables to Docker Compose. No .env file on disk.
Security Features
| Feature | Details |
|---|---|
| End-to-end encryption | Secrets encrypted client-side before reaching the server |
| Role-based access | Viewer, developer, admin roles per project |
| Audit logs | Full history of who accessed which secret and when |
| Secret versioning | Roll back to any previous value |
| IP allowlisting | Restrict API access by IP |
| 2FA | TOTP-based two-factor authentication |
| Secret rotation | Scheduled rotation for database credentials |
| Point-in-time recovery | Restore all secrets to a specific timestamp |
Reverse Proxy
Behind Nginx Proxy Manager:
Proxy Host: secrets.example.com → http://infisical:8080
Enable: WebSocket Support, Force SSL
HTTPS is strongly recommended — this service handles your most sensitive data.
Backup
| Volume | Contains | Priority |
|---|---|---|
infisical-db | All secrets (encrypted), projects, users | Critical |
infisical-redis | Session cache (regenerated) | Low |
Critical: Also back up your ENCRYPTION_KEY. Without it, database backups are useless — secrets cannot be decrypted.
# Database backup
docker exec infisical-db pg_dump -U infisical infisical > infisical-backup-$(date +%Y%m%d).sql
# Store ENCRYPTION_KEY separately from the database backup
See Backup Strategy.
Troubleshooting
”Invalid encryption key” on startup
Symptom: Infisical fails to start with encryption errors.
Fix: ENCRYPTION_KEY must be exactly 32 hex characters (16 bytes). Generate correctly: openssl rand -hex 16. Do NOT change this key after initial setup — existing secrets become unreadable.
Cannot invite team members
Symptom: Email invitations not sent.
Fix: SMTP must be configured correctly. Test with a simple email first. Check docker logs infisical for SMTP errors.
Service token returns 401
Symptom: API calls with a service token return unauthorized. Fix: Verify the token hasn’t expired (tokens have configurable TTLs). Ensure the token has access to the correct project and environment.
Resource Requirements
- RAM: ~300 MB idle (Infisical + PostgreSQL + Redis), ~500 MB under load
- CPU: Low — mostly I/O bound (database queries and encryption)
- Disk: ~200 MB for application, database grows slowly (secrets are small)
Verdict
Infisical is the best self-hosted secrets manager for teams and homelabs. It’s easier to set up and use than HashiCorp Vault, which is overkill for most self-hosting scenarios. The CLI integration with Docker Compose is the killer feature — inject secrets without ever writing them to disk. If you need a simpler, single-user solution, a Vaultwarden vault with secure notes also works. But for team access control, auditing, and environment-specific secrets, Infisical is the right tool.
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments