Security intermediate ⏱ 45 minutes

Infisical: Modern Secrets Management for Homelabs

Open-source HashiCorp Vault alternative. Manage secrets, environment variables, and API keys securely.

By homelabbing.io • 2025-12-16
#infisical#secrets#security#environment-variables#vault-alternative

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:

  1. User Registration: User creates password → Derives encryption key using Argon2
  2. Project Creation: Generates project-specific encryption key
  3. Secret Storage: Secrets encrypted with project key before database storage
  4. Secret Retrieval: Encrypted secrets retrieved from database → Decrypted client-side
  5. 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

FeatureInfisicalHashiCorp VaultDoppler
TypeSelf-hostedSelf-hostedCloud SaaS
ComplexityLowHighVery Low
RAM Usage200-300MB1-2GBN/A (cloud)
Setup Time15 minutes60+ minutes5 minutes
Web UI✅ Modern⚠️ Basic✅ Modern
CLI Quality✅ Excellent✅ Excellent✅ Excellent
Docker Integration✅ Native⚠️ Manual✅ Native
Self-Hosted✅ Yes✅ Yes❌ Cloud only
Best ForHomelabs, SMBEnterpriseTeams 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

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:

  1. Create proxy host: secrets.example.com
  2. Forward to: infisical:8080
  3. 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:

  1. Navigate to: https://secrets.example.com (or http://localhost:8080)
  2. Create admin account:
  3. Verify email (if SMTP configured) or click verification link in logs:
    docker-compose logs infisical | grep "verification"
  4. Login with admin credentials
  5. Complete onboarding wizard

Section 3: Creating Projects and Environments

Step 1: Create Your First Project

  1. Click “Create Project”
  2. Project Name: Homelab Infrastructure
  3. Description: Core homelab services and infrastructure
  4. 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:

  1. Navigate to: Project Settings → Environments
  2. Click “Add Environment”
  3. Create:
    • local - Personal laptop/workstation
    • docker-compose - Docker Compose deployments
    • kubernetes - K3s cluster
  4. Save

Step 4: Add Secrets

Via Web UI:

  1. Select environment (e.g., “Production”)
  2. Click “Add Secret”
  3. Enter:
    • Key: DATABASE_URL
    • Value: postgresql://user:pass@postgres:5432/db
    • Comment: Main PostgreSQL database
  4. Click “Save”

Bulk import via JSON:

  1. Click “Import Secrets”
  2. Select format: JSON or .env
  3. 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"
    }
  4. Click “Import”

Step 5: Organize Secrets with Folders

Create logical grouping:

  1. Click “New Folder”
  2. Folder name: database/
  3. Add secrets inside folder:
    • database/POSTGRES_HOST
    • database/POSTGRES_USER
    • database/POSTGRES_PASSWORD
  4. Repeat for categories:
    • api/ - API keys and tokens
    • email/ - SMTP credentials
    • oauth/ - OAuth client IDs/secrets
    • monitoring/ - Grafana, Prometheus tokens

Step 6: Secret Versioning

Infisical automatically tracks secret changes:

  1. Edit existing secret
  2. Change value
  3. Click “Save”
  4. View history: Click secret → “History” tab
  5. 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:

  1. CLI fetches secrets from Infisical
  2. Secrets injected as environment variables
  3. Command runs with full environment
  4. 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.

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:

  1. Add secret to Development environment
  2. Test application locally
  3. Copy secret structure to Staging (change values)
  4. Copy secret structure to Production (change values)
  5. 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:

  1. Navigate to: Project → Settings → Service Tokens
  2. Click “Create Token”
  3. Configure:
    • Name: docker-compose-prod
    • Environment: Production
    • Expiration: Never or 90 days
    • Permissions: Read or Read & Write
  4. Click “Create”
  5. 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:

  1. User Settings → Access Tokens
  2. Create Personal Access Token
  3. Set expiration (30, 60, 90 days, or never)
  4. 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:

  1. Project → Settings → Members
  2. Click “Invite Member”
  3. Enter email
  4. Select role: Admin, Developer, or Viewer
  5. Send invitation

Environment-specific permissions:

  1. Project → Settings → Access Control
  2. Create custom role:
    • Name: Production Read-Only
    • Permissions:
      • Production: Read
      • Staging: Read & Write
      • Development: Read & Write
  3. Assign to users

Audit Logging

Track all secret access and changes:

  1. Project → Audit Logs
  2. View events:
    • Secret created/updated/deleted
    • User access
    • Token usage
    • Permission changes
  3. Filter by:
    • User
    • Date range
    • Action type
    • Environment
  4. 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:

  1. Create service token in Infisical (Production, Read-only)
  2. Add to GitHub Secrets: INFISICAL_TOKEN
  3. Workflow fetches secrets at runtime
  4. 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:

  1. Generate new secret value
  2. Update in Infisical (old value still available in history)
  3. Deploy applications with new secret
  4. Verify functionality
  5. 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:

  1. Project → Settings → Webhooks
  2. Create Webhook:
    • URL: https://your-notification-endpoint.com/webhook
    • Events: secret.created, secret.updated, secret.deleted
    • Authentication: Bearer token
  3. 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

  1. Migrate Existing Secrets: Move hardcoded credentials to Infisical
  2. Integrate CI/CD: Add Infisical to deployment pipelines
  3. Implement Rotation: Set up automated credential rotation
  4. Team Onboarding: Invite team members with appropriate roles
  5. Monitoring: Set up alerts for secret access patterns

Best Practices

  1. Never commit secrets to Git - Use Infisical injection instead
  2. Rotate service tokens quarterly - Limit blast radius of compromise
  3. Use environment-specific tokens - Dev tokens shouldn’t access prod
  4. Enable audit logging - Track all secret access for compliance
  5. Backup encryption key - Store in multiple secure locations
  6. Principle of least privilege - Grant minimal required permissions
  7. Regular secret rotation - Especially for external APIs

Resources

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!