Skip to content

jwillikers/caddy-ovh-image

Repository files navigation

Caddy OVH Image

Build Status pre-commit

A container image for the running the Caddy reverse-proxy complete with the Caddy OVH Module capable of completing the ACME DNS-01 challenge.

Synopsis

Image

quay.io/jwillikers/caddy-ovh

Tags
  • latest

Supported architectures
  • amd64 (x86_64)

  • arm64 (aarch64)

Labels
io.containers.autoupdate=registry

Enables automatic updates when using Podman and the fully-qualified image name.

Quick Start

I recommend putting the Caddy container along with all of the containers it will proxy on a dedicated Podman network with the DNS option enabled. This makes it easy to delegate to the corresponding containers and doesn’t require port-forwarding on their part, which means port address conflicts won’t be an issue. A dedicated Podman network also provides better isolation. If you need to, you can also use the Caddy container with host networking with other containers using host networking or those using the default slirp4netns networking mode. The example instructions here use dedicated Podman network. For more information on the configuring OVH DNS via the DNS-01 challenge, refer to the certbot-dns-ovh Documentation. It explains the related configuration in more detail.

  1. Allow rootless containers to publish to ports 80 and 443 by lowering the starting port for the range of unprivileged ports. This makes it possible to run the Caddy container rootless and use the standard HTTP and HTTPS ports.

    /etc/sysctl.d/99-lower-unprivileged_port_start.conf
    ; Allow publishing to lower port numbers without requiring superuser privileges.
    net.ipv4.ip_unprivileged_port_start=80
  2. Load the new sysctl configuration.

    sudo sysctl --system
  3. Open the default HTTP and HTTPS ports, 80 and 443 respectively, in the firewall, since rootless Podman won’t be able to open these ports for the container.

    sudo firewall-cmd --add-port=80/tcp --add-port=443/tcp --permanent
  4. Reload the firewall rules that were just saved.

    sudo firewall-cmd --reload
  5. Create a new Podman network which will have DNS networking enabled by default.

    podman network create --ipv6
  6. Open the OVH Create Token Page in a web browser.

  7. Enter the Application name, i.e. Caddy ROCKPro64.

  8. Enter an _Application description. I used ACME DNS-01 Challenge Provider.

  9. Select the time after which the token will expire in the Validity field. I use Unlimited to avoid the token expiring.

  10. The required Rights are /domain/zone/* for each of GET, PUT, POST, and DELETE.

  11. Store your OVH application key as a Podman secret to avoid exposing it.

    printf '****' '%s' | podman secret create ovh_application_key -
  12. Store your OVH application secret as a Podman secret to avoid exposing it.

    printf '****' '%s' | podman secret create ovh_application_secret -
  13. Store your OVH consumer key as a Podman secret to avoid exposing it.

    printf '****' '%s' | podman secret create ovh_consumer_key -
  14. In your Caddyfile, be sure to provide the previously stored secrets to the module. Then it’s just a matter of proxying to hosts using the network’s domain name, dns.podman by default. The following Caddyfile demonstrates enabling the OVH DNS-01 ACME challenge globally and configuring a reverse-proxy to a container running Gitea on the same Podman network.

    Caddyfile
    {
    	email jordan@jwillikers.com
    	acme_dns ovh {
    		endpoint {$OVH_ENDPOINT}
    		application_key {$OVH_APPLICATION_KEY}
    		application_secret {$OVH_APPLICATION_SECRET}
    		consumer_key {$OVH_CONSUMER_KEY}
    	}
    	# For testing
    	# acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
    }
    
    gitea.example {
    	reverse_proxy gitea.dns.podman:3000
    }
  15. Run Caddy rootless, forwarding the appropriate ports, proving the OVH secrets, and mounting the Caddyfile along with the necessary directories.

    podman run \
      --detach \
      --env OVH_ENDPOINT="ovh-eu" \
      --label "io.containers.autoupdate=registry" \
      --name caddy \
      --network podman1 \
      --publish 80:80/tcp \
      --publish 443:443/tcp \
      --rm \
      --secret ovh_application_key,type=env,target=OVH_APPLICATION_KEY \
      --secret ovh_application_secret,type=env,target=OVH_APPLICATION_SECRET \
      --secret ovh_consumer_key,type=env,target=OVH_CONSUMER_KEY \
      --volume $PWD:/etc/caddy:Z \
      --volume caddy-config:/config/:Z \
      --volume caddy-data:/data/:Z \
      quay.io/jwillikers/caddy-ovh:latest

Kubernetes

The Caddy container can also be configured and run via Kubernetes YAML. These instructions use the same Podman network created in the previous section.

  1. Configure a Kubernetes YAML file with the necessary secrets for OVH.

    caddy-secrets.yaml
    link:caddy-secrets.yaml[role=include]
  2. Load the secrets into Podman.

    podman play kube caddy-secrets.yaml
  3. Delete the secrets file.

    rm caddy-secrets.yaml
  4. Configure the path to the Caddyfile in the caddy.yaml Kubernetes YAML file.

    caddy.yaml
    link:caddy.yaml[role=include]
  5. Run the Caddy pod using the Kubernetes YAML file.

    podman play kube --network podman --replace

Build

  1. Install the necessary dependencies.

    sudo dnf -y install fish git podman pre-commit
  2. Clone this repository.

    git -C ~/Projects clone git@github.com:jwillikers/caddy-ovh-image.git
  3. Change into the project directory.

    cd ~/Projects/caddy-ovh-image
  4. Install pre-commit’s Git hooks.

    pre-commit install
  5. Build the Containerfile.

    podman build . -t caddy-ovh

Contributing

Contributions in the form of issues, feedback, and even pull requests are welcome. Make sure to adhere to the project’s Code of Conduct.

Open Source Software

This project is built on the hard work of countless open source contributors. Several of these projects are enumerated below.

Code of Conduct

Refer to the project’s Code of Conduct for details.

License

This repository is licensed under the GPLv3, a copy of which is provided in the license file.

© 2023 Jordan Williams

Authors