Infisical: Modern Secrets Management for Homelabs
Open-source HashiCorp Vault alternative. Manage secrets, environment variables, and API keys securely.
Introduction
Managing secrets—API keys, database passwords, certificates, tokens—is one of the most critical yet overlooked aspects of homelab security. Hardcoded credentials in Docker Compose files, plaintext .env files committed to Git, and passwords scattered across sticky notes create serious security vulnerabilities.
Infisical solves this problem by providing a modern, open-source secrets management platform designed for developers and DevOps workflows. Unlike heavyweight enterprise solutions like HashiCorp Vault, Infisical offers a user-friendly interface, seamless CLI integration, and native Docker support—making it perfect for homelabs and small teams.
In this comprehensive guide, you’ll learn how to deploy a self-hosted Infisical instance, organize secrets by environment, inject secrets into applications at runtime, integrate with Docker Compose, use the Infisical CLI for automation, and implement best practices for secret rotation and access control.
What You’ll Build:
- Self-hosted Infisical instance with PostgreSQL and Redis
- Project-based secret organization with environments (dev, staging, prod)
- Secret injection into Docker containers without plaintext exposure
- CLI integration for local development and CI/CD pipelines
- Service tokens for automated secret retrieval
- Secret versioning and audit logging
- Integration with Docker Compose and Kubernetes (optional)
Why Choose Infisical?
- Developer-Friendly: Beautiful web UI and intuitive workflows
- Zero-Trust Architecture: End-to-end encryption, secrets encrypted at rest
- CLI-First Design: Powerful CLI for automation and CI/CD
- Docker Native: First-class Docker and container support
- Lightweight: 200-300MB RAM (vs Vault’s 1-2GB)
- Self-Hosted: Complete control over your secrets infrastructure
- Active Development: Backed by YC, rapid feature development
Prerequisites
Before starting, ensure you have:
Technical Requirements:
- Server with 2 CPU cores, 2GB RAM, 10GB storage
- Docker 20.10.0+ and Docker Compose 1.27.0+
- Domain name (e.g.,
secrets.example.com) - DNS configured to point to your server
- (Optional) Reverse proxy for HTTPS termination
- (Optional) SMTP credentials for email notifications
Knowledge Requirements:
- Basic Docker and command line familiarity
- Understanding of environment variables
- YAML configuration experience
- Git workflow knowledge (helpful)
Preparation:
# Verify Docker installation
docker --version
docker-compose --version
# Create working directory
mkdir -p ~/infisical
cd ~/infisical Section 1: Understanding Infisical Architecture
Core Concepts
Projects: Top-level containers for organizing secrets. Each project typically represents an application or service (e.g., “Homelab Infrastructure”, “Media Stack”, “Monitoring”).
Environments: Separate namespaces within a project for different deployment stages (Development, Staging, Production). Secrets in one environment are isolated from others.
Secrets: Key-value pairs encrypted end-to-end. Each secret can have different values across environments.
Service Tokens: Machine-to-machine authentication credentials for automated secret retrieval (CLI, CI/CD, containers).
Personal Access Tokens: User-specific tokens for CLI authentication.
Secret References: Ability to reference secrets from other projects or environments, creating a hierarchy.
Architecture Components
Infisical Backend: Node.js API server handling authentication, authorization, secret encryption/decryption, and audit logging.
PostgreSQL Database: Stores encrypted secrets, user accounts, audit logs, and metadata. Secrets are encrypted with user/service-specific keys before storage.
Redis (Optional): Caches frequently accessed secrets and manages session state. Improves performance but not strictly required.
Infisical CLI: Go-based command-line tool for secret injection, retrieval, and management. Runs locally or in CI/CD pipelines.
Web UI: React-based dashboard for managing secrets, users, projects, and access controls.
Encryption Model
Infisical uses end-to-end encryption with zero-knowledge architecture:
- User Registration: User creates password → Derives encryption key using Argon2
- Project Creation: Generates project-specific encryption key
- Secret Storage: Secrets encrypted with project key before database storage
- Secret Retrieval: Encrypted secrets retrieved from database → Decrypted client-side
- Zero-Knowledge: Server never sees plaintext secrets or encryption keys
Security guarantees:
- Secrets encrypted at rest in database
- TLS encryption in transit
- Client-side encryption/decryption
- Database breach does NOT expose secrets
Infisical vs Alternatives
| Feature | Infisical | HashiCorp Vault | Doppler |
|---|---|---|---|
| Type | Self-hosted | Self-hosted | Cloud SaaS |
| Complexity | Low | High | Very Low |
| RAM Usage | 200-300MB | 1-2GB | N/A (cloud) |
| Setup Time | 15 minutes | 60+ minutes | 5 minutes |
| Web UI | ✅ Modern | ⚠️ Basic | ✅ Modern |
| CLI Quality | ✅ Excellent | ✅ Excellent | ✅ Excellent |
| Docker Integration | ✅ Native | ⚠️ Manual | ✅ Native |
| Self-Hosted | ✅ Yes | ✅ Yes | ❌ Cloud only |
| Best For | Homelabs, SMB | Enterprise | Teams OK with SaaS |
Choose Infisical if:
- Want self-hosted secrets management with minimal complexity
- Need developer-friendly UI and CLI
- Want native Docker/Kubernetes integration
- Prefer modern, actively developed tools
- Don’t need advanced Vault features (PKI, dynamic secrets)
Section 2: Installing Infisical
Step 1: Create Docker Compose Configuration
Create a production-ready Docker Compose stack:
# docker-compose.yml
version: '3.8'
services:
postgres:
image: postgres:16-alpine
container_name: infisical-postgres
environment:
POSTGRES_DB: infisical
POSTGRES_USER: infisical
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- infisical
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U infisical"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
container_name: infisical-redis
command: redis-server --appendonly yes
volumes:
- redis-data:/data
networks:
- infisical
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 5
infisical:
image: infisical/infisical:latest
container_name: infisical
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
environment:
# Database Configuration
DB_CONNECTION_URI: postgresql://infisical:${POSTGRES_PASSWORD}@postgres:5432/infisical
REDIS_URL: redis://redis:6379
# Application Configuration
ENCRYPTION_KEY: ${ENCRYPTION_KEY}
AUTH_SECRET: ${AUTH_SECRET}
SITE_URL: https://secrets.example.com
# SMTP Configuration (optional)
SMTP_HOST: smtp.resend.com
SMTP_PORT: 587
SMTP_USERNAME: resend
SMTP_PASSWORD: ${SMTP_PASSWORD}
SMTP_FROM_ADDRESS: [email protected]
SMTP_FROM_NAME: Infisical
# Optional: Telemetry
TELEMETRY_ENABLED: false
ports:
- "8080:8080"
networks:
- infisical
- proxy # For reverse proxy integration
restart: unless-stopped
networks:
infisical:
driver: bridge
proxy:
external: true # Shared with reverse proxy
volumes:
postgres-data:
redis-data: Step 2: Generate Secrets
Create secure cryptographic secrets:
# Generate encryption key (32 bytes hex)
export ENCRYPTION_KEY=$(openssl rand -hex 32)
# Generate auth secret (32 bytes hex)
export AUTH_SECRET=$(openssl rand -hex 32)
# Generate PostgreSQL password
export POSTGRES_PASSWORD=$(openssl rand -base64 24)
# Generate SMTP password (if using email)
export SMTP_PASSWORD="your-resend-api-key" # From Resend dashboard
# Create .env file
cat > .env << EOF
ENCRYPTION_KEY=${ENCRYPTION_KEY}
AUTH_SECRET=${AUTH_SECRET}
POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
SMTP_PASSWORD=${SMTP_PASSWORD}
EOF
# Secure permissions
chmod 600 .env
# Display secrets (SAVE THESE SECURELY!)
echo "=== SAVE THESE SECRETS ==="
cat .env
echo "==========================" CRITICAL: Backup these secrets
- Store in password manager
- Loss of ENCRYPTION_KEY means loss of ALL secrets
- Create encrypted backup:
gpg -c .env
Step 3: Configure Reverse Proxy (Optional but Recommended)
For Traefik:
# Update infisical service in docker-compose.yml
services:
infisical:
labels:
- "traefik.enable=true"
- "traefik.http.routers.infisical.rule=Host(`secrets.example.com`)"
- "traefik.http.routers.infisical.entrypoints=websecure"
- "traefik.http.routers.infisical.tls=true"
- "traefik.http.routers.infisical.tls.certresolver=letsencrypt"
- "traefik.http.services.infisical.loadbalancer.server.port=8080" For Nginx Proxy Manager:
- Create proxy host:
secrets.example.com - Forward to:
infisical:8080 - Enable SSL with Let’s Encrypt
Step 4: Start Infisical
Launch all services:
# Pull latest images
docker-compose pull
# Start services
docker-compose up -d
# Monitor startup logs
docker-compose logs -f infisical
# Wait for: "Server is running on port 8080" Verify services:
# Check container status
docker-compose ps
# Expected output:
# NAME STATUS
# infisical Up (healthy)
# infisical-postgres Up (healthy)
# infisical-redis Up (healthy)
# Test health endpoint
curl http://localhost:8080/api/status
# Expected: {"status":"ok"} Step 5: Initial Setup
Access Infisical web UI:
- Navigate to:
https://secrets.example.com(orhttp://localhost:8080) - Create admin account:
- Email:
[email protected] - Password: Strong password (min 12 chars)
- First/Last name
- Email:
- Verify email (if SMTP configured) or click verification link in logs:
docker-compose logs infisical | grep "verification" - Login with admin credentials
- Complete onboarding wizard
Section 3: Creating Projects and Environments
Step 1: Create Your First Project
- Click “Create Project”
- Project Name:
Homelab Infrastructure - Description:
Core homelab services and infrastructure - Click “Create”
Step 2: Understand Default Environments
Infisical creates three default environments:
- Development (dev): Local development secrets
- Staging (staging): Pre-production testing
- Production (prod): Live production secrets
Step 3: Add Custom Environments (Optional)
For homelabs, you might want additional environments:
- Navigate to: Project Settings → Environments
- Click “Add Environment”
- Create:
local- Personal laptop/workstationdocker-compose- Docker Compose deploymentskubernetes- K3s cluster
- Save
Step 4: Add Secrets
Via Web UI:
- Select environment (e.g., “Production”)
- Click “Add Secret”
- Enter:
- Key:
DATABASE_URL - Value:
postgresql://user:pass@postgres:5432/db - Comment:
Main PostgreSQL database
- Key:
- Click “Save”
Bulk import via JSON:
- Click “Import Secrets”
- Select format: JSON or .env
- Paste secrets:
{ "DATABASE_URL": "postgresql://user:pass@postgres:5432/db", "REDIS_URL": "redis://redis:6379", "API_KEY": "sk_live_abc123xyz789", "JWT_SECRET": "your-jwt-secret-here" } - Click “Import”
Step 5: Organize Secrets with Folders
Create logical grouping:
- Click “New Folder”
- Folder name:
database/ - Add secrets inside folder:
database/POSTGRES_HOSTdatabase/POSTGRES_USERdatabase/POSTGRES_PASSWORD
- Repeat for categories:
api/- API keys and tokensemail/- SMTP credentialsoauth/- OAuth client IDs/secretsmonitoring/- Grafana, Prometheus tokens
Step 6: Secret Versioning
Infisical automatically tracks secret changes:
- Edit existing secret
- Change value
- Click “Save”
- View history: Click secret → “History” tab
- Rollback: Select previous version → “Restore”
Use cases:
- Rollback after breaking change
- Audit when secrets changed
- Compliance requirements
Section 4: Secret Injection with Infisical CLI
The Infisical CLI enables secret injection without storing plaintext credentials.
Step 1: Install Infisical CLI
Linux:
# Download and install
curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | sudo -E bash
sudo apt-get update && sudo apt-get install -y infisical
# Verify installation
infisical --version macOS:
# Using Homebrew
brew install infisical/get-cli/infisical
# Verify
infisical --version Windows (WSL or PowerShell):
# Using Scoop
scoop bucket add infisical https://github.com/Infisical/scoop-infisical.git
scoop install infisical
# Verify
infisical --version Docker (alternative):
# Create alias
alias infisical='docker run --rm -v $(pwd):/app infisical/cli:latest'
# Verify
infisical --version Step 2: Authenticate CLI
Method 1: Login (interactive)
# Login with email/password
infisical login
# Opens browser for authentication
# Or manually enter email/password in terminal Method 2: Service Token (automation)
# Create service token in Web UI:
# Project → Settings → Service Tokens → Create
# Copy token value
# Set as environment variable
export INFISICAL_TOKEN="st.abc123.xyz789.full-token-here"
# Verify authentication
infisical secrets list --env prod Step 3: Basic Secret Operations
List secrets:
# List all secrets in production environment
infisical secrets list --env prod
# List secrets in specific folder
infisical secrets list --env prod --path /database Get specific secret:
# Retrieve single secret value
infisical secrets get DATABASE_URL --env prod
# Get secret in different format
infisical secrets get DATABASE_URL --env prod --format json Set secret:
# Create or update secret
infisical secrets set API_KEY="sk_live_new_value" --env prod
# Set multiple secrets
infisical secrets set DATABASE_HOST=postgres DATABASE_PORT=5432 --env prod Delete secret:
# Remove secret
infisical secrets delete API_KEY --env prod
# Confirm deletion Step 4: Secret Injection into Commands
Run commands with secrets injected as environment variables:
# Inject secrets and run application
infisical run --env prod -- npm start
# Run Python script with secrets
infisical run --env prod -- python app.py
# Run Docker Compose with injected secrets
infisical run --env prod -- docker-compose up -d
# Run one-off command
infisical run --env prod -- curl -H "Authorization: Bearer $API_KEY" https://api.example.com How it works:
- CLI fetches secrets from Infisical
- Secrets injected as environment variables
- Command runs with full environment
- Secrets never written to disk
Step 5: Export Secrets to File
For legacy applications requiring .env files:
# Export to .env format
infisical secrets export --env prod --format dotenv > .env
# Export to JSON
infisical secrets export --env prod --format json > secrets.json
# Export specific folder
infisical secrets export --env prod --path /database --format dotenv > database.env Security warning:
- Exported files contain plaintext secrets
- Use only when absolutely necessary
- Add to .gitignore immediately
- Delete after use
Section 5: Docker Integration
Integrate Infisical with Docker Compose for secret injection without plaintext exposure.
Method 1: CLI Wrapper (Recommended)
Use Infisical CLI to inject secrets when starting containers:
# docker-compose.yml (no hardcoded secrets!)
version: '3.8'
services:
app:
image: myapp:latest
environment:
# Reference environment variables (populated by Infisical)
- DATABASE_URL=${DATABASE_URL}
- API_KEY=${API_KEY}
- REDIS_URL=${REDIS_URL}
ports:
- "3000:3000" Start with secret injection:
# Inject secrets and start containers
infisical run --env prod -- docker-compose up -d
# View logs
docker-compose logs -f app
# App receives DATABASE_URL, API_KEY, etc. as environment variables Method 2: Infisical Agent Sidecar
Run Infisical agent as sidecar container for automatic secret sync:
version: '3.8'
services:
infisical-agent:
image: infisical/cli:latest
command: >
agent --token ${INFISICAL_TOKEN}
--env prod
--interval 60s
--output /secrets/.env
environment:
- INFISICAL_TOKEN=${INFISICAL_TOKEN}
volumes:
- secrets:/secrets
restart: unless-stopped
app:
image: myapp:latest
depends_on:
- infisical-agent
env_file:
- /secrets/.env # Mounted from shared volume
volumes:
- secrets:/secrets:ro
ports:
- "3000:3000"
volumes:
secrets: Benefits:
- Automatic secret refresh every 60 seconds
- Secrets updated without container restart
- Centralized secret management
Method 3: Init Container Pattern (Kubernetes-style)
Fetch secrets once at container startup:
version: '3.8'
services:
app:
image: myapp:latest
entrypoint: /entrypoint.sh
environment:
- INFISICAL_TOKEN=${INFISICAL_TOKEN}
volumes:
- ./entrypoint.sh:/entrypoint.sh
ports:
- "3000:3000" entrypoint.sh:
#!/bin/bash
set -e
# Fetch secrets from Infisical
infisical secrets export --env prod --format dotenv > /tmp/.env
# Source secrets
set -a
source /tmp/.env
set +a
# Remove temporary file
rm /tmp/.env
# Start application
exec node index.js Method 4: Docker Secrets (Swarm)
For Docker Swarm deployments:
# docker-compose.yml
version: '3.8'
services:
app:
image: myapp:latest
secrets:
- database_url
- api_key
environment:
- DATABASE_URL_FILE=/run/secrets/database_url
- API_KEY_FILE=/run/secrets/api_key
secrets:
database_url:
external: true
api_key:
external: true Create Docker secrets from Infisical:
# Fetch secret value and create Docker secret
infisical secrets get DATABASE_URL --env prod --plain | docker secret create database_url -
infisical secrets get API_KEY --env prod --plain | docker secret create api_key - Section 6: Environment Management Patterns
Pattern 1: Environment Parity
Keep secrets in sync across environments with different values:
Development:
DATABASE_URL=postgresql://localhost:5432/dev
API_KEY=sk_test_abc123
DEBUG=true
Production:
DATABASE_URL=postgresql://prod-db:5432/prod
API_KEY=sk_live_xyz789
DEBUG=false Workflow:
- Add secret to Development environment
- Test application locally
- Copy secret structure to Staging (change values)
- Copy secret structure to Production (change values)
- Maintain consistent key names across environments
Pattern 2: Secret References
Reference secrets from other projects/environments:
# In Web UI: Create secret reference
Key: SHARED_DATABASE_URL
Type: Reference
Source: Project "Shared Infrastructure" → Environment "prod" → Secret "DATABASE_URL" Use cases:
- Shared databases across multiple projects
- Centralized API credentials
- Reusable configuration values
Pattern 3: Secret Overrides
Override default values for specific use cases:
# Default production secrets
infisical run --env prod -- ./app
# Override for maintenance mode
MAINTENANCE_MODE=true infisical run --env prod -- ./app
# Override database for migration
DATABASE_URL=postgresql://migration-db:5432/temp infisical run --env prod -- ./migrate.sh Pattern 4: Multi-Project Secrets
Organize secrets across multiple projects:
Project: "Core Infrastructure"
- DATABASE_URL
- REDIS_URL
- SMTP credentials
Project: "Media Stack"
- JELLYFIN_API_KEY
- PLEX_TOKEN
- SONARR_API_KEY
Project: "Monitoring"
- GRAFANA_API_KEY
- PROMETHEUS_TOKEN
- ALERTMANAGER_URL Benefits:
- Clear separation of concerns
- Granular access control per project
- Easier auditing and compliance
Section 7: Service Tokens and Access Control
Creating Service Tokens
Service tokens enable machine-to-machine authentication.
Create token via Web UI:
- Navigate to: Project → Settings → Service Tokens
- Click “Create Token”
- Configure:
- Name:
docker-compose-prod - Environment:
Production - Expiration:
Neveror90 days - Permissions:
ReadorRead & Write
- Name:
- Click “Create”
- Copy token (shown only once!)
Token format:
st.abc123def456.xyz789.full-token-very-long-string Use in automation:
# Set as environment variable
export INFISICAL_TOKEN="st.abc123def456.xyz789..."
# CLI commands now authenticated
infisical secrets list --env prod
# Docker Compose with token
INFISICAL_TOKEN=st.abc123... infisical run --env prod -- docker-compose up -d Personal Access Tokens
For user-specific CLI authentication:
- User Settings → Access Tokens
- Create Personal Access Token
- Set expiration (30, 60, 90 days, or never)
- Copy token
Use with CLI:
# Login with personal access token
infisical login --token your-personal-access-token
# Or set environment variable
export INFISICAL_TOKEN="your-personal-access-token" Role-Based Access Control
Default roles:
- Admin: Full project access, manage users, delete project
- Developer: Read/write secrets, cannot manage users
- Viewer: Read-only access to secrets
Invite team members:
- Project → Settings → Members
- Click “Invite Member”
- Enter email
- Select role: Admin, Developer, or Viewer
- Send invitation
Environment-specific permissions:
- Project → Settings → Access Control
- Create custom role:
- Name:
Production Read-Only - Permissions:
- Production: Read
- Staging: Read & Write
- Development: Read & Write
- Name:
- Assign to users
Audit Logging
Track all secret access and changes:
- Project → Audit Logs
- View events:
- Secret created/updated/deleted
- User access
- Token usage
- Permission changes
- Filter by:
- User
- Date range
- Action type
- Environment
- Export logs (JSON or CSV)
Use cases:
- Compliance reporting
- Security incident investigation
- Usage analytics
- Access pattern analysis
Section 8: CI/CD Integration
GitHub Actions
Use Infisical in GitHub Actions workflows:
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Infisical CLI
run: |
curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | sudo -E bash
sudo apt-get update && sudo apt-get install -y infisical
- name: Deploy with secrets
env:
INFISICAL_TOKEN: ${{ secrets.INFISICAL_TOKEN }}
run: |
# Fetch secrets and deploy
infisical run --env prod -- ./deploy.sh
- name: Run database migrations
env:
INFISICAL_TOKEN: ${{ secrets.INFISICAL_TOKEN }}
run: |
infisical run --env prod -- npm run migrate Setup:
- Create service token in Infisical (Production, Read-only)
- Add to GitHub Secrets:
INFISICAL_TOKEN - Workflow fetches secrets at runtime
- No secrets stored in repository
GitLab CI
# .gitlab-ci.yml
deploy:
stage: deploy
image: ubuntu:22.04
before_script:
- curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | bash
- apt-get update && apt-get install -y infisical
script:
- infisical run --env prod -- ./deploy.sh
variables:
INFISICAL_TOKEN: $INFISICAL_TOKEN # Set in GitLab CI/CD variables
only:
- main Jenkins
// Jenkinsfile
pipeline {
agent any
environment {
INFISICAL_TOKEN = credentials('infisical-token')
}
stages {
stage('Install Infisical CLI') {
steps {
sh '''
curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | sudo -E bash
sudo apt-get update && sudo apt-get install -y infisical
'''
}
}
stage('Deploy') {
steps {
sh 'infisical run --env prod -- ./deploy.sh'
}
}
}
} Section 9: Advanced Features
Secret Rotation
Automate credential rotation:
Manual rotation workflow:
- Generate new secret value
- Update in Infisical (old value still available in history)
- Deploy applications with new secret
- Verify functionality
- Archive old secret
Automated rotation script:
#!/bin/bash
# rotate-database-password.sh
# Generate new password
NEW_PASSWORD=$(openssl rand -base64 32)
# Update in Infisical
infisical secrets set DATABASE_PASSWORD="$NEW_PASSWORD" --env prod
# Update actual database
docker exec postgres psql -U postgres -c "ALTER USER appuser PASSWORD '$NEW_PASSWORD';"
# Restart application to pick up new secret
infisical run --env prod -- docker-compose restart app
echo "Database password rotated successfully" Schedule with cron:
# Rotate every 90 days
0 0 1 */3 * /opt/scripts/rotate-database-password.sh Secret Leakage Prevention
Pre-commit hook to prevent secret commits:
#!/bin/bash
# .git/hooks/pre-commit
# Check for potential secrets in staged files
if git diff --cached | grep -E '(password|secret|api_key|token).*='; then
echo "ERROR: Potential secret detected in commit!"
echo "Use Infisical instead of hardcoding secrets."
exit 1
fi
# Check for .env files
if git diff --cached --name-only | grep -E '.env$'; then
echo "ERROR: .env file detected in commit!"
echo "Add .env to .gitignore"
exit 1
fi
exit 0 Make executable:
chmod +x .git/hooks/pre-commit Webhook Notifications
Get notified when secrets change:
- Project → Settings → Webhooks
- Create Webhook:
- URL:
https://your-notification-endpoint.com/webhook - Events:
secret.created,secret.updated,secret.deleted - Authentication: Bearer token
- URL:
- Save
Webhook payload example:
{
"event": "secret.updated",
"project": "homelab-infrastructure",
"environment": "production",
"secret": {
"key": "DATABASE_PASSWORD",
"updatedBy": "[email protected]",
"timestamp": "2025-12-16T10:30:00Z"
}
} Kubernetes Integration
Deploy secrets to Kubernetes clusters:
# Install Infisical Kubernetes Operator
kubectl apply -f https://raw.githubusercontent.com/Infisical/infisical/main/k8s-operator/install.yaml
# Create Infisical secret (contains service token)
kubectl create secret generic infisical-token --from-literal=token=st.abc123...
# Create InfisicalSecret CRD
cat <<EOF | kubectl apply -f -
apiVersion: secrets.infisical.com/v1alpha1
kind: InfisicalSecret
metadata:
name: app-secrets
spec:
tokenSecretRef:
name: infisical-token
projectId: abc123
environment: production
managedSecretReference:
secretName: app-secret
secretNamespace: default
EOF
# Secrets automatically synced to Kubernetes Secret "app-secret" Use in pod:
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: app
image: myapp:latest
envFrom:
- secretRef:
name: app-secret # Auto-populated by Infisical Section 10: Backup and Disaster Recovery
Backup Strategies
1. Database Backup (Recommended)
# Create PostgreSQL backup
docker exec infisical-postgres pg_dump -U infisical infisical > infisical-backup-$(date +%Y%m%d).sql
# Encrypt backup
gpg --symmetric --cipher-algo AES256 infisical-backup-$(date +%Y%m%d).sql
# Upload to secure storage
rclone copy infisical-backup-$(date +%Y%m%d).sql.gpg remote:backups/infisical/ 2. Export All Secrets (Per-Project)
# Export all secrets from project
infisical secrets export --env prod --format json > secrets-prod-$(date +%Y%m%d).json
# Encrypt
gpg -c secrets-prod-$(date +%Y%m%d).json
# Store securely 3. Configuration Backup
# Backup .env and docker-compose.yml
tar -czf infisical-config-$(date +%Y%m%d).tar.gz .env docker-compose.yml
# Encrypt
gpg -c infisical-config-$(date +%Y%m%d).tar.gz Automated Backup Script
#!/bin/bash
# /opt/scripts/backup-infisical.sh
set -e
BACKUP_DIR="/backup/infisical"
DATE=$(date +%Y%m%d-%H%M%S)
# Create backup directory
mkdir -p "$BACKUP_DIR"
# Backup database
docker exec infisical-postgres pg_dump -U infisical infisical | gzip > "$BACKUP_DIR/db-$DATE.sql.gz"
# Backup configuration
cd /root/infisical
tar -czf "$BACKUP_DIR/config-$DATE.tar.gz" .env docker-compose.yml
# Encrypt backups
gpg --batch --yes --passphrase-file /root/.backup-passphrase --symmetric --cipher-algo AES256 "$BACKUP_DIR/db-$DATE.sql.gz"
gpg --batch --yes --passphrase-file /root/.backup-passphrase --symmetric --cipher-algo AES256 "$BACKUP_DIR/config-$DATE.tar.gz"
# Remove unencrypted files
rm "$BACKUP_DIR/db-$DATE.sql.gz"
rm "$BACKUP_DIR/config-$DATE.tar.gz"
# Upload to remote storage
rclone copy "$BACKUP_DIR" remote:backups/infisical/
# Clean up old backups (keep 30 days)
find "$BACKUP_DIR" -name "*.gpg" -mtime +30 -delete
echo "Backup completed successfully: $DATE" Schedule with cron:
# Daily backup at 2 AM
0 2 * * * /opt/scripts/backup-infisical.sh >> /var/log/infisical-backup.log 2>&1 Disaster Recovery Procedure
Scenario: Complete infrastructure loss
# 1. Deploy fresh Infisical instance
docker-compose up -d
# 2. Stop Infisical (keep database running)
docker stop infisical
# 3. Restore database backup
gunzip < infisical-backup-20251216.sql.gz | docker exec -i infisical-postgres psql -U infisical infisical
# 4. Restore .env file (with original ENCRYPTION_KEY!)
gpg -d infisical-config-20251216.tar.gz.gpg | tar -xz
# 5. Restart with restored configuration
docker-compose up -d
# 6. Verify secrets accessible
infisical login
infisical secrets list --env prod CRITICAL: The ENCRYPTION_KEY from the original .env must be used. Without it, encrypted secrets cannot be decrypted.
Section 11: Troubleshooting
Issue 1: Cannot Decrypt Secrets
Symptoms: Error “Failed to decrypt secret”
Causes:
- Wrong ENCRYPTION_KEY in .env
- Database corruption
- Key mismatch after restore
Solutions:
# Verify ENCRYPTION_KEY matches original
cat .env | grep ENCRYPTION_KEY
# Check database connectivity
docker exec infisical-postgres psql -U infisical -c "SELECT version();"
# Restore from backup with correct key Issue 2: Service Token Not Working
Symptoms: CLI returns “Invalid token” or “Unauthorized”
Solutions:
# Verify token format (should start with "st.")
echo $INFISICAL_TOKEN | cut -c1-3 # Should output: st.
# Check token hasn't expired (Web UI → Service Tokens)
# Regenerate token and update environment variable Issue 3: High Memory Usage
Symptoms: Container consuming excessive RAM
Solutions:
# Add resource limits to docker-compose.yml
services:
infisical:
deploy:
resources:
limits:
memory: 512M
reservations:
memory: 256M # Restart with limits
docker-compose up -d Issue 4: Slow Secret Retrieval
Symptoms: CLI commands take 5+ seconds
Solutions:
# Ensure Redis is running
docker-compose ps redis
# Check Redis connectivity
docker exec infisical-redis redis-cli ping # Should return: PONG
# Restart Infisical to clear cache
docker-compose restart infisical Conclusion
Congratulations! You’ve deployed a production-ready Infisical secrets management platform. You now have:
- ✅ Self-hosted secrets infrastructure with end-to-end encryption
- ✅ Project and environment-based secret organization
- ✅ Infisical CLI for development and automation
- ✅ Docker integration with secret injection
- ✅ Service tokens for CI/CD pipelines
- ✅ Audit logging and access control
- ✅ Backup and disaster recovery procedures
Next Steps
- Migrate Existing Secrets: Move hardcoded credentials to Infisical
- Integrate CI/CD: Add Infisical to deployment pipelines
- Implement Rotation: Set up automated credential rotation
- Team Onboarding: Invite team members with appropriate roles
- Monitoring: Set up alerts for secret access patterns
Best Practices
- Never commit secrets to Git - Use Infisical injection instead
- Rotate service tokens quarterly - Limit blast radius of compromise
- Use environment-specific tokens - Dev tokens shouldn’t access prod
- Enable audit logging - Track all secret access for compliance
- Backup encryption key - Store in multiple secure locations
- Principle of least privilege - Grant minimal required permissions
- Regular secret rotation - Especially for external APIs
Resources
- Official Documentation: https://infisical.com/docs
- CLI Reference: https://infisical.com/docs/cli/overview
- GitHub Repository: https://github.com/Infisical/infisical
- Community Discord: https://infisical.com/discord
Final Thoughts
Infisical transforms secrets management from a liability into a streamlined, secure process. By centralizing secrets, enforcing access control, and eliminating plaintext exposure, you’ve significantly improved your homelab’s security posture.
The CLI-first approach enables powerful automation patterns while maintaining zero-trust principles. Whether managing a personal homelab or a small business infrastructure, Infisical provides enterprise-grade secrets management without enterprise-level complexity.
Your secrets are now secure, versioned, and centrally managed. Happy homelabbing!
Guide Version: 1.0 Last Updated: December 2025 Infisical Version: 0.76+ Tested On: Ubuntu 22.04, Docker 24.0+
Author Note: This guide is maintained as part of the homelabbing.io project. Found an issue or have improvements? Contribute on GitHub!