Using my own root certificates for my web-app

I have traefik running in docker swarm. Here is my stack:

version: '3'

services:
  traefik:
    # The latest official supported Traefik docker image
    image: traefik:v2.9
    # Enables the Traefik Dashboard and tells Traefik to listen to docker
    # enable --log.level=INFO so we can see what Traefik is doing in the log files
    deploy:
      placement:
        constraints:
          - node.role==manager
    ports:
      # Exposes port 80 for incomming web requests
      - "80:80"
      - "443:443"
      # The Web UI port http://0.0.0.0:8080 (enabled by --api.insecure=true)
      - "8080:8080"
    networks:
      - public
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock
      - /home/robo/docker-volumes/traefik/traefik-yaml/traefik.yml:/etc/traefik/traefik.yml
      - /home/robo/docker-volumes/cert:/etc/certs/

networks:
  public:
    external: true
    

I have a trafik.yml that looks like this:

################################################################
# API and dashboard configuration
################################################################
api:
  # Dashboard
  #
  #
  dashboard: true
  insecure: true

################################################################
# Docker configuration backend
################################################################
providers:
  docker:
    watch: true
    exposedByDefault: false
    swarmMode: true

################################################################
# Traefik Logging
################################################################
log:
  level:DEBUG

################################################################
# Entrypoint
################################################################
entryPoints:
  web:
    address: ":80"
  websecure:
    address: ":443"
################################################################
# certificates
################################################################
http:
  routers:
    subdomain-router:
      rule: "Host(`sendsms.unord.dk`)"
      service: sendsms
      tls:
        certFile: /etc/certs/_.unord.dk.crt
        keyFile: /etc/certs/_.unord.dk.key

And my web-app stack looks like this:

version: '3.2'
services:
  web-app:
    image: robounord/sms-unord-django:v1.07
    container_name: sms-unord-django
    command: "python manage.py runserver 0.0.0.0:8000" 
    networks:
      - public
    deploy:
      labels:
       - "traefik.enable=true"
       - "traefik.port=public"
       - "traefik.http.routers.sendsms.rule=Host(`sendsms.unord.dk`)"
       - "traefik.http.routers.service=sendsms"
       - "traefik.http.services.sendsms.loadbalancer.server.port=8000"
       - "traefik.http.routers.sendsms.tls=true"
       - "traefik.http.routers.sendsms.entrypoints=websecure"

       
    volumes:
      - /home/robo/docker-volumes/sms-unord/code/sms-unord:/app
      - /home/robo/docker-volumes/cert:/etc/certs/
      
networks:
  public:
    external: true

I am useing a root certificate unord.dk (files: '.unord.crt', '.unord.key') for my web-app sendsms.unord.dk. But when I access the website https://sendsms.unord.dk which only runs localy it uses self signede certificates from traefik instead. I am getting no errors from traefik.

Not sure where I am going worng here.

You need to setup your custom certificates in a dynamic config file, which you load in static config via provider.file. And, as you did, enable TLS on the router labels with .tls=true or globally on the websecure entrypoint.

# static config
providers.file.directory=/traefik
providers.file.watch=true

# dynamic config, for example /traefik/traefik-dynamic.yml
tls:
  options:
    default:
      minVersion: VersionTLS12
  certificates:
    - certFile: /traefik/example.com.crt
      keyFile: /traefik/example.com.key

If you use Docker Swarm, you can place the certs in a Docker Swarm config or secret, which is automatically available on all nodes. But the update (every year) is more complicated, we usually re-create the whole stack for that. But you can also just simply mount them from the hosts.

I have changed it to the following:
traefik.yml:

################################################################
# API and dashboard configuration
################################################################
api:
  # Dashboard
  #
  #
  dashboard: true
  insecure: true
################################################################
# Docker configuration backend
################################################################
providers:
  file:
    filename: "/etc/traefik/dynamic_conf.yml"
    watch: true
  docker:
    watch: true
    exposedByDefault: false
    swarmMode: true
################################################################
# Traefik Logging
################################################################
log:
  level: DEBUG

################################################################
# Entrypoint
################################################################
entryPoints:
  web:
    address: ":80"
  websecure:
    address: ":443"

dynamic_conf.yml:

################################################################
# certificates
################################################################
tls:
  options:
    default:
      minVersion: VersionTLS12
  certificates:
      - certFile: /etc/certs/_.unord.dk.crt
        keyFile: /etc/certs/_.unord.dk.key

Still not working and I am not getting any errors from traefik. I have ssh in to the traefik container and it can find the .crt file and .key.file. It also loads the traefik file when looking at debug. i have restartede traefik containr and my web-app container. It is still issueing self signed certificates.

I assume your custom certs are paid and contain the domain name. Check in the Traefik container (via cat <file>) and the logs that Traefik can read /etc/traefik/dynamic_conf.yml, /etc/certs/_.unord.dk.crt and /etc/certs/_.unord.dk.key. Config works for me.

You can set TLS global for websecure:

entryPoints:
  websecure:
    address: :443
    http:
      tls: true

You can try to add the certs as default, too:

tls:
  options:
    default:
      minVersion: VersionTLS12
  certificates:
    - certFile: /run/secrets/example.com.crt
      keyFile: /run/secrets/example.com.key
  stores:
    default:
      defaultCertificate:
        certFile: /run/secrets/example.com.crt
        keyFile: /run/secrets/example.com.key

I really wonder why you get no useful info from the Traefik debug logs.

If it's still not working, please post full files again.

My files are a such now:
traefik stack:

version: '3'

services:
  traefik:
    # The latest official supported Traefik docker image
    image: traefik:v2.9
    # Enables the Traefik Dashboard and tells Traefik to listen to docker
    # enable --log.level=INFO so we can see what Traefik is doing in the log files
    deploy:
      placement:
        constraints:
          - node.role==manager
    ports:
      # Exposes port 80 for incomming web requests
      - "80:80"
      - "443:443"
      # The Web UI port http://0.0.0.0:8080 (enabled by --api.insecure=true)
      - "8080:8080"
    networks:
      - public
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock
      - /home/robo/docker-volumes/traefik/traefik-yaml/traefik.yml:/etc/traefik/traefik.yml
      - /home/robo/docker-volumes/traefik/traefik-yaml/traefik.yml:/etc/traefik/dynamic_conf.yml
      - /home/robo/docker-volumes/cert:/etc/certs/

networks:
  public:
    external: true
    

traefik.yml:

################################################################
# API and dashboard configuration
################################################################
api:
  # Dashboard
  #
  #
  dashboard: true
  insecure: true

################################################################
# Docker configuration backend
################################################################
providers:
  file:
    filename: "/etc/traefik/dynamic_conf.yml"
    watch: true
  docker:
    watch: true
    exposedByDefault: false
    swarmMode: true

################################################################
# Traefik Logging
################################################################
log:
  level:DEBUG

################################################################
# Entrypoint
################################################################
entryPoints:
  web:
    address: ":80"
  websecure:
    address: ":443"
    http:
      tls: true

dynamic_conf.yml:

  ################################################################
# certificates
################################################################
tls:
  options:
    default:
      minVersion: VersionTLS12
  certificates:
      - certFile: /etc/certs/_.unord.dk.crt
        keyFile: /etc/certs/_.unord.dk.key
  stores:
    default:
      defaultCertificate:
        certFile: /etc/certs/_.unord.dk.crt
        keyFile: /etc/certs/_.unord.dk.key

my web-app stack:

version: '3.2'
services:
  web-app:
    image: robounord/sms-unord-django:v1.07
    container_name: sms-unord-django
    command: "python manage.py runserver 0.0.0.0:8000" 
    networks:
      - public
    deploy:
      labels:
       - "traefik.enable=true"
       - "traefik.port=public"
       - "traefik.http.routers.sendsms.rule=Host(`sendsms.unord.dk`)"
       - "traefik.http.routers.service=sendsms"
       - "traefik.http.services.sendsms.loadbalancer.server.port=8000"
       - "traefik.http.routers.sendsms.tls=true"
       - "traefik.http.routers.sendsms.entrypoints=websecure"

       
    volumes:
      - /home/robo/docker-volumes/sms-unord/code/sms-unord:/app
      - /home/robo/docker-volumes/cert:/etc/certs/
      
networks:
  public:
    external: true

I can confirm I can cd to my certificates and yml files in my traefik container

With the changes from your last past I finally got an error from traefik, but I don't know what they mean:

time="2023-01-26T12:50:04Z" level=info msg="Configuration loaded from file: /etc/traefik/traefik.yml"

time="2023-01-26T13:35:15Z" level=error msg="Error while Peeking first byte: read tcp 10.0.0.47:80->10.0.0.2:56056: read: connection timed out"

time="2023-01-26T13:45:05Z" level=error msg="Error while Peeking first byte: read tcp 10.0.0.47:80->10.0.0.2:45552: read: connection timed out"

time="2023-01-26T14:07:32Z" level=error msg="Error while Peeking first byte: read tcp 10.0.0.47:80->10.0.0.2:37008: read: connection timed out"

You mount a certs folder for your webapp, does it itself have a TLS-encrypted port 8000? I would recommend to go into your Traefik container and try a wget http and wget https to the IPs from (fresh) error messages.

The deploy section for your webapp is missing the replicas count, will those containers even be created?

Also check the Traefik dashboard at http://sendsms.unord.dk:8080/dashboard/. Note that this is currently set to public with insecure and no user/pass.

Remove all lines below # certificates in traefik.yml.

What's that? Did you mean network?

Here is your real bug :grin:

1 Like

Damn... sorry for my mistake. I was just code blind I guess

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.