commit 7a3e1fed35bf734337c1bd821b0a948f26341a6b Author: vorpax Date: Tue Jan 20 14:48:15 2026 +0000 feat: add Dockerfile, docker-compose, and init script for step-ca with PostgreSQL support diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..81a32eb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM smallstep/step-ca +USER root +RUN apk update +RUN apk add --no-cache jq +COPY init.sh /scripts/init.sh + +USER step +ENTRYPOINT [ "/scripts/init.sh"] diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..d9ba320 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,84 @@ +name: step-ca +services: + postgres: + image: postgres:16-alpine + container_name: ca-postgres + restart: unless-stopped + environment: + POSTGRES_DB: stepca + POSTGRES_USER: stepca + POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password + volumes: + - postgres-data:/var/lib/postgresql/data + networks: + - ca-internal + secrets: + - postgres_password + healthcheck: + test: ["CMD-SHELL", "pg_isready -U stepca"] + interval: 10s + timeout: 5s + retries: 5 + + step-ca: + #image: smallstep/step-ca + container_name: ca + build: + context: . + dockerfile: Dockerfile + restart: unless-stopped + stdin_open: true + tty: true + depends_on: + postgres: + condition: service_healthy + ports: + - ${STEP_CA_IP:-127.0.0.1}:${STEP_CA_PORT:-9000}:9000 + dns: + - ${DNS_1:-8.8.8.8} + - ${DNS_2:-8.8.4.4} + dns_search: + - ${DNS_SEARCH_1:-localhost} + - ${DNS_SEARCH_2:-local} + - ${DNS_SEARCH_3:-internal} + entrypoint: ["/scripts/init.sh"] + environment: + - DOCKER_STEPCA_INIT_NAME=${STEP_CA_NAME:-Default CA} + - DOCKER_STEPCA_INIT_ISSUER=${STEP_CA_ISSUER:-CN=Default CA, O=Organization, C=US} + - DOCKER_STEPCA_INIT_DNS_NAMES=${STEP_CA_DNS_NAMES:-localhost,ca.local} + - DOCKER_STEPCA_INIT_PROVISIONER_NAME=${STEP_CA_PROVISIONER:-admin} + - DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT=${STEP_CA_REMOTE_MANAGEMENT:-true} + - DOCKER_STEPCA_INIT_ADMIN_SUBJECT=${STEP_CA_ADMIN_SUBJECT:-admin@example.com} + - DOCKER_STEPCA_INIT_SSH=${STEP_CA_SSH:-true} + - DOCKER_STEPCA_INIT_ACME=${STEP_CA_ACME:-true} + - POSTGRES_PASSWORD_FILE=/run/secrets/postgres_password + - DOCKER_STEPCA_INIT_PWD_FILE=/run/secrets/password + volumes: + - stepca-data:/home/step + - ./init.sh:/scripts/init.sh:ro + networks: + - ca-internal + secrets: + - postgres_password + - source: step_pwd + target: /run/secrets/password + alpine: + image: alpine:latest + volumes: + - stepca-data:/step + entrypoint: /bin/ash + +volumes: + stepca-data: + name: ca-stepca-data + postgres-data: + name: ca-postgres-data +secrets: + postgres_password: + file: ./secrets/postgres_password.txt + step_pwd: + file: ./secrets/step_pwd.txt + +networks: + ca-internal: + driver: bridge diff --git a/init.sh b/init.sh new file mode 100755 index 0000000..e48b4fe --- /dev/null +++ b/init.sh @@ -0,0 +1,50 @@ +#!/bin/sh +set -e + +CONFIG_FILE="/home/step/config/ca.json" +MARKER="/home/step/.postgres-configured" +POSTGRES_PASSWORD=$(cat /run/secrets/postgres_password) + + +# If already configured, start normally with PostgreSQL +if [ -f "$MARKER" ]; then + echo "✅ PostgreSQL already configured, starting step-ca..." + echo $(cat $CONFIG_FILE) + exec step-ca "$CONFIG_FILE" +fi + +# If ca.json does not exist yet, perform full initialization +if [ ! -f "$CONFIG_FILE" ]; then + echo "🔄 Running step ca init (with Badger temporarily)..." + + # Use Docker secrets directly (mounted at /run/secrets/password) + step ca init \ + --name="${DOCKER_STEPCA_INIT_NAME}" \ + --dns="${DOCKER_STEPCA_INIT_DNS_NAMES}" \ + --address=:9000 \ + --provisioner="${DOCKER_STEPCA_INIT_PROVISIONER_NAME}" \ + --password-file=/run/secrets/password \ + --provisioner-password-file=/run/secrets/password \ + --ssh \ + --acme \ + --remote-management\ + --admin-subject="${DOCKER_STEPCA_INIT_ADMIN_SUBJECT}" + + echo "✅ Init complete, certificates generated" + touch "$MARKER" +fi + +# Now modify ca.json to use PostgreSQL +echo "🔧 Replacing Badger with PostgreSQL in ca.json..." + +jq --arg datasource "postgresql://stepca:${POSTGRES_PASSWORD}@postgres:5432/stepca?sslmode=disable" \ + 'del(.db) | . + {db: {type: "postgresql", dataSource: $datasource}}' \ + "$CONFIG_FILE" > "${CONFIG_FILE}.tmp" + +mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE" + +# Mark as configured +touch "$MARKER" + +echo "✅ PostgreSQL configured, starting step-ca with PostgreSQL backend..." +exec step-ca "$CONFIG_FILE" --password-file=/run/secrets/password \ No newline at end of file