Git Product home page Git Product logo

caddy-custom-builds's Introduction

Caddy Docker Custom Builds

GitHub release (latest SemVer) GitHub build status License

Caddy takes a modular approach to building Docker images, allowing users to include only the modules they need. This repository aims to provide flexibility and convenience to run Caddy with specific combinations of modules by providing pre-built images according to the needs and preferences of the users.

All custom images are updated automatically when a new version of Caddy is released using the official Caddy Docker image. This is done by using GitHub Actions to build and push the images for all Caddy supported platforms to Docker Hub, GitHub Packages and Quay container registries.

All commits and tags are signed with a GPG key to ensure their integrity and authenticity, and 2FA is enabled in the accounts involved in the management of this repository and the container registries.

Builds

If you are looking for a specific custom build not available yet in this repository, please open a new Issue with your request. To make sure no broken or unsafe builds are created, the requested modules should be properly maintained and listed in the Caddy's download page. Additional information and instructions can be found by clicking on the name of the Caddy images and modules listed below.

Caddy Images:

Modules:

Usage

Since all images from this repository are built off the official Caddy Docker image, the same volumes and/or bind mounts, ports mapping, environment variables, etc. can be used with this container. Please refer to the official Caddy Docker image and docs for more information on using Caddy.

Docker builds for all Caddy supported platforms are available at the following container registries:

  • Docker Hub > docker pull serfriz/<caddy-build-name>:latest
  • GitHub Packages > docker pull ghcr.io/serfriz/<caddy-build-name>:latest
  • Quay > docker pull quay.io/serfriz/<caddy-build-name>:latest

To pull a specific build, replace <caddy-build-name> with the desired one. For example, to pull the caddy-cloudflare build from Docker Hub, use docker pull serfriz/caddy-cloudflare:latest.

Tags

The following tags are available for all images:

  • latest
  • <version> (eg: 2.7.4, including: 2.7, 2, etc.)

Container Creation

Simply create the container using the docker run command, or a docker-compose.yml file including the necessary environment variables depending on the modules used. The following blocks contain examples for both methods using <caddy-build-name> as the image name (replace it with the desired Caddy build name), and including all environment variables required by the modules listed above (some may not apply to your specific build).

Docker Run

docker run --rm -it \
  --name caddy \  # feel free to choose your own container name
  --restart unless-stopped \  # run container unless stopped by user (optional)
  -p 80:80 \  # HTTP port
  -p 443:443 \  # HTTPS port
  -p 443:443/udp \  # HTTP/3 port (optional)
  -v caddy-data:/data \  # volume mount for certificates data
  -v caddy-config:/config \  # volume mount for configuration data
  -v $PWD/Caddyfile:/etc/caddy/Caddyfile \  # to use your own Caddyfile
  -v $PWD/log:/var/log \  # bind mount for the log directory (optional)
  -v $PWD/srv:/srv \  # bind mount to serve static sites or files (optional)
  -e CLOUDFLARE_API_TOKEN=<token-value> \  # Cloudflare API token (if applicable)
  -e DUCKDNS_API_TOKEN=<token-value> \  # DuckDNS API token (if applicable)
  -e CROWDSEC_API_KEY=<key-value> \  # CrowdSec API key (if applicable)
  -e NETCUP_CUSTOMER_NUMBER=<number-value> \  # Netcup customer number (if applicable)
  -e NETCUP_API_KEY=<key-value> \  # Netcup API key (if applicable)
  -e NETCUP_API_PASSWORD=<password-value> \  # Netcup API password (if applicable)
  serfriz/<caddy-build-name>:latest  # replace with the desired Caddy build name

The volume and bind mounts can be adjusted to meet to your needs, $PWD is used to reference the current working directory, but you can replace it with your preferred path. The environment variables are only required if the modules used in the build require them.

The default Caddyfile that is included inside the Docker container is just a placeholder to serve a static Caddy welcome page with some useful instructions. So you will most likely want to mount your own $PWD/Caddyfile to configure Caddy according to your needs (the file must already exist in the specified path before creating the container).

The restart policy can be adjusted to your needs. The policy unless-stopped ensures the container is always running (even at boot) unless it is explicitly stopped by the user.

Docker Compose

version: "3.7"
services:
  caddy:
    image: serfriz/<caddy-build-name>:latest  # replace with the desired Caddy build name
    container_name: caddy  # feel free to choose your own container name
    restart: "unless-stopped"  # run container unless stopped by user (optional) 
    ports:
      - "80:80"  # HTTP port
      - "443:443"  # HTTPS port
      - "443:443/udp"  # HTTP/3 port (optional)
    volumes:
      - caddy-data:/data  # volume mount for certificates data
      - caddy-config:/config  # volume mount for configuration data
      - $PWD/Caddyfile:/etc/caddy/Caddyfile  # to use your own Caddyfile
      - $PWD/log:/var/log  # bind mount for the log directory (optional)
      - $PWD/srv:/srv \  # bind mount to serve static sites or files (optional)
    environment:
      - CLOUDFLARE_API_TOKEN=<token-value>  # Cloudflare API token (if applicable)
      - DUCKDNS_API_TOKEN=<token-value>  # DuckDNS API token (if applicable)
      - CROWDSEC_API_KEY=<key-value>  # CrowdSec API key (if applicable)
      - NETCUP_CUSTOMER_NUMBER=<number-value> \  # Netcup customer number (if applicable)
      - NETCUP_API_KEY=<key-value> \  # Netcup API key (if applicable)
      - NETCUP_API_PASSWORD=<password-value> \  # Netcup API password (if applicable)
volumes:
  caddy-data:
    external: true
  caddy-config:

Defining the data volume as external makes sure docker-compose down does not delete the volume, but you may need to create it first using docker volume create caddy-data. This doesn't apply to bind mounts if you opt to use them instead of volumes.

Graceful Reloads

Caddy does not require a full restart when the Caddyfile is modified. Caddy comes with a caddy reload command which can be used to reload its configuration with zero downtime.

When running Caddy in Docker, the recommended way to trigger a config reload is by executing the caddy reload command in the running container. First, you'll need to determine your container ID or name. Then, pass the container ID to docker exec. The working directory is set to /etc/caddy so Caddy can find your Caddyfile without additional arguments.

caddy_container_id=$(docker ps | grep caddy | awk '{print $1;}')  # use your container name if different from 'caddy'
docker exec -w /etc/caddy $caddy_container_id caddy reload

It is possible to create an alias for the caddy reload command to make it more convenient to use by adding the following line to your ~/.bashrc or ~/.zshrc file:

alias caddy-reload="docker exec -w /etc/caddy $(docker ps | grep caddy | awk '{print $1;}') caddy reload"

Once you have added the alias to the appropriate file, you will need to source it for the changes to take effect. You can do this by running source ~/.bashrc or source ~/.zshrc in your terminal. After this, you will be able to use the caddy-reload alias in your terminal sessions.

Configuration

This section aims to provide some basic information on how to configure Caddy with the modules included in the custom builds, but it is not intended to be a comprehensive guide. All the examples are based on the official Caddyfile syntax and the modules' documentation.

DNS Modules

To make use of the different modules that provide DNS-01 ACME validation support at the server level, set the global acme_dns directive in your Caddyfile using your DNS provider's name and the respective environment variable for the API token. The example shows the use case for Cloudflare DNS with the rest of the DNS providers commented out.

{
  acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN} #  for Cloudflare
  # acme_dns duckdns {env.DUCKDNS_API_TOKEN} #  for DuckDNS
  # acme_dns netcup {  # for Netcup
		# 	customer_number {env.NETCUP_CUSTOMER_NUMBER}
		# 	api_key {env.NETCUP_API_KEY}
		# 	api_password {env.NETCUP_API_PASSWORD}
		# }
}

Alternatively, you can use the tls directive at each site. See the caddy-dns/cloudflare module for additional details.

my.domain.tld {
  tls {
    dns cloudflare {env.CLOUDFLARE_API_TOKEN}  # for Cloudflare
    # dns duckdns {env.DUCKDNS_API_TOKEN}  # for DuckDNS
    # dns netcup {  # for Netcup
		# 	customer_number {env.NETCUP_CUSTOMER_NUMBER}
		# 	api_key {env.NETCUP_API_KEY}
		# 	api_password {env.NETCUP_API_PASSWORD}
		# }
  }
}

Creating a Cloudflare API Token

You can generate a Cloudflare API token via the Cloudflare web dashboard through the following steps:

  1. Login to your Cloudflare Dashboard
  2. Go to Account Profile > API Tokens
  3. Click "Create token" (Use the "Create Custom Token" option)
  4. Grant the following permissions:
    • Zone > Zone > Read
    • Zone > DNS > Edit
  5. Copy the token and use it as the CLOUDFLARE_API_TOKEN environment variable.

Creating a DuckDNS API Token

To generate a DuckDNS API token, login to your DuckDNS account, copy the token, and use it as the DUCKDNS_API_TOKEN environment variable. You can recreate the token by clicking on the three vertical lines in the top right corner next to your logged in email, and selecting the recreate token option.

Creating a Netcup API Token

To generate a Netcup API token follow the steps from the Netcup API docs. Use the NETCUP_CUSTOMER_NUMBER, NETCUP_API_KEY and NETCUP_API_PASSWORD environment variables in the Docker Compose/Run and Caddyfile configuration.

Cloudflare IPs

To restrict access to your server only to Cloudflare's IP ranges, add the trusted_proxies directive to the global options, under servers, in your Caddyfile. For additional details, refer to trusted_proxies/cloudflare documentation and WeidiDeng/caddy-cloudflare-ip repository.

{
  servers {
    trusted_proxies cloudflare {
      interval 12h
      timeout 15s
    }
  }
}

Dynamic DNS

To keep your DNS records updated with the public IP address of your instance, add the dynamic_dns directive to the global options in your Caddyfile. This module regularly queries a service for your public IP address and updates the DNS records via your DNS provider's API whenever it changes. For additional details and advanced configuration examples refer to mholt/caddy-dynamicdns repository. The example shows the use case for Cloudflare DNS with the rest of the DNS providers commented out.

{
  dynamic_dns {
    provider cloudflare {env.CLOUDFLARE_API_TOKEN}  # for Cloudflare
    # provider duckdns {env.DUCKDNS_API_TOKEN}  # for DuckDNS
    # dns netcup {  # for Netcup
		# 	customer_number {env.NETCUP_CUSTOMER_NUMBER}
		# 	api_key {env.NETCUP_API_KEY}
		# 	api_password {env.NETCUP_API_PASSWORD}
		# }
    domains {
      domain.tld
    }
  }
}

Using the option dynamic_domains, it can also be configured to scan through the domains configured in the Caddyfile and try to manage those DNS records.

CrowdSec Bouncer

CrowdSec is a free and open source security automation tool that uses local logs and a set of scenarios to infer malicious intent. In addition to operating locally, an optional community integration is also available, through which crowd-sourced IP reputation lists are distributed.

To make use of the CrowdSec Bouncer module, set the global crowdsec directive in your Caddyfile, and include it in every site you want to protect. For advanced usage, refer to the hslatman/caddy-crowdsec-bouncer repository.

{
  debug  # makes Caddy logs more detailed (optional)
  order crowdsec first  # forces the CrowdSec directive to be executed first
  crowdsec {
    api_url http://localhost:8080  # it should point to your CrowdSec API (it can be a remote URL)
    api_key {env.CROWDSEC_API_KEY}
  }
}

my.domain.tld {
  crowdsec
  log {
    output file /var/log/access.log  # the path should match the bind mount of the log directory
  }
}

Creating a CrowdSec API Key

To register the Caddy CrowdSec Bouncer to your API, you need to run the command below on the server where the CrowdSec API is installed, and use the generated API key CROWDSEC_API_KEY as environment variable when creating the Caddy container.

sudo cscli bouncers add caddy-bouncer

For additional details, refer to the CrowdSec documentation.

Rate Limit

The rate_limit HTTP handler module lets you define rate limit zones, which have a unique name of your choosing. If a rate limit is exceeded, an HTTP error with status 429 will be returned. This error can be handled using the conventional error handling routes in your config.

Additional information and Caddyfile configuration examples can be found in the mholt/caddy-ratelimit repository.

Caddy Security

This plugin implements different authentication methods: Form-Based, Basic, Local, LDAP, OpenID Connect, OAuth 2.0, SAML, including MFA/2FA with App Authenticators and Yubico (formerly caddy-auth-portal). It is also an authorization plugin for HTTP request authorization based on JWT/PASETO tokens (formerly caddy-authorize, caddy-auth-jwt), and manages credentials for various integrations.

Please, refer to the official greenpau/caddy-security documentation for additional details. Some configuration examples can also be found in the authp/authp.github.io repository.

Docker Proxy

The plugin scans Docker metadata, looking for labels indicating that the service or container should be served by Caddy. Then, it generates an in-memory Caddyfile with site entries and proxies pointing to each Docker service by their DNS name or container IP. Every time a Docker object changes, the plugin updates the Caddyfile and triggers Caddy to gracefully reload with zero downtime.

Additional information and Caddyfile configuration examples can be found in the lucaslorentz/caddy-docker-proxy repository.

Sablier

Sablier is a free and open-source software that can scale your workloads on demand following different strategies. Your workloads can be a docker container, a kubernetes deployment and more (see providers for the full list). This plugin provides an integration with Caddy.

Additional information and Caddyfile configuration examples can be found in the acouvreur/sablier documentation.

GeoIP Filter

Allows Caddy to filter traffic based on the client's IP address location. This module needs access to the Maxmind GeoLite2 database which can be downloaded for free after creating an account. Additional information is available on Maxmind official website. You will specifically need the GeoLite2-Country.mmdb file, or the GeoLite2-City.mmdb if you're matching on subdivisions and metro codes.

Information and examples about the usage of this module can be found on the on the Caddy website's plugin page and the porech/caddy-maxmind-geolocation repository.

Events Exec

It can be used to execute commands on the system based on specific events, such as when a certificate is renewed. This is configured in the Caddyfile using the standard events directive along with the events.handlers.exec module. Additional information and examples can be found in the mholt/caddy-events-exec repository. Please be mindful of any security implications of the commands you run and how you configure this module.

Contributing

Feel free to contribute, request additional Caddy images with your preferred modules, and make things better by opening an Issue or Pull Request.

License

Software under GPL-3.0 ensures users' freedom to use, modify, and distribute it while keeping the source code accessible. It promotes transparency, collaboration, and knowledge sharing. Users agree to comply with the GPL-3.0 license terms and provide the same freedom to others.

caddy-custom-builds's People

Contributors

serfriz avatar dependabot[bot] avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.