No description
  • PowerShell 57.7%
  • Shell 42.3%
Find a file
2026-05-29 13:34:25 -04:00
apps init 2026-05-29 13:34:25 -04:00
.dockerignore initial validation of doco-cd and sops with mealie 2026-02-12 11:37:40 -05:00
.doco-cd.yaml remove template and add .doco-cd auto discovery file 2026-02-12 13:11:28 -05:00
.gitignore initial validation of doco-cd and sops with mealie 2026-02-12 11:37:40 -05:00
decrypt-sops.ps1 initial validation of doco-cd and sops with mealie 2026-02-12 11:37:40 -05:00
decrypt-sops.sh initial validation of doco-cd and sops with mealie 2026-02-12 11:37:40 -05:00
encrypt-sops.ps1 fix encryption logic to use secrets add litellm 2026-02-13 13:42:24 -05:00
encrypt-sops.sh add dockpeek and dozzle 2026-02-16 14:31:27 -05:00
QUICK-START.md initial validation of doco-cd and sops with mealie 2026-02-12 11:37:40 -05:00
README.md initial validation of doco-cd and sops with mealie 2026-02-12 11:37:40 -05:00
setup-sops.ps1 initial validation of doco-cd and sops with mealie 2026-02-12 11:37:40 -05:00
setup-sops.sh initial validation of doco-cd and sops with mealie 2026-02-12 11:37:40 -05:00
SOPS-EXAMPLE.md initial validation of doco-cd and sops with mealie 2026-02-12 11:37:40 -05:00

doco-cd-example

A sample repository demonstrating how to deploy multiple Docker Compose applications using doco-cd and Forgejo CI/CD runners, with SOPS encryption for secure secrets management.

🚀 Quick Start

New to this project? Start here: QUICK-START.md - Get running in 5 minutes!

Overview

This project showcases the doco-cd pattern for managing multiple containerized applications, each with its own docker-compose.yml and doco-cd.yml configuration file. When changes are pushed to any app folder, Forgejo Actions automatically deploys only the changed applications.

Key Features:

  • 🔐 SOPS Encryption - Secure secrets management with age encryption
  • 📦 Multi-app Structure - Independent deployment of multiple applications
  • 🎯 Selective Deployment - Only changed apps are deployed
  • 🔄 Automated CI/CD - Forgejo Actions integration
  • 🛡️ Production Ready - Security best practices included

What is doco-cd?

doco-cd is a tool for deploying Docker Compose applications to remote servers via SSH. It simplifies the deployment process by:

  • 📦 Copying compose files and dependencies to remote servers
  • 🚀 Running docker-compose commands remotely
  • 🔄 Managing multiple applications independently
  • 🎯 Supporting pre/post deployment hooks
  • 🔐 Handling environment variables securely

Project Structure

doco-cd-example/
├── .forgejo/
│   └── workflows/
│       └── doco-cd.yml         # Forgejo CI/CD workflow
├── app-a/
│   ├── docker-compose.yml      # Nginx web server
│   ├── doco-cd.yml             # doco-cd configuration
│   └── html/
│       └── index.html          # Static website
├── app-b/
│   ├── docker-compose.yml      # Redis + Redis Commander
│   └── doco-cd.yml             # doco-cd configuration
├── app-c/
│   ├── docker-compose.yml      # PostgreSQL + Adminer
│   ├── doco-cd.yml             # doco-cd configuration
│   ├── init.sql                # Database initialization
│   └── .env.example            # Environment variables template
└── README.md                   # This file

Sample Applications

App A - Static Web Server

  • Service: Nginx serving static HTML
  • Port: 8080
  • Use case: Simple static website deployment

App B - Redis Cache

  • Services: Redis + Redis Commander (web UI)
  • Ports: 6379 (Redis), 8081 (Commander)
  • Use case: Caching layer with management interface

App C - PostgreSQL Database

  • Services: PostgreSQL + Adminer (web UI)
  • Ports: 5432 (PostgreSQL), 8082 (Adminer)
  • Use case: Database with initialization scripts

Prerequisites

  • Docker and Docker Compose installed (locally and on deployment server)
  • Forgejo instance with Actions enabled
  • Forgejo runner configured and running
  • Remote deployment server with SSH access
  • doco-cd installed on CI/CD runner (installed automatically in workflow)

Local Testing

Test any application locally before deploying:

# Test app-a
cd app-a
docker-compose up -d
# Visit http://localhost:8080

# Test app-b
cd app-b
docker-compose up -d
# Visit http://localhost:8081 (Redis Commander)

# Test app-c
cd app-c
cp .env.example .env  # Edit as needed
docker-compose up -d
# Visit http://localhost:8082 (Adminer)

# Stop any app
docker-compose down

Forgejo CI/CD Setup

1. Configure Forgejo Secrets

Add these secrets to your Forgejo repository settings (Settings → Secrets):

  • DEPLOY_HOST: Deployment server hostname or IP (e.g., 192.168.1.100)
  • DEPLOY_USER: SSH username (e.g., deploy)
  • SSH_PRIVATE_KEY: SSH private key for authentication

2. Prepare Deployment Server

On your deployment server:

# Create deployment directories
sudo mkdir -p /opt/apps/{app-a,app-b,app-c}
sudo chown -R deploy:deploy /opt/apps

# Ensure Docker and Docker Compose are installed
docker --version
docker-compose --version

3. How It Works

The Forgejo workflow (.forgejo/workflows/doco-cd.yml):

  1. Detects changes: Identifies which app folders were modified
  2. Deploys selectively: Only deploys changed applications
  3. Uses doco-cd: Runs doco-cd deploy for each changed app
  4. Runs in parallel: Multiple apps can deploy simultaneously

4. Deployment Trigger

Push changes to the main branch:

# Modify app-a
echo "Updated content" > app-a/html/index.html
git add app-a/
git commit -m "Update app-a content"
git push origin main
# Only app-a will be deployed

doco-cd Configuration

Each app has a doco-cd.yml file that configures deployment:

version: "1"

target:
  host: "${DEPLOY_HOST}"      # From Forgejo secrets
  user: "${DEPLOY_USER}"      # From Forgejo secrets
  port: 22
  path: "/opt/apps/app-a"     # Remote deployment path

compose:
  file: "docker-compose.yml"
  project_name: "app-a"

deploy:
  pull: true                  # Pull images before deploying
  build: false                # Don't build (use pre-built images)
  remove_orphans: true        # Clean up old containers
  timeout: 300

hooks:
  pre_deploy:
    - echo "Starting deployment..."
  post_deploy:
    - echo "Deployment complete!"

Adding New Applications

  1. Create app folder:

    mkdir app-d
    
  2. Add docker-compose.yml:

    version: '3.8'
    services:
      your-service:
        image: your-image
        # ... configuration
    
  3. Add doco-cd.yml:

    version: "1"
    target:
      host: "${DEPLOY_HOST}"
      user: "${DEPLOY_USER}"
      path: "/opt/apps/app-d"
    compose:
      file: "docker-compose.yml"
      project_name: "app-d"
    
  4. Update workflow: Add a new job in .forgejo/workflows/doco-cd.yml following the existing pattern

SOPS Encryption Integration

doco-cd supports SOPS (Secrets OPerationS) for encrypting sensitive data in your deployment files. This allows you to commit encrypted secrets to version control safely.

Why Use SOPS?

Secure: Encrypt secrets before committing to git Flexible: Supports YAML, JSON, ENV, and INI files Automatic: doco-cd automatically detects and decrypts SOPS files Partial encryption: Encrypt only sensitive values, keep structure readable

Quick Setup

  1. Run the setup script:

    # Linux/macOS
    chmod +x setup-sops.sh
    ./setup-sops.sh
    
    # Windows PowerShell
    .\setup-sops.ps1
    
  2. Encrypt your secrets:

    # Create a secrets file
    cd app-a
    cp secrets.env.example secrets.env
    # Edit secrets.env with your actual secrets
    
    # Encrypt it with SOPS
    sops encrypt --age <your-age-public-key> secrets.env > secrets.enc.env
    
  3. Reference encrypted file in docker-compose.yml:

    services:
      app:
        env_file:
          - secrets.enc.env  # doco-cd will decrypt this automatically
    
  4. Configure CI/CD: Add SOPS_AGE_KEY to your Forgejo secrets (the private key from sops_age_key.txt)

Manual SOPS Setup

If you prefer manual setup:

# Install age (encryption tool)
# macOS: brew install age
# Linux: apt install age
# Windows: scoop install age

# Install SOPS
# macOS: brew install sops
# Linux: Download from https://github.com/getsops/sops/releases
# Windows: scoop install sops

# Generate age key pair
age-keygen -o sops_age_key.txt

# Extract public key
grep "public key:" sops_age_key.txt

Encrypting Files

# Encrypt a file
sops encrypt --age <age-public-key> secrets.env > secrets.enc.env

# Edit encrypted file
SOPS_AGE_KEY_FILE=sops_age_key.txt sops edit secrets.enc.env

# Decrypt file (for testing)
sops decrypt secrets.enc.env

Supported File Formats

  • .yaml, .yml - YAML files
  • .json - JSON files
  • .env - Environment files
  • .ini - INI configuration files

Example: Encrypted Environment File

<augment_code_snippet path="app-a/secrets.env.example" mode="EXCERPT">

# Example secrets file - encrypt this with SOPS
API_KEY=your-api-key-here
DB_PASSWORD=your-database-password

</augment_code_snippet>

After encryption with SOPS, the file becomes unreadable without the decryption key, but doco-cd will automatically decrypt it during deployment.

CI/CD Configuration for SOPS

Update your Forgejo workflow to include the SOPS key:

- name: Deploy app-a
  working-directory: app-a
  env:
    DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
    DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
    SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }}  # Add this
  run: |
    doco-cd deploy -c doco-cd.yml

Important: Never commit sops_age_key.txt to git! It's automatically added to .gitignore.

Troubleshooting

View deployment logs in Forgejo

Check the Actions tab in your Forgejo repository for workflow runs and logs.

SSH connection issues

# Test SSH connection from runner
ssh -i ~/.ssh/id_rsa user@host "echo 'Connection successful'"

View remote container logs

ssh user@host "cd /opt/apps/app-a && docker-compose logs -f"

Manual deployment

# Install doco-cd locally
pip install doco-cd

# Deploy manually
cd app-a
export DEPLOY_HOST=your-host
export DEPLOY_USER=your-user
doco-cd deploy -c doco-cd.yml

SOPS decryption issues

# Test SOPS decryption locally
SOPS_AGE_KEY_FILE=sops_age_key.txt sops decrypt secrets.enc.env

# Verify age key is correct
grep "public key:" sops_age_key.txt

Alternative: External Secrets Providers

While this example uses SOPS encryption, doco-cd also supports external secret management providers:

  • AWS Secrets Manager
  • Bitwarden Secrets Manager
  • 1Password
  • Infisical
  • OpenBao

See doco-cd External Secrets Wiki for configuration details.

SOPS vs External Providers

Feature SOPS External Providers
Cost Free Varies (some free tiers)
Setup Simple (age key) Requires service account
Offline Works offline Requires API access
Git-friendly Encrypted files in repo ⚠️ References only
Rotation Manual Often automated
Audit logs Git history Provider-specific
Best for Small teams, simple setups Enterprise, compliance needs

Resources

Documentation

Tools

Contributing

Feel free to submit issues or pull requests to improve this example repository!

License

MIT