Caddy with Docker

1. Caddy version (caddy version): caddy:2-alpine

2. How I run Caddy: Running in a docker container next to a service

a. System environment:

Docker

b. Command:

docker-compose up --force-recreate --build -d --remove-orphans

c. Service/unit/compose file:

version: '3'
networks:
   caddy:
      external: true
services:
   livekit:
      image: "livekit/livekit-server"
      restart: always
      environment:
         LIVEKIT_KEYS: "APImzH8pdMsUvj2: hMy34yUgIFRyDQhwQfUprjdDH5pvKzFV5jeZ9YXv5Il"
         dev: null
         node-ip: 23.95.166.25
      expose:
         - 7880
         - 8000-10000
      ports:
         - "7880:7880"
         - "7881:7881"
         - "7882:7882/udp"
      networks:
         - caddy
   caddy:
      image: caddy:2-alpine
      restart: unless-stopped
      ports:
         - "80:80"
         - "443:443"
      volumes:
         - /data/caddy/Caddyfile:/etc/caddy/Caddyfile
         - /data/caddy/data:/data
         - /data/caddy/config:/config
      networks:
         - caddy

d. My complete Caddyfile or JSON config:

{
    # Global options block. Entirely optional, https is on by default
    # Optional email key for lets encrypt
    email clark@clarkeverson.com
    #Optional staging lets encrypt for testing. Comment out for production.
    #acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}
video.clarkeverson.com {
    reverse_proxy localhost:7880
}

3. The problem I’m having:

I am trying to run the above docker file and get it to point to an https: domain. When I run the docker if i access the site via the ip it gives me an ok, but the service requires https to run

4. Error messages and/or full log output:

docker logs cb33976c3dca
{"level":"info","ts":1642094967.9332201,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"}
{"level":"warn","ts":1642094967.9352427,"msg":"input is not formatted with 'caddy fmt'","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":2}
{"level":"info","ts":1642094967.938082,"logger":"admin","msg":"admin endpoint started","address":"tcp/localhost:2019","enforce_origin":false,"origins":["localhost:2019","[::1]:2019","127.0.0.1:2019"]}
{"level":"info","ts":1642094967.938906,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc0000da1c0"}
{"level":"info","ts":1642094967.9390614,"logger":"http","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
{"level":"info","ts":1642094967.9391088,"logger":"http","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1642094967.9401004,"logger":"tls","msg":"cleaning storage unit","description":"FileStorage:/data/caddy"}
{"level":"info","ts":1642094967.9414263,"logger":"tls","msg":"finished cleaning storage units"}
{"level":"info","ts":1642094967.9415934,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["video.clarkeverson.com"]}
{"level":"info","ts":1642094967.942147,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1642094967.942166,"msg":"serving initial configuration"}
{"level":"info","ts":1642094967.9427993,"logger":"tls.obtain","msg":"acquiring lock","identifier":"video.clarkeverson.com"}
{"level":"info","ts":1642094967.946919,"logger":"tls.obtain","msg":"lock acquired","identifier":"video.clarkeverson.com"}
{"level":"info","ts":1642094968.372588,"logger":"tls.issuance.acme","msg":"waiting on internal rate limiter","identifiers":["video.clarkeverson.com"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":"clark@clarkeverson.com"}
{"level":"info","ts":1642094968.372696,"logger":"tls.issuance.acme","msg":"done waiting on internal rate limiter","identifiers":["video.clarkeverson.com"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":"clark@clarkeverson.com"}
{"level":"info","ts":1642094968.5554833,"logger":"tls.issuance.acme.acme_client","msg":"trying to solve challenge","identifier":"video.clarkeverson.com","challenge_type":"http-01","ca":"https://acme-v02.api.letsencrypt.org/directory"}
{"level":"info","ts":1642094968.797444,"logger":"tls.issuance.acme","msg":"served key authentication","identifier":"video.clarkeverson.com","challenge":"http-01","remote":"3.19.56.43:60014","distributed":false}
{"level":"info","ts":1642094968.9792392,"logger":"tls.issuance.acme","msg":"served key authentication","identifier":"video.clarkeverson.com","challenge":"http-01","remote":"34.219.87.132:24524","distributed":false}
{"level":"info","ts":1642094969.014632,"logger":"tls.issuance.acme","msg":"served key authentication","identifier":"video.clarkeverson.com","challenge":"http-01","remote":"18.192.36.99:46410","distributed":false}
{"level":"info","ts":1642094969.6384957,"logger":"tls.issuance.acme","msg":"served key authentication","identifier":"video.clarkeverson.com","challenge":"http-01","remote":"66.133.109.36:26328","distributed":false}
{"level":"info","ts":1642094969.915655,"logger":"tls.issuance.acme.acme_client","msg":"validations succeeded; finalizing order","order":"https://acme-v02.api.letsencrypt.org/acme/order/362756650/55090385910"}
{"level":"info","ts":1642094970.289824,"logger":"tls.issuance.acme.acme_client","msg":"successfully downloaded available certificate chains","count":2,"first_url":"https://acme-v02.api.letsencrypt.org/acme/cert/036f8216602f37e8f92b6fde848aad943f92"}
{"level":"info","ts":1642094970.2911155,"logger":"tls.obtain","msg":"certificate obtained successfully","identifier":"video.clarkeverson.com"}
{"level":"info","ts":1642094970.291148,"logger":"tls.obtain","msg":"releasing lock","identifier":"video.clarkeverson.com"}
{"level":"error","ts":1642095030.246662,"logger":"http.log.error","msg":"dial tcp 127.0.0.1:7880: connect: connection refused","request":{"remote_addr":"167.94.138.59:50682","proto":"HTTP/1.1","method":"GET","host":"video.clarkeverson.com","uri":"/","headers":{"User-Agent":["Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)"],"Accept":["*/*"],"Accept-Encoding":["gzip"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"","proto_mutual":true,"server_name":"video.clarkeverson.com"}},"duration":0.005500081,"status":502,"err_id":"jnf5242tm","err_trace":"reverseproxy.statusError (reverseproxy.go:886)"}
{"level":"error","ts":1642095030.3145401,"logger":"http.log.error","msg":"dial tcp 127.0.0.1:7880: connect: connection refused","request":{"remote_addr":"167.94.138.59:51924","proto":"HTTP/1.1","method":"GET","host":"video.clarkeverson.com","uri":"/","headers":{"Accept":["*/*"],"Accept-Encoding":["gzip"],"User-Agent":["Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"","proto_mutual":true,"server_name":"video.clarkeverson.com"}},"duration":0.00114496,"status":502,"err_id":"fpb68yjqn","err_trace":"reverseproxy.statusError (reverseproxy.go:886)"}
{"level":"error","ts":1642095032.8798296,"logger":"http.log.error","msg":"dial tcp 127.0.0.1:7880: connect: connection refused","request":{"remote_addr":"73.142.12.85:45708","proto":"HTTP/1.1","method":"GET","host":"video.clarkeverson.com","uri":"/rtc?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDQ2ODcwMDksImlzcyI6IkFQSW16SDhwZE1zVXZqMiIsImp0aSI6ImNsYXJrIiwibmJmIjoxNjQyMDk1MDA5LCJzdWIiOiJjbGFyayIsInZpZGVvIjp7InJvb20iOiJteXJvb20iLCJyb29tSm9pbiI6dHJ1ZX19.Qp3L3i4Va-1-m-QowL2balCjgZXdk0x6I-tg_nhiNb4&protocol=5&sdk=js&version=0.15.3","headers":{"Connection":["Upgrade"],"Pragma":["no-cache"],"User-Agent":["Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"],"Upgrade":["websocket"],"Origin":["https://example.livekit.io"],"Sec-Websocket-Version":["13"],"Accept-Encoding":["gzip, deflate, br"],"Accept-Language":["en-US,en;q=0.9"],"Sec-Websocket-Key":["poPia2An+hsjFzptUrWHcQ=="],"Cache-Control":["no-cache"],"Sec-Websocket-Extensions":["permessage-deflate; client_max_window_bits"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"","proto_mutual":true,"server_name":"video.clarkeverson.com"}},"duration":0.001300496,"status":502,"err_id":"uizhuznkz","err_trace":"reverseproxy.statusError (reverseproxy.go:886)"}
{"level":"error","ts":1642095033.026339,"logger":"http.log.error","msg":"dial tcp 127.0.0.1:7880: connect: connection refused","request":{"remote_addr":"73.142.12.85:45712","proto":"HTTP/2.0","method":"GET","host":"video.clarkeverson.com","uri":"/rtc/validate?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDQ2ODcwMDksImlzcyI6IkFQSW16SDhwZE1zVXZqMiIsImp0aSI6ImNsYXJrIiwibmJmIjoxNjQyMDk1MDA5LCJzdWIiOiJjbGFyayIsInZpZGVvIjp7InJvb20iOiJteXJvb20iLCJyb29tSm9pbiI6dHJ1ZX19.Qp3L3i4Va-1-m-QowL2balCjgZXdk0x6I-tg_nhiNb4&protocol=5&sdk=js&version=0.15.3","headers":{"Origin":["https://example.livekit.io"],"Sec-Fetch-Mode":["cors"],"Referer":["https://example.livekit.io/"],"Sec-Gpc":["1"],"Accept":["*/*"],"Sec-Fetch-Site":["cross-site"],"Sec-Fetch-Dest":["empty"],"Accept-Encoding":["gzip, deflate, br"],"Accept-Language":["en-US,en;q=0.9"],"User-Agent":["Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","proto_mutual":true,"server_name":"video.clarkeverson.com"}},"duration":0.001080132,"status":502,"err_id":"pkt7dfndn","err_trace":"reverseproxy.statusError (reverseproxy.go:886)"}
{"level":"error","ts":1642095116.6592171,"logger":"http.log.error","msg":"dial tcp 127.0.0.1:7880: connect: connection refused","request":{"remote_addr":"73.142.12.85:45714","proto":"HTTP/2.0","method":"GET","host":"video.clarkeverson.com","uri":"/","headers":{"Cache-Control":["max-age=0"],"Upgrade-Insecure-Requests":["1"],"Sec-Gpc":["1"],"Sec-Fetch-Site":["none"],"Sec-Fetch-Mode":["navigate"],"Sec-Fetch-Dest":["document"],"Accept-Language":["en-US,en;q=0.9"],"User-Agent":["Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"],"Sec-Fetch-User":["?1"],"Accept-Encoding":["gzip, deflate, br"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","proto_mutual":true,"server_name":"video.clarkeverson.com"}},"duration":0.001169885,"status":502,"err_id":"wsu35rzhw","err_trace":"reverseproxy.statusError (reverseproxy.go:886)"}
{"level":"error","ts":1642095128.4322267,"logger":"http.log.error","msg":"dial tcp 127.0.0.1:7880: connect: connection refused","request":{"remote_addr":"179.43.169.181:57462","proto":"HTTP/1.1","method":"GET","host":"video.clarkeverson.com","uri":"/","headers":{"User-Agent":["Mozilla/5.0 (X11; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"","proto_mutual":true,"server_name":"video.clarkeverson.com"}},"duration":0.000954797,"status":502,"err_id":"tj0gf0a0z","err_trace":"reverseproxy.statusError (reverseproxy.go:886)"}

5. What I already tried:

So i attempted to remove caddy to see if i could get the service working but then it gives an unsecure message. I have also reached out to the people that make the livekit tool but they don’t have caddy experience. This is my first attempt at docker compose

6. Links to relevant resources: Getting Started | docs

You’re using localhost here, but you’re running in Docker. localhost will try to connect to something inside of the same container, but livekit is running in another container.

Proxy to livekit:7880 instead. Docker has a DNS resolver built-in which makes this work – the docker-compose service names are usable as hostnames.