# How to renew / update user-defined (custom) certificates

**URL:** https://community.traefik.io/t/how-to-renew-update-user-defined-custom-certificates/20598
**Category:** Traefik v2
**Tags:** docker, docker-swarm
**Created:** [November 28, 2023, 1:57pm UTC](https://community.traefik.io/t/how-to-renew-update-user-defined-custom-certificates/20598 "2023-11-28T13:57:16Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![YuryHrytsuk](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/yuryhrytsuk/32/7717_2.png) [@YuryHrytsuk](https://community.traefik.io/u/YuryHrytsuk)
#### Post date: [November 28, 2023, 1:57pm UTC](https://community.traefik.io/t/how-to-renew-update-user-defined-custom-certificates/20598/1 "2023-11-28T13:57:16Z")

</div>

I want to switch to user-defined certificates. Every 3 months I will manually renew certificates with [Lego](https://go-acme.github.io/lego/) and then I want to feed them to traefik. How to do that?

Will updating certificate files in a volume with certificates suffice? Do I need to restart traefik?

P.S. this only involves update / renew already existing certificates.

---

<div class="post-metadata">

### Author: ![ldez](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/ldez/32/5_2.png) [@ldez](https://community.traefik.io/u/ldez)
#### Post date: [November 28, 2023, 3:21pm UTC](https://community.traefik.io/t/how-to-renew-update-user-defined-custom-certificates/20598/2 "2023-11-28T15:21:30Z")

</div>

Hello,

this means you are using the file provider to handle the certificates.  
if your certificate definitions don't change inside the configuration, you just have to do a `touch` on the configuration file that contains the certificate definitions. You don't need to restart.

---

<div class="post-metadata">

### Author: ![YuryHrytsuk](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/yuryhrytsuk/32/7717_2.png) [@YuryHrytsuk](https://community.traefik.io/u/YuryHrytsuk)
#### Post date: [December 1, 2023, 1:36pm UTC](https://community.traefik.io/t/how-to-renew-update-user-defined-custom-certificates/20598/3 "2023-12-01T13:36:00Z")

</div>

It does NOT work. Let me describe what I do:

I run traefik in `docker swarm`. I am testing if traefik will update configuration in case of changes. The changes I do is renaming the certificates files to check if `traefik` will switch to a default certificate. After the renaming the certificates file on localhost which is mounted via volumes (e.g. from `/etc/traefik_certs/<domain>.crt` --\> `/etc/traefik_certs/<domain>.crt.moved`) and `touch`ing the dynamic config file (`./config/master_dyn_cfg.yml`) nothing changes. The traefik still serves the (non-default) certificates.

[more context]  
In fact only `docker stack rm` + `docker stack deploy` make traefik see the changes and start serving the default certificate (since the certificate path were deliberately changed to make dynamic config wrong).

[more context]  
The files are mounted correctly via volumes and I can see all the changes inside the containers (both certificates renaming and dynamic config file timestamps are updated)

traefik docker compose file:

```yaml
version: "3.7"
services:
  traefik:
    command:
    - --api=true
    - --api.dashboard=true
    - --log.level=DEBUG
    - --metrics.prometheus=true
    - --metrics.prometheus.addEntryPointsLabels=true
    - --metrics.prometheus.addServicesLabels=true
    - --entryPoints.metrics.address=:8082
    - --metrics.prometheus.entryPoint=metrics
    - --entryPoints.http.address=:80
    - --entryPoints.https.address=:443
    - --entryPoints.master_postgres.address=:5432
    - --entryPoints.smtp.address=:25
    - --providers.docker.endpoint=unix:///var/run/docker.sock
    - --providers.docker.swarmMode=true
    - --providers.docker.exposedByDefault=false
    - --tracing=true
    - --tracing.jaeger=true
    - --tracing.jaeger.samplingServerURL=http://jaeger:5778/sampling
    - --tracing.jaeger.localAgentHostPort=jaeger:6831
    - --providers.docker.constraints=!LabelRegex(...)
    - --entryPoints.https.forwardedHeaders.insecure
    - --providers.file.filename=/etc/traefik/dynamic_cfg.yml
    deploy:
      replicas: 1
      labels:
        ...
      resources:
        limits:
          cpus: "3.000"
          memory: "2147483648"
        reservations:
          cpus: "1.000"
          memory: "524288000"
      placement:
        constraints:
        - node.role == manager
        - node.labels.traefik==true
    environment:
      ...
    image: traefik:v2.10.4
    init: true
    networks:
      monitored: null
      public: null
    ports:
    - mode: host
      target: 80
      published: 80
    - mode: host
      target: 443
      published: 443
    - mode: host
      target: 5432
      published: 5432
    - mode: host
      target: 5433
      published: 5433
    volumes:
    - type: bind
      source: .../traefik/config/master_dyn_cfg.yml
      target: /etc/traefik/dynamic_cfg.yml
      bind:
        create_host_path: true
    - type: bind
      source: /etc/traefik_certs
      target: /etc/traefik_certs
      bind:
        create_host_path: true
    - type: bind
      source: /var/run/docker.sock
      target: /var/run/docker.sock
      bind:
        create_host_path: true
  whoami:
    deploy:
      labels:
        traefik.docker.network: public-network
        traefik.enable: "true"
        traefik.http.routers.whoami.entrypoints: https
        traefik.http.routers.whoami.middlewares: ops_whitelist_ips@docker, ops_auth@docker,
          ops_gzip@docker
        traefik.http.routers.whoami.rule: Host(`<domain>`)
          && PathPrefix(`/whoami`)
        traefik.http.routers.whoami.tls: "true"
        traefik.http.services.whoami.loadbalancer.server.port: "80"
      resources:
        limits:
          cpus: "0.5"
          memory: "52428800"
        reservations:
          cpus: "0.1"
          memory: "6291456"
    image: containous/whoami
    networks:
      public: null
networks:
  monitored:
    name: monitored_network
    external: true
  public:
    name: public-network
    external: true

```

./config/master\_dyn\_cfg.yml

```yaml
tls:
  certificates:
    - certFile: /etc/traefik_certs/<domain>.crt
      keyFile: /etc/traefik_certs/<domain>.key

```

`/etc/traefik_certs` contains the certificates listed in `./config/master_dyn_cfg.yml`.

---

<div class="post-metadata">

### Author: ![ldez](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/ldez/32/5_2.png) [@ldez](https://community.traefik.io/u/ldez)
#### Post date: [December 1, 2023, 2:45pm UTC](https://community.traefik.io/t/how-to-renew-update-user-defined-custom-certificates/20598/4 "2023-12-01T14:45:00Z")

</div>

You have to replace:

> [@YuryHrytsuk](#):
>
> `--providers.file.filename`

by `--providers.file.directory` (and use a directory instead of a file)

because `filename` has a problem on some filesystems to detect changes.

> **[Traefik File Documentation - Traefik](https://doc.traefik.io/traefik/providers/file/#directory)**
>
> The file provider in Traefik Proxy lets you define the dynamic configuration in a YAML or TOML file. Read the technical documentation.

---

<div class="post-metadata">

### Author: ![bluepuma77](https://avatars.discourse-cdn.com/v4/letter/b/a9adbd/32.png) [@bluepuma77](https://community.traefik.io/u/bluepuma77)
#### Post date: [December 1, 2023, 3:17pm UTC](https://community.traefik.io/t/how-to-renew-update-user-defined-custom-certificates/20598/5 "2023-12-01T15:17:17Z")

</div>

And don't forget to enable `watch` ([doc](https://doc.traefik.io/traefik/providers/file/#watch))

---

<div class="post-metadata">

### Author: ![YuryHrytsuk](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/yuryhrytsuk/32/7717_2.png) [@YuryHrytsuk](https://community.traefik.io/u/YuryHrytsuk)
#### Post date: [December 1, 2023, 4:08pm UTC](https://community.traefik.io/t/how-to-renew-update-user-defined-custom-certificates/20598/6 "2023-12-01T16:08:31Z")

</div>

So, the final solution that make `traefik` dynamically update certificates is as follows:

1. you must use `providers.file.directory` instead of `providers.file.filename`
2. you must use `providers.file.watch=true`
3. to trigger traefik update you must touch the `dynamic config` or the mounted directory itself

**docker-compose.yml**

```yaml
version: '3.7'
services:
  traefik:
    command:
      ...
      - "--providers.file.directory=/etc/traefik/"
      - "--providers.file.watch=true"
    env_file:
      - .env
    volumes:
    - /etc/traefik_certs:/etc/traefik_certs
    - ./config/master/:/etc/traefik/

```

**./config/master/dynamic\_config.yml**

```yaml
tls:
  certificates:
    - certFile: /etc/traefik_certs/<domain>.crt
      keyFile: /etc/traefik_certs/<domain>.key

```

I will attach a good guide here. It has one flaw: it doesn't mention that you must `touch` dynamic config to trigger traefik to update certificates. The guide: [Traefik Proxy 2.x and TLS 101 [Updated 2022] | Traefik Labs](https://traefik.io/blog/traefik-2-tls-101-23b4fbee81f1/)

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex020/uploads/containo/original/2X/b/bd81ebdb578656e76e56ff3cc3eed021d3ba132d.png) [@system](https://community.traefik.io/u/system)
#### Post date: [December 4, 2023, 4:08pm UTC](https://community.traefik.io/t/how-to-renew-update-user-defined-custom-certificates/20598/7 "2023-12-04T16:08:56Z")

</div>

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