Skip to main content

Caddy Docker Compose - Webserver & Reverse Proxy for Apache Container

549 words·
Caddy Docker-Compose Webserver Reverse Proxy

Prerequisites
#

Folder Structure
#

# Create folder structure
sudo mkdir -p /opt/caddy && cd /opt/caddy

Caddy Docker Compose File
#

Docker Compose File
#

  • Default Version: Volumes
services:
  caddy:
    image: caddy:latest
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./site:/srv
      - caddy_data:/data
      - caddy_config:/config

volumes:
  caddy_data:
  caddy_config:
  • Default Version: Host Mount
services:
  caddy:
    image: caddy:latest
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./site:/srv
      - ./caddy_data:/data
      - ./caddy_config:/config

HTML File Example
#

# Create the directory for the .indexhtml file
sudo mkdir site

# Create the index.html file
sudo vi site/index.html
<!DOCTYPE html>
<html>

<head>
        <title>jklug.work</title>
</head>

<body>
        <h1>Caddy Example</h1>
</body>

</html>

Caddy Examples
#

Plain Text
#

This example prints text without providing an index.html file. Different ports can be used (and still be TLS encrypted) just open them in the docker-compose.yml file.

# Create Docker Compose file
sudo vi docker-compose.yml
services:
  caddy:
    image: caddy:latest
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
      - "4443:4443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./site:/srv
      - caddy_data:/data
      - caddy_config:/config

volumes:
  caddy_data:
  caddy_config:
# Create the Caddyfile
sudo vi Caddyfile
caddy-website.jklug.work {
	respond "Hello, world!"
}

caddy-website.jklug.work:4443 {
	respond "Goodbye, world!"
}
# Create / start Docker stack
sudo docker compose up -d

Static Website HTTP
#

  • Static website on port 80
:80 {
    root * /srv
    file_server
}
  • Several static websites on port 80
caddy-site1.jklug.work:80 {
    root * /srv/site1
    file_server
}

caddy-site2.jklug.work:80 {
    root * /srv/site2
    file_server
}

Static Website HTTPS: Automatic TLS Certificate
#

  • Caddy will automatically apply a TLS certificate (FQDN required)

  • Redirection from HTTP to HTTPS

caddy-website.jklug.work {
    root * /srv
    file_server
}
  • Several static websites using HTTPS
caddy-site1.jklug.work {
    root * /srv/site1
    file_server
}

caddy-site2.jklug.work {
    root * /srv/site2
    file_server
}

Static Website HTTPS: Define Certificate
#

  • Create the certs folder and add the certificates before the container is started
services:
  caddy:
    image: caddy:latest
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./site:/srv
      - ./caddy_data:/data
      - ./caddy_config:/config
      - ./certs:/certs
  • Caddy will use an already existing certificate, for example a Let’s Encrypt wildcard certificate

  • Redirection from HTTP to HTTPS

caddy-website.jklug.work {
    root * /srv
    file_server
    tls /certs/fullchain.pem /certs/privkey.pem
}

Reverse Proxy for Container
#

# Create Docker network
docker network create caddy
  • Caddy Container
# Create Docker Compose file
sudo vi docker-compose.yml
services:
  caddy:
    image: caddy:latest
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./caddy_data:/data
      - ./caddy_config:/config
    networks:
      - caddy 

networks:
  caddy:
    external: true
  • Caddyfile
# Create the Caddyfile
sudo vi Caddyfile
caddy-site1.jklug.work {
    reverse_proxy apache_1:80
}

caddy-site2.jklug.work {
    reverse_proxy apache_2:80
}
  • Apache Container no 1
# Create Docker Compose file
sudo vi docker-compose.yml
version: '3.8'
services:

  apache2:
    image: httpd:latest
    container_name: apache_1
    ports:
      - "80"
    networks:
      - caddy 
    command: /bin/sh -c "echo 'Apache Container no 1' > /usr/local/apache2/htdocs/index.html && httpd-foreground"

networks:
  caddy:
    external: true
  • Apache Container no 2
# Create Docker Compose file
sudo vi docker-compose.yml
version: '3.8'
services:

  apache2:
    image: httpd:latest
    container_name: apache_2
    ports:
      - "80"
    networks:
      - caddy 
    command: /bin/sh -c "echo 'Apache Container no 2' > /usr/local/apache2/htdocs/index.html && httpd-foreground"

networks:
  caddy:
    external: true

Caddy Commands
#

# Reload Caddy
docker exec -w /etc/caddy containername caddy reload
# For example
docker exec -w /etc/caddy caddy-caddy-1 caddy reload

Links #

# Official Documentation
https://caddyserver.com/docs/

# DockerHub
https://registry.hub.docker.com/_/caddy