How to Deploy Traefik v3 with Docker Compose and Automatic HTTPS via Cloudflare DNS-01

Overview

This tutorial shows how to deploy Traefik v3 as a modern reverse proxy with Docker Compose and automatic HTTPS certificates using Let’s Encrypt via the Cloudflare DNS-01 challenge. The DNS-01 method works even behind NAT, on residential ISPs, and with Cloudflare’s orange cloud (proxy) enabled. By the end, you will have a secure, production-ready reverse proxy and a sample container accessible over HTTPS.

Prerequisites

- A Linux server (Ubuntu 22.04/24.04 or similar) with Docker Engine and Docker Compose v2 installed.
- A domain managed by Cloudflare (nameservers pointing to Cloudflare).
- A Cloudflare API token with Zone.DNS:Edit and Zone:Read permissions for the zone you’ll use.
- Basic terminal access and a user with Docker privileges.

Step 1 — Verify Docker and Compose

Confirm your Docker setup is ready. Run: docker --version and docker compose version. If Compose v2 is not present, install the latest Docker Engine from the official repository. On Ubuntu, ensure the docker group exists and your user is a member: sudo usermod -aG docker $USER then re-log.

Step 2 — Create a Dedicated Docker Network

Create an external network so Traefik can share it with your app containers: docker network create proxy. Using a dedicated network helps isolate traffic and makes adding new services predictable.

Step 3 — Prepare Folders and Secrets

Make a working directory for Traefik and create a place to store ACME data (certificates):

mkdir -p ~/traefik/letsencrypt
cd ~/traefik
touch ./letsencrypt/acme.json
chmod 600 ./letsencrypt/acme.json

Create an .env file to hold your Cloudflare token securely. This file will be read by Docker Compose:

echo "CF_DNS_API_TOKEN=<paste_your_cloudflare_api_token>" > .env

The API token should include Zone.DNS:Edit and Zone.Zone:Read permissions for the domain. Restrict the token to the specific zone for better security.

Step 4 — Create docker-compose.yml

Create a docker-compose.yml file in ~/traefik with the following content. Replace [email protected] with your email and whoami.example.com with a real subdomain in your zone.

services:
  traefik:
    image: traefik:v3.1
    command:
     - --providers.docker=true
     - --providers.docker.exposedbydefault=false
     - --entrypoints.web.address=:80
     - --entrypoints.websecure.address=:443
     - --entrypoints.web.http.redirections.entrypoint.to=websecure
     - --entrypoints.web.http.redirections.entrypoint.scheme=https
     - [email protected]
     - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
     - --certificatesresolvers.letsencrypt.acme.dnschallenge=true
     - --certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare
     - --api.dashboard=true
    ports:
     - "80:80"
     - "443:443"
    environment:
     - CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN}
    volumes:
     - /var/run/docker.sock:/var/run/docker.sock:ro
     - ./letsencrypt:/letsencrypt
    networks:
     - proxy

  whoami:
    image: traefik/whoami:v1.10
    labels:
     - "traefik.enable=true"
     - "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
     - "traefik.http.routers.whoami.entrypoints=websecure"
     - "traefik.http.routers.whoami.tls.certresolver=letsencrypt"
    networks:
     - proxy

networks:
  proxy:
    external: true

Create a DNS A/AAAA record for whoami.example.com pointing to your server’s public IP in Cloudflare. The orange cloud (proxy) can be ON or OFF; DNS-01 works either way.

Step 5 — Launch and Test

Start the stack from the ~/traefik directory: docker compose up -d. Traefik will request a certificate from Let’s Encrypt using the Cloudflare DNS-01 challenge. Check logs with docker compose logs -f traefik to confirm issuance (look for “Server responded with a certificate”).

Open https://whoami.example.com in your browser. You should see the whoami test service showing headers and IP details over HTTPS.

Optional: Secure the Traefik Dashboard

The dashboard is enabled but not published by default in this setup. To expose it safely, add labels to a new service or to Traefik itself using a distinct host like traefik.example.com, require basic auth middleware, and keep it behind TLS. Always disable --api.insecure=true in production.

Troubleshooting Tips

- If certificates do not issue, verify the API token has Zone.DNS:Edit and is scoped to the correct zone. Also confirm the .env is loaded and the environment variable name matches.
- If you see rate-limit errors, you may have requested too many certificates; wait and try again or use the Let’s Encrypt staging endpoint during testing (--certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory).
- Ensure your firewall allows TCP 80 and 443 inbound to the server.

Maintaining and Adding Services

To add a new app behind Traefik, place it on the proxy network and attach labels for rule, entrypoint, and TLS resolver. Example labels: traefik.enable=true, traefik.http.routers.app.rule=Host(`app.example.com`), traefik.http.routers.app.entrypoints=websecure, and traefik.http.routers.app.tls.certresolver=letsencrypt. Restart only the new service; Traefik hot-reloads routes automatically.

Conclusion

With Traefik v3, Docker Compose, and Cloudflare’s DNS-01 challenge, you can ship secure containers with automatic HTTPS and minimal friction. This setup scales cleanly, keeps certificates current, and works in challenging network environments. Add your apps with labels, keep tokens scoped and secret, and enjoy a tidy, TLS-by-default container platform.

3.

Deploy Ollama and Open WebUI on Ubuntu 24.04 with NVIDIA GPU, Docker Compose, and Traefik TLS

Overview

This tutorial shows how to deploy a secure, GPU-accelerated local AI stack on Ubuntu 24.04 using Docker Compose. We will run Ollama for model inference and Open WebUI as a sleek web interface, fronted by Traefik for reverse proxy, HTTPS (Let’s Encrypt), and basic authentication. You will get a production-ready setup that supports NVIDIA GPUs and is protected with TLS and a login prompt.

Prerequisites

- Ubuntu 24.04 LTS with a modern NVIDIA GPU (e.g., RTX series).
- A public DNS record (e.g., ai.example.com) pointing to your server’s IP.
- Ports 80 and 443 open in the firewall or cloud security group.
- A sudo-enabled user on the server.
- Docker and the Docker Compose plugin installed (Ubuntu’s docker.io + docker-compose-plugin or Docker’s official packages).
- An email address for Let’s Encrypt certificates.

1) Install NVIDIA Driver and Container Toolkit

First, make sure the proprietary NVIDIA driver is installed and working. On Ubuntu 24.04, the recommended driver is usually offered by “Additional Drivers” or via apt:

sudo apt update && sudo apt install -y ubuntu-drivers-common
sudo ubuntu-drivers install
sudo reboot

After reboot, confirm the driver and GPU are detected:

nvidia-smi

Now install the NVIDIA Container Toolkit so Docker can access the GPU:

curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit.gpg
distribution=$(. /etc/os-release; echo $ID$VERSION_ID)
curl -fsSL https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt update && sudo apt install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

2) Prepare Docker Network and Directory

Create a dedicated network and a working directory for the stack:

docker network create ai_net || true
mkdir -p ~/ai-stack/{letsencrypt,ollama}

3) Create HTTP Basic Auth for Open WebUI

We will protect the web UI with Traefik’s basic auth. Generate a bcrypt hash with htpasswd. Note: when placing the hash in docker-compose labels, escape each $ as $$.

sudo apt install -y apache2-utils
htpasswd -nbB aiadmin 'StrongP@ssw0rd!'

You will get output like aiadmin:$2y$05$abc.... Copy it for the next step and remember to replace each $ with $$ in the compose file.

4) Write docker-compose.yml

Create ~/ai-stack/docker-compose.yml with the following content. Replace ai.example.com and [email protected] with your values. Also paste your basic auth user:hash in the indicated line, with dollars escaped as $$.

version: '3.8'

services:
traefik:
image: traefik:v3.0
container_name: traefik
command:
- --api.dashboard=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- [email protected]
- --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.le.acme.httpchallenge=true
- --certificatesresolvers.le.acme.httpchallenge.entrypoint=web
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
networks:
- ai_net

ollama:
image: ollama/ollama:latest
container_name: ollama
environment:
- NVIDIA_VISIBLE_DEVICES=all
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
volumes:
- ./ollama:/root/.ollama
networks:
- ai_net
deploy:
resources:
reservations:
devices:
- capabilities: [gpu]

openwebui:
image: ghcr.io/open-webui/open-webui:latest
container_name: openwebui
environment:
- OLLAMA_BASE_URL=http://ollama:11434
depends_on:
- ollama
networks:
- ai_net
labels:
- traefik.enable=true
- traefik.http.routers.openwebui.rule=Host(`ai.example.com`)
- traefik.http.routers.openwebui.entrypoints=websecure
- traefik.http.routers.openwebui.tls.certresolver=le
- traefik.http.services.openwebui.loadbalancer.server.port=8080
- traefik.http.routers.openwebui.middlewares=openwebui-auth
- traefik.http.middlewares.openwebui-auth.basicauth.users=aiadmin:$$2y$$05$$REPLACE_WITH_YOUR_HASH

networks:
ai_net:
external: true

Notes: The deploy.resources.devices section in Compose is ignored outside Swarm, but many users report it still helps Compose detect GPUs with the NVIDIA Container Toolkit. If your GPU is not picked up, add runtime: nvidia under the ollama service or map NVIDIA devices explicitly.

5) Launch the Stack

Start everything in the background:

cd ~/ai-stack
docker compose up -d

Confirm that Traefik, Ollama, and Open WebUI are running:

docker ps

Wait 10–30 seconds for Let’s Encrypt to issue the certificate. Then visit https://ai.example.com. You should see a basic auth prompt. Enter your credentials and access Open WebUI.

6) Pull a Model and Test

From the Open WebUI interface, add a model like llama3:8b or phi3:mini. Alternatively, pull via CLI:

docker exec -it ollama ollama pull llama3:8b
docker exec -it ollama ollama run llama3:8b "Explain containers in one paragraph."

Open WebUI will connect to Ollama at http://ollama:11434 and use your GPU to accelerate inference if it is available.

Troubleshooting

- If nvidia-smi fails on the host, fix the driver first. The container cannot use a GPU your OS cannot see.
- If Open WebUI shows a connection error, check logs: docker logs openwebui -f and docker logs ollama -f.
- If certificates are not issued, ensure ports 80/443 are open and DNS is correct. Review docker logs traefik -f.
- If basic auth is not accepted, verify you escaped $ characters as $$ in the label.
- To keep models between upgrades, never delete the ./ollama folder.

Optional Hardening

- Restrict access by IP allowlists with Traefik middlewares in addition to basic auth.
- Set LOG_LEVEL=ERROR in Traefik if you want quieter logs.
- If exposing the Ollama API externally, add its own router, TLS, and auth. By default in this guide, the Ollama API is internal only.

Maintenance

Update images periodically and redeploy:

cd ~/ai-stack
docker compose pull
docker compose up -d

To stop the stack:

docker compose down

You now have a secure, GPU-ready, self-hosted AI chat environment with automatic HTTPS on Ubuntu 24.04, powered by Docker, Traefik, Ollama, and Open WebUI.

Popular Posts

Install Ollama and Open WebUI on Ubuntu 24.04 with NVIDIA GPU Acceleration (Step-by-Step)

Install Ollama + Open WebUI on Ubuntu 24.04 with NVIDIA GPU Acceleration (Step-by-Step)

Install a Local AI Chatbot on Ubuntu 24.04 with Ollama and Open WebUI (Step-by-Step)

Trending Now

Recovering from Btrfs Boot Failures Using GUI Tools on Fedora

By the end of this guide the reader will be able to identify a Btrfs‑based Fedora installation, boot from a live USB, list and restore snapshots using the graphical utilities btrfs‑assistant and snapper, and verify that the system returns to a functional state without resorting to the command line. Understanding the Btrfs Layout Used by Fedora Fedora Workstation and Fedora KDE install the root filesystem as a single Btrfs partition that contains two default sub‑volumes. One sub‑volume holds the traditional “/” hierarchy, while the second is dedicated to /var/lib/machines . The latter exists to keep container images out of snapshot operations; it remains empty on systems that do not run virtual machines. Because Btrfs stores data in sub‑volumes rather than separate partitions, a snapshot captures the state of an entire sub‑volume at a point in time. The installer (Anaconda) automatically registers these sub‑volumes with the snapper service. Snapper maintains a series of read‑only ...