How to Deploy Caddy with Docker on a SWC Cloud Server

July 8, 2024 Docker, Web Servers
Avatar photo

Russell Bates

Caddy is a versatile, open-source web server that provides secure access to applications on your server. Docker, a container orchestration platform, allows for efficient application building and deployment. This guide will walk you through the process of installing Caddy using Docker on a SecureWeb Cloud Server, creating a sample Docker application, and configuring Caddy to securely expose your internal application.

Before You Begin

Ensure you have:

  1. Deployed a SWC Cloud Server
  2. SSH access to the server
  3. Created a non-root sudo user
  4. Added the user to the Docker group:
   $ sudo usermod -aG docker myuser
  1. Switched to the non-root sudo user account:
   $ su - myuser

Setting Up Caddy

Caddy requires two host locations for persistent data storage. Let’s set these up:

  1. Create a Caddy files directory:
   $ sudo mkdir -p /opt/caddy/
   $ cd /opt/caddy
  1. Create data and config directories:
   $ sudo mkdir data
   $ sudo mkdir caddy_config
  1. Create and edit the Caddyfile:
   $ sudo touch Caddyfile
   $ sudo nano Caddyfile
  1. Add the following to the Caddyfile:
   :80 {
           respond "Caddy is configured correctly!"
   }
  1. Verify your directory structure:
   $ ls /opt/caddy

Installing Caddy with Docker

You can install Caddy using either Docker CLI or Docker Compose.

Using Docker CLI

  1. Pull the Caddy image:
   $ docker pull caddy
  1. Run Caddy as a Docker container:
   $ docker run -d -p 80:80 -p 443:443 -p 443:443/udp \
   -v /opt/caddy/Caddyfile:/etc/caddy/Caddyfile \
   -v /opt/caddy/data:/data \
   -v /opt/caddy/caddy_config:/config \
   --name caddy caddy
  1. Verify the container is running:
   $ docker ps
  1. Test access to Caddy:
   $ curl 127.0.0.1:80

Using Docker Compose

  1. Create a Docker Compose file:
   $ touch caddy-install.yaml
   $ nano caddy-install.yaml
  1. Add the following configuration:
   version: "3.9"

   services:
     caddy:
       image: caddy:latest
       container_name: caddy
       restart: unless-stopped
       ports:
         - "80:80"
         - "443:443"
         - "443:443/udp"    
       networks:
         - caddy-net 
       volumes:
         - /opt/caddy/Caddyfile:/etc/caddy/Caddyfile
         - /opt/caddy/caddy_data:/data
         - /opt/caddy/caddy_config:/config

   volumes:
     caddy_data:
       external: true
     caddy_config:

   networks:
     caddy-net:
       driver: bridge
  1. Run Docker Compose:
   $ docker compose -f caddy-install.yaml up -d
  1. Verify Caddy is running:
   $ docker ps
   $ curl 127.0.0.1:80

Configuring Docker Networking

To enable inter-container communication:

  1. Create a Docker network:
   $ docker network create caddy-net
  1. Connect Caddy to the network:
   $ docker network connect caddy-net caddy
  1. Verify the connection:
   $ docker network inspect caddy-net

Exposing Docker Applications with Caddy

Let’s set up a sample application and configure Caddy as a reverse proxy:

  1. Deploy a sample Nginx application:
   $ docker run -d -p 80 --name nginx --network caddy-net nginx
  1. Update the Caddyfile:
   $ sudo nano /opt/caddy/Caddyfile
  1. Modify the configuration:
   :80 {
           reverse_proxy nginx:80
   }
  1. Reload Caddy:
   $ docker exec -w /etc/caddy caddy caddy reload
  1. Test the configuration:
   $ curl 127.0.0.1:80

Enhancing Security

Configure your firewall to allow traffic to Caddy:

  1. Allow HTTP and HTTPS ports:
   $ sudo ufw allow 80
   $ sudo ufw allow 443
  1. Reload the firewall:
   $ sudo ufw reload

Setting Up Automatic SSL Certificates

Caddy can automatically handle SSL certificates for your domains:

  1. Add a domain record pointing to your server’s IP.
  2. Update the Caddyfile:
   app.example.com {
           tls your_email@example.com
           reverse_proxy nginx:80
   }
  1. Reload Caddy:
   $ docker exec -w /etc/caddy caddy caddy reload
  1. Access your domain via HTTPS after a short wait.

Troubleshooting

If you encounter issues:

  1. View Caddy logs:
   $ docker logs caddy
  1. For format errors, use:
   $ docker exec -w /etc/caddy caddy caddy fmt --overwrite
  1. Always reload Caddy after changes:
   $ docker exec -w /etc/caddy caddy caddy reload

By following this guide, you’ve successfully set up Caddy with Docker, configured it as a reverse proxy, and enabled automatic HTTPS. Caddy’s flexibility allows for further customization to meet your specific needs. For more advanced configurations, refer to the official Caddy documentation.