Files
step-ca_postgres/README.md

8.1 KiB

Step-CA Docker Stack

A Docker Compose setup for deploying Smallstep CA (step-ca) with PostgreSQL backend support for certificate management and PKI infrastructure.

Features

  • Automated Initialization: Automatic step-ca setup with optional SSH and ACME support
  • PostgreSQL Backend: Uses PostgreSQL as the primary database (replacing the default Badger)
  • Health Checks: Built-in health checks for PostgreSQL service
  • Customizable Configuration: Full environment variable support for customization
  • Docker Build: Custom Dockerfile with jq for JSON manipulation
  • Remote Management: Support for remote management capabilities
  • Admin Provisioner: Built-in JWK admin provisioner for certificate issuance

Prerequisites

  • Docker
  • Docker Compose
  • Basic knowledge of step-ca and PKI concepts

Quick Start

1. Clone and Setup

cd /path/to/step-ca
cp .env.example .env
# Edit .env with your specific configuration

2. Configure Environment

Edit .env file with your desired configuration:

# PostgreSQL Configuration
POSTGRES_PASSWORD=your_secure_password

# Step-CA Configuration
STEP_CA_IP=192.168.1.100
STEP_CA_PORT=9000
STEP_CA_NAME=My Internal CA
STEP_CA_ISSUER=CN=My Internal CA, O=MyOrg, C=US
STEP_CA_DNS_NAMES=ca.example.com,ca.internal,pki.local
STEP_CA_PROVISIONER=admin-provisioner
STEP_CA_ADMIN_SUBJECT=admin@example.com
STEP_CA_SSH=true
STEP_CA_ACME=true
STEP_CA_REMOTE_MANAGEMENT=true

# DNS Configuration
DNS_1=8.8.8.8
DNS_2=8.8.4.4
DNS_SEARCH_1=example.com
DNS_SEARCH_2=internal.local

3. Initialize Secrets

Create the required secret files. These are mounted as Docker secrets at /run/secrets/ inside containers:

mkdir -p secrets

echo "your_secure_password" > secrets/postgres_password.txt

echo "your_ca_password" > secrets/step_pwd.txt

chmod 600 secrets/*.txt

Important: These secrets are automatically mounted by Docker Compose:

  • secrets/postgres_password.txt/run/secrets/postgres_password
  • secrets/step_pwd.txt/run/secrets/password

or just make configure

4. Start the Stack

docker-compose up -d --build

5. Verify Deployment

docker-compose logs -f step-ca

docker-compose ps

Configuration

Environment Variables

All configuration is managed through the .env file. Key variables:

Variable Description Default Example
POSTGRES_PASSWORD PostgreSQL password - secure_pass_123
STEP_CA_IP IP address for CA service 127.0.0.1 192.168.1.100
STEP_CA_PORT Port for CA service 9000 9000
STEP_CA_NAME CA name Default CA Company Internal CA
STEP_CA_ISSUER CA issuer certificate DN - CN=My CA, O=Org, C=US
STEP_CA_DNS_NAMES DNS names for CA cert localhost,ca.local ca.example.com,ca.internal
STEP_CA_PROVISIONER Provisioner name admin admin-provisioner
STEP_CA_ADMIN_SUBJECT Admin email address admin@example.com ca-admin@company.com
STEP_CA_SSH Enable SSH support true true or false
STEP_CA_ACME Enable ACME support true true or false
STEP_CA_REMOTE_MANAGEMENT Enable remote management true true or false
DNS_1, DNS_2 DNS servers 8.8.8.8, 8.8.4.4 1.1.1.1, 1.0.0.1
DNS_SEARCH_1-3 DNS search domains localhost,local,internal example.com,internal.local

Service Details

PostgreSQL Service

  • Image: postgres:16-alpine
  • Database: stepca
  • User: stepca
  • Health Check: PostgreSQL readiness probe every 10 seconds
  • Persistent Storage: postgres-data volume

Step-CA Service

  • Build: Custom image based on smallstep/step-ca
  • Port: Configurable via STEP_CA_PORT (default: 9000)
  • Database Migration: Automatic transition from Badger to PostgreSQL
  • Persistent Storage: stepca-data volume for certificates and configuration

Initialization Flow

  1. First Run: If ca.json doesn't exist:

    • Step-ca performs automated initialization with Badger database
    • Uses Docker secret from /run/secrets/password for key encryption
    • Generates root, intermediate, and SSH certificates
    • Creates admin provisioner
  2. PostgreSQL Migration:

    • Configuration is migrated from Badger to PostgreSQL
    • Database connection details are stored in ca.json
    • Marker file created to prevent re-initialization
  3. Subsequent Runs:

    • Step-ca starts directly with PostgreSQL backend
    • Uses the same Docker secret for decrypting keys
    • No re-initialization occurs (marker file prevents this)

File Structure

step-ca/
├── compose.yaml           # Docker Compose configuration
├── Dockerfile             # Custom Docker image build
├── init.sh               # Initialization script
├── .env.example          # Environment variables template
├── .gitignore            # Git ignore rules
├── config/
│   └── ca.json          # Step-ca configuration (generated)
├── secrets/
│   ├── postgres_password.txt
│   └── step_pwd.txt
└── README.md            # This file

Usage Examples

Access Step-CA Admin Interface

Once the container is running, you can interact with step-ca:

# Enter the container
docker-compose exec step-ca sh

# List certificates
step certificate list

# Get CA fingerprint
step certificate fingerprint /home/step/certs/root_ca.crt

Request a Certificate via JWK Provisioner

# From inside the container, using the mounted Docker secret
docker-compose exec step-ca sh -c \
  'step ca certificate --provisioner=admin --provisioner-password-file=/run/secrets/password \
  "my-service.example.com" /tmp/cert.pem /tmp/key.pem'

# Or from the host with your CA password
step ca certificate --provisioner=admin \
  "my-service.example.com" cert.pem key.pem

ACME Client Setup

If ACME is enabled, configure your ACME client:

CA URL: https://ca.example.com:9000
Directory: https://ca.example.com:9000/acme/acme/directory

Troubleshooting

PostgreSQL Connection Fails

# Check PostgreSQL logs
docker-compose logs postgres

# Verify database exists
docker-compose exec postgres psql -U stepca -d stepca -c "\dt"

Step-CA Won't Start

# Check step-ca logs
docker-compose logs step-ca

# Verify configuration
docker-compose exec step-ca cat /home/step/config/ca.json

Remove and Reset

To completely reset the environment:

# Stop and remove containers
docker-compose down

# Remove data volumes
docker volume rm ca-stepca-data ca-postgres-data

# Restart fresh
docker-compose up -d --build

Security Considerations

  • Secret Management: Store passwords in secrets/ directory and add to .gitignore
  • Network: Use internal Docker network for PostgreSQL communication
  • Firewall: Restrict access to port 9000 from trusted networks only
  • TLS: Ensure step-ca certificates are properly validated by clients
  • Backups: Regularly backup the stepca-data and postgres-data volumes

Ports and Networks

  • Step-CA Port: 9000 (configurable)
  • PostgreSQL Port: 5432 (internal only)
  • Network: ca-internal (internal Docker bridge)

Debugging

Enable verbose logging by modifying the init script:

# Add to init.sh
set -x  # Enable debug output

View real-time logs:

docker-compose logs -f step-ca
docker-compose logs -f postgres

Support

For issues with step-ca, refer to:

License

This Docker Compose stack follows the licensing of Smallstep and individual components.