# Traefik Setup Guide for Docker Swarm This guide provides the step-by-step instructions to correctly configure and deploy Traefik in a Docker Swarm environment, especially when dealing with potentially read-only host filesystems. This method uses Docker Configs and Docker Volumes to manage Traefik's configuration and data, which is the standard best practice for Swarm. All commands should be run on your **Docker Swarm manager node**. --- ### Step 1: Create the `traefik.yml` Configuration File This step creates the Traefik static configuration file. You have two options: #### Option A: Using `sudo tee` (Direct Host Write) This command uses a `HEREDOC` with `sudo tee` to write the `traefik.yml` file directly to your manager node's filesystem. This is generally straightforward if your manager node's filesystem is writable. **Action:** 1. **IMPORTANT:** Replace `your-email@example.com` with your actual email address in the command below. 2. Copy and paste the entire block into your Zsh terminal on the manager node. ```zsh # --- Creates the traefik.yml file --- sudo tee ./traefik.yml > /dev/null <<'EOF' global: checkNewVersion: true sendAnonymousUsage: false log: level: INFO api: dashboard: true insecure: false entryPoints: web: address: ":80" http: redirections: entryPoint: to: websecure scheme: https websecure: address: ":443" providers: docker: network: traefik-public exposedByDefault: false certificatesResolvers: leresolver: acme: email: "your-email@example.com" storage: "/letsencrypt/acme.json" dnsChallenge: provider: duckdns delayBeforeCheck: "120s" EOF ``` #### Option B: Using `docker run` (Via Temporary Container) This method creates the `traefik.yml` file *inside* a temporary `busybox` container and then copies it to your manager node's current directory. This is useful if you prefer to avoid direct `sudo tee` or if you're working in an environment where direct file creation is restricted. **Action:** 1. **IMPORTANT:** Replace `your-email@example.com` with your actual email address in the command below. 2. Copy and paste the entire block into your Zsh terminal on the manager node. ```zsh # --- Creates the traefik.yml file in a temporary container and copies it out --- docker run --rm -i -v "$(pwd):/host" busybox sh -c 'cat > /host/traefik.yml <<\'EOF\' checkNewVersion: true sendAnonymousUsage: false log: level: INFO api: dashboard: true insecure: false entryPoints: web: address: ":80" http: redirections: entryPoint: to: websecure scheme: https websecure: address: ":443" http: tls: certResolver: leresolver providers: docker: network: traefik-public exposedByDefault: false certificatesResolvers: leresolver: acme: email: "your-email@example.com" storage: "/letsencrypt/acme.json" dnsChallenge: provider: duckdns delayBeforeCheck: 30s resolvers: - "192.168.1.196:53" - "192.168.1.245:53" - "192.168.1.62:53" EOF' ``` > **Note on Versioning:** The `traefik:latest` tag can introduce unexpected breaking changes, as seen here. For production or stable environments, it is highly recommended to pin to a specific version in your stack file, for example: `image: traefik:v2.11` or `image: traefik:v3.0`. --- ### Step 2: Create the Docker Swarm Config This command ingests the `traefik.yml` file (created in Step 1) into Docker Swarm, making it securely available to services. **Action:** Run the following command on your manager node. ```zsh docker config create traefik.yml ./traefik.yml ``` --- ### Step 3: Create the Let's Encrypt Volume This creates a managed Docker Volume that will persist your TLS certificates. **Action:** Run the following command on your manager node. ```zsh docker volume create traefik_letsencrypt ``` --- ### Step 4: Prepare the `acme.json` File Traefik requires an `acme.json` file to exist with the correct permissions before it can start. This command creates the empty file inside the volume you just made. **Action:** Run the following command on your manager node. ```zsh docker run --rm -v traefik_letsencrypt:/letsencrypt busybox sh -c "touch /letsencrypt/acme.json && chmod 600 /letsencrypt/acme.json" ``` --- ### Step 5: Update and Deploy the `networking-stack.yml` You can now deploy your `networking-stack` using the YAML below. It has been modified to use the Swarm config and volume instead of host paths. **Action:** 1. **IMPORTANT:** Replace `YOUR_DUCKDNS_TOKEN` with your actual DuckDNS token in the `environment` section. 2. Upload this YAML content to Portainer to deploy your stack. ```yaml version: '3.9' networks: traefik-public: external: true volumes: traefik_letsencrypt: external: true configs: traefik_yml: external: true name: traefik.yml services: traefik: image: traefik:latest ports: - "80:80" - "443:443" volumes: - /var/run/docker.sock:/var/run/docker.sock - traefik_letsencrypt:/letsencrypt networks: - traefik-public environment: - "DUCKDNS_TOKEN=YOUR_DUCKDNS_TOKEN" configs: - source: traefik_yml target: /traefik.yml deploy: labels: - "traefik.enable=true" - "traefik.http.routers.traefik.rule=Host(`traefik.sj98.duckdns.org`)" - "traefik.http.routers.traefik.entrypoints=websecure" - "traefik.http.routers.traefik.tls.certresolver=leresolver" - "traefik.http.routers.traefik.service=api@internal" placement: constraints: - node.role == manager whoami: image: traefik/whoami networks: - traefik-public deploy: labels: - "traefik.enable=true" - "traefik.http.routers.whoami.rule=Host(`whoami.sj98.duckdns.org`)" - "traefik.http.routers.whoami.entrypoints=websecure" - "traefik.http.routers.whoami.tls.certresolver=leresolver" - "traefik.http.services.whoami.loadbalancer.server.port=80" ``` --- ### Step 6: Clean Up (Optional) Since the configuration is now stored in Docker Swarm, you can remove the local `traefik.yml` file from your manager node's filesystem. **Action:** Run the following command on your manager node. ```zsh rm ./traefik.yml ``` --- ### Troubleshooting and Removal If you encounter an error and need to start the setup process over, follow these steps to cleanly remove all the components you created. Run these commands on your **Docker Swarm manager node**. #### Step 1: Remove the Stack First, remove the deployed stack from your Swarm. **Action:** - In Portainer, go to "Stacks", select your `networking-stack`, and click "Remove". #### Step 2: Remove the Docker Config This removes the Traefik configuration that was stored in the Swarm. **Action:** ```zsh docker config rm traefik.yml ``` #### Step 3: Remove the Docker Volume This deletes the volume that was storing your Let's Encrypt certificates. **Warning:** This will delete your existing certificates. **Action:** ```zsh docker volume rm traefik_letsencrypt ``` #### Step 4: Remove the Local Config File (If Present) If you didn't delete the `traefik.yml` file in the optional clean-up step, remove it now. **Action:** ```zsh rm ./traefik.yml ``` After completing these steps, your environment will be clean, and you can safely re-run the setup guide from the beginning. --- ### Step 7: Verify Traefik Dashboard Once your `networking-stack` is deployed and Traefik has started, you can verify its functionality by accessing the Traefik dashboard. **Action:** 1. Open your web browser and navigate to the Traefik dashboard: - **Traefik Dashboard:** `https://traefik.sj98.duckdns.org` You should see the Traefik dashboard, listing your routers and services. If you see a certificate warning, it might take a moment for Let's Encrypt to issue the certificate. If the dashboard loads, Traefik is running correctly.