Post

Using GitHub Actions to deploy your Caddyfile

Overview

This guide explains how to set up and deploy a Caddyfile using GitHub Actions with a self-hosted runner.

Prerequisites

  1. Docker and Docker Compose: Docker and Docker Compose must be installed on your host machine. Refer to the Docker website for installation on your OS.
  2. Caddyfile: Chances are if you are viewing this guide, you already have Caddy running. This guide will not show you how to create a Caddyfile. Caddy has excellent documentation on how to do that here.

Requirements

  1. Caddy Container: Ensure Caddy is installed and running in a Docker container on your server.
  2. GitHub Repository: Create a repository for storing the Caddyfile.
  3. Self-hosted Runner: Setup a self-hosted runner on your server where Caddy is running.
  4. GitHub Action: Create a repository for storing the Caddyfile.

Steps

1. Set Up a Caddy server

  1. Create a docker compose file with volumes:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
     version: "3.7"
    
     services:
     caddy:
         image: caddy:latest
         container_name: caddy_public
         restart: unless-stopped
         cap_add:
         - NET_ADMIN
         ports:
         - "80:80"
         - "443:443"
         - "443:443/udp"
         volumes:
         - /path/on/host/caddy_data:/data
         - /path/on/host/caddy_config:/config
         - /path/on/host/caddy_caddyFile:/etc/caddy # take note of this host location. You will need to define it in GitHub Actions.
    
  2. Run docker compose up -d to start your container.

2. Create a GitHub Repository

  1. Create a new repository on GitHub.
  2. Create a directory structure as follows:
    1
    2
    
    └── caddy
        └── public
    

3. Set Up a Self-hosted Runner

The account you use for GitHub actions must have permission to write to the caddy_file volume on the machine. It also needs permission to run exec on the caddy docker container. I recommend creating a new account for the github actions service and adding this to the /etc/sudoers file (where git is the name of your account): git ALL=(ALL) NOPASSWD: /bin/cp, /usr/bin/docker exec *

  1. Go to your repository on GitHub.
  2. Click on Settings > Actions > Runners.
  3. Click New self-hosted runner and follow the instructions to download and configure the runner on the server.
  4. Assign a label to the runner, e.g., t1-public.

4. Create a GitHub Action

  1. In your repository, create a directory named .github/workflows/
  2. Inside .github/workflows/, create a file named deploy-public-caddyfile.yml
  3. Add the following content to the deploy-public-caddyfile.yml file and commit the changes:

    Change the run-on and run commands to match what you defined in the previous steps.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
     name: Deploy Caddyfile
    
     on:
       push:
         branches:
           - main  # Adjust this to your branch setup
         paths:
           - 'caddy/t1-public/Caddyfile'  # Trigger only when Caddyfile is changed
        
     jobs:
       deploy:
         runs-on: [self-hosted, t1-public]  # Use the label for your specific runner
         steps:
         - name: Checkout code
           uses: actions/checkout@v2
        
         - name: Copy Caddyfile to Docker volume
           run: |
             sudo cp ./caddy/t1-public/Caddyfile /var/lib/docker/volumes/caddy_caddyFile/_data/Caddyfile
           shell: bash
        
         - name: Gracefully Reload Caddy
           run: |
             caddy_container_id=$(docker ps | grep caddy | awk '{print $1;}')
             docker exec -w /etc/caddy $caddy_container_id caddy reload
           shell: bash
    
    

4. Run the Github action

  1. Add your Caddyfile to the caddy/public/ directory and your configuration should be updated.
This post is licensed under CC BY 4.0 by the author.