Caddy can't find cerificates

Hello, I’m trying to set up vaultwarden with caddy. I have generated SSL keys with lego from GoDaddy. Logs say that no such file or directory :frowning:
Logs:

caddy        | {"level":"info","ts":1659433276.6507158,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"}
caddy        | {"level":"warn","ts":1659433276.6526322,"msg":"Caddyfile input is not formatted; run the 'caddy fmt' command to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":2}
caddy        | {"level":"info","ts":1659433276.6537828,"logger":"admin","msg":"admin endpoint started","address":"tcp/localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
caddy        | {"level":"info","ts":1659433276.6543276,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc0005eafc0"}
caddy        | {"level":"info","ts":1659433276.6546295,"logger":"tls.cache.maintenance","msg":"stopped background certificate maintenance","cache":"0xc0005eafc0"}
caddy        | run: loading initial config: loading new config: loading http app module: provision http: getting tls app: loading tls app module: provision tls: loading certificates: open /opt/vaultwarden/.lego/certificates/vw.example.club.crt: no such file or directory

Here’s my Caddyfile:

{$DOMAIN}:443 {
  log {
    level INFO
    output file {$LOG_FILE} {
      roll_size 10MB
      roll_keep 10
    }
  }

  # Get a cert by using the ACME HTTP-01 challenge.
  tls {$SSL_CERT_PATH} {$SSL_KEY_PATH}

  encode gzip

  # Headers to improve security.
  header {
  # Enable HSTS
  Strict-Transport-Security "max-age=31536000;"

  # Enable cross-site filter (XSS)
  X-XSS-Protection "1; mode=block"

  # Disallow the site to be rendered within a frame (clickjacking protection)
  X-Frame-Options "DENY"

  # Prevent search engines from indexing
  X-Robots-Tag "none"

  # Remove Caddy branding
  -Server
  }

  # Redirect notifications to the WebSocket.
  reverse_proxy /notifications/hub vaultwarden:3012

  reverse_proxy vaultwarden:80 {
       header_up X-Real-IP {remote_host}
  }
}

Here’s my docker-compose file:

 version: '3'

services:
  bitwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: always
    environment:
      WEBSOCKET_ENABLED: "true"
      SIGNUPS_ALLOWED: "true"
      DOMAIN: https://vw.example.club
      SMTP_HOST: smtp.gmail.com
      SMTP_FROM: example@gmail.com
      SMTP_PORT: 587
      SMTP_SECURITY: force_tls
      SMTP_USERNAME: example@gmail.com
      SMTP_PASSWORD: Example!
      ADMIN_TOKEN: example

    volumes:
      - ./bw-data:/data

  caddy:
    image: caddy:latest
    container_name: caddy
    restart: always
    ports:
      - 80:80  # Needed for the ACME HTTP-01 challenge.
      - 443:443
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./caddy-config:/config
      - ./caddy-data:/data
      - .lego/certificates:/etc/ssl
    environment:
      DOMAIN: https://vw.example.club
      EMAIL: example@gmail.com       # The email address to use for ACME registration.
      LOG_FILE: /data/access.log
      SSL_CERT_PATH: /opt/vaultwarden/.lego/certificates/vw.example.club.crt
      SSL_KEY_PATH: /opt/vaultwarden/.lego/certificates/vw.example.club.key

Hi :wave:

Host paths aren’t available in Docker containers.
That’s why one has the ability to manually specify volumes: []
The “short-syntax” in Docker-Compose goes something like

volumes:
 - $volumeOrHostPath:$PathInContainer

So in your case:

Your local host directory ./.lego/certificates mounted as /etc/ssl not /opt/vaultwarden/.lego/certificates in the container.

So you will have to fix your environment vars:

    environment:
        SSL_CERT_PATH: /etc/ssl/vw.example.club.crt
        SSL_KEY_PATH: /etc/ssl/vw.example.club.key
2 Likes

thanks a lot for your answer, I’ve tried to edit the config file but doesn’t help :frowning:

    volumes:
       - ./Caddyfile:/etc/caddy/Caddyfile:ro
       - ./caddy-config:/config
       - ./caddy-data:/data
       - .lego/certificates:/etc/ssl
     environment:
       DOMAIN: https://vw.example.club
       EMAIL: example@gmail.com       # The email address to use for ACME registration.
       LOG_FILE: /data/access.log
       SSL_CERT_PATH: "/etc/ssl/vw.example.club.crt"
       SSL_KEY_PATH: "/etc/ssl/vw.example.club.key"

Did you run docker-compose up -d after changing your docker-compose.yml to apply your changes?
What errors are you currently getting?

I can’t tell how your ./.lego/certificates directory looks like, because you didn’t share that information.
You can use docker exec -it caddy ash to enter the container (assuming it’s running).

From there, you can do things like ls -la /etc/ssl to confirm your files are actually where you would expect them to be.

You could also just remove the tls {$SSL_CERT_PATH} {$SSL_KEY_PATH} line in your Caddyfile.

Caddy will then issue a new certificate and automatically renews it when needed.

sorry, here’s the directory tree:

root@vaultwarden:/opt/vaultwarden# tree .lego
.lego
├── accounts
│   └── acme-v02.api.letsencrypt.org
│       ├── example@gmail.com
│          ├── account.json
│          └── keys
│            └── example@gmail.com.key
│  
└── certificates
    ├── vw.example.club.crt
    ├── vw.example.club.issuer.crt
    ├── vw.example.club.json
    └── vw.example.club.key

this helped me, i’ve changed this to tls {$EMAIL} and restarted docker compose, now it opens in the browser with SSL properly, I do appreciate your help! thanks!

1 Like