Files
plex-playlist/docs/SECURE_DOCKER_CICD.md
2026-06-19 10:33:42 -04:00

3.1 KiB

Secure Docker CI/CD with BuildKit Secrets

This document explains how our CI/CD pipeline securely handles SSH keys using Docker BuildKit secrets.

🔒 Security Benefits

Before (Insecure)

ARG SSH_PRIVATE_KEY
RUN echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
  • SSH key stored in Docker image layers
  • Visible in docker history
  • Can be extracted from images
  • Security vulnerability

After (Secure)

RUN --mount=type=secret,id=ssh_private_key \
    cp /run/secrets/ssh_private_key ~/.ssh/id_rsa && \
    # ... use key ... && \
    rm -rf ~/.ssh
  • SSH key never stored in image layers
  • Not visible in docker history
  • Cannot be extracted from final image
  • Secure by design

🏗️ CI/CD Pipeline Implementation

Gitea Actions Workflow

The CI workflow files under .gitea/workflows/ now use:

  1. Docker BuildKit Enabled

    export DOCKER_BUILDKIT=1
    
  2. Secure Secret Mounting

    # Create temporary SSH key file
    echo "${SSH_PRIVATE_KEY}" > /tmp/ssh_key
    chmod 600 /tmp/ssh_key
    
    # Build with secret mount
    docker build -f Dockerfile.cicd \
      --secret id=ssh_private_key,src=/tmp/ssh_key \
      -t cicd:latest .
    
    # Clean up immediately
    rm -f /tmp/ssh_key
    

Local Development

Use the secure build script:

./scripts/build-cicd-secure.sh plex-playlist-cicd:latest

🔧 Required Setup

1. Gitea Secrets Configuration

Ensure these secrets are configured in your Gitea repository:

  • SSH_PRIVATE_KEY: Your private SSH key for git operations
  • GITEA_TOKEN: Token for pushing to container registry

2. Docker BuildKit Support

  • Gitea Actions: Automatically enabled with DOCKER_BUILDKIT=1
  • Local builds: Requires Docker 18.09+ with BuildKit enabled
  • CI runners: Ensure BuildKit support in your runner environment

📋 Best Practices Applied

  1. Temporary Files: SSH keys are written to temporary files and immediately removed
  2. File Permissions: SSH keys get proper 600 permissions
  3. Multi-stage Security: Keys are cleaned up within the same RUN command
  4. No ARG Secrets: Never pass secrets via build arguments
  5. Dockerignore Protection: .dockerignore prevents accidental secret inclusion

🧪 Testing Security

Verify no secrets in image:

# Build the image
./scripts/build-cicd-secure.sh test-image

# Check history (should show no secrets)
docker history test-image

# Try to find SSH keys (should find none)
docker run --rm test-image find / -name "*rsa*" -o -name "*ssh*" 2>/dev/null

🚀 Migration Checklist

  • Updated Dockerfile.cicd to use --mount=type=secret
  • Removed insecure ARG SSH_PRIVATE_KEY
  • Modified CI/CD workflow to use BuildKit secrets
  • Added .dockerignore patterns for SSH keys
  • Created secure build script
  • Documented security improvements

📚 References