Simple Caddy2 Setup

1. Caddy version (caddy version):

Version 2.2.1

2. How I run Caddy:

Ubuntu 20.04 in Docker using custom image to include duckdns DNS challenge

a. System environment:

Ubuntu 20.04 in Docker

b. Command:

Dockerfile:

FROM caddy:2.2.1-builder-alpine AS builder

RUN xcaddy build \
    --with github.com/caddy-dns/duckdns

FROM caddy:2.2.1-alpine

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

c. Service/unit/compose file:

version: "3"
services:
  caddy:
    container_name: caddy
    image: custom/caddy2:2.2.1
    environment:
      - TZ=America/Chicago
      - ACME_AGREE=true
    volumes:
      - $PWD/caddyfile:/etc/caddy/Caddyfile
      - $PWD/caddy_data:/data
      - $PWD/caddy_config:/config
    restart: unless-stopped

d. My complete Caddyfile or JSON config:

router.example.duckdns.org {
 reverse_proxy 10.0.10.250.:5800
 tls {
   dns duckdns {env.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
 }
 log {
   output file $PWD/caddy.log
 }
}

3. The problem I’m having:

I am unable to reach the host. I am trying to use Caddy to access 2 different types of services.

  1. Webpages running in docker on the server. This server is the same place where Caddy is running
  2. Webpages running outside of the server e.g. router

4. Error messages and/or full log output:

{"level":"info","ts":1613184206.7064419,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"}
{"level":"info","ts":1613184206.709996,"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":1613184206.711087,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000398e70"}
{"level":"info","ts":1613184206.7111785,"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":1613184206.711202,"logger":"http","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1613184206.7117474,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["router.example.duckdns.org"]}
{"level":"info","ts":1613184206.7127964,"msg":"autosaved config","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1613184206.7128134,"msg":"serving initial configuration"}
{"level":"info","ts":1613184206.714057,"logger":"tls.obtain","msg":"acquiring lock","identifier":"router.example.duckdns.org"}
{"level":"info","ts":1613184206.71545,"logger":"tls.obtain","msg":"lock acquired","identifier":"router.example.duckdns.org"}
{"level":"info","ts":1613184206.7198553,"logger":"tls","msg":"cleaned up storage units"}
{"level":"info","ts":1613184206.7255352,"logger":"tls.issuance.acme","msg":"waiting on internal rate limiter","identifiers":["router.example.duckdns.org"]}
{"level":"info","ts":1613184206.725569,"logger":"tls.issuance.acme","msg":"done waiting on internal rate limiter","identifiers":["router.example.duckdns.org"]}
{"level":"info","ts":1613184207.7788768,"logger":"tls.issuance.acme.acme_client","msg":"trying to solve challenge","identifier":"router.example.duckdns.org","challenge_type":"dns-01","ca":"https://acme-v02.api.letsencrypt.org/directory"}
{"level":"error","ts":1613184208.8024192,"logger":"tls.issuance.acme.acme_client","msg":"cleaning up solver","identifier":"router.example.duckdns.org","challenge_type":"dns-01","error":"no memory of presenting a DNS record for router.example.duckdns.org (probably OK if presenting failed)"}
{"level":"error","ts":1613184208.9209912,"logger":"tls.obtain","msg":"will retry","error":"[router.example.duckdns.org] Obtain: [router.example.duckdns.org] solving challenges: presenting for challenge: adding temporary record for zone duckdns.org.: DuckDNS request failed, expected (OK) but got (KO), url: [https://www.duckdns.org/update?domains=puldal.duckdns.org&token=&txt=7QCQ1ZKq8K5FflkfeaikEbfWGK-WkdCegM-dFjcUPN4&verbose=true], body: KO (order=https://acme-v02.api.letsencrypt.org/acme/order/112606271/7875550488) (ca=https://acme-v02.api.letsencrypt.org/directory)","attempt":1,"retrying_in":60,"elapsed":2.205521407,"max_duration":2592000}

5. What I already tried:

I have tried to search for sample configuration.

Please upgrade to Caddy v2.3.0!

I don’t see a port 80/443 binding on your container. Did you forget that?

You don’t need this for Caddy v2 anymore. The ACME agreement is implicit by using Caddy at all.

You have an extra . in there.

Caddy doesn’t expand $PWD for you. Change it to ./caddy.log maybe. But note that the PWD inside of the container is /srv which is not usually where you want your log files to go.

Looks like duckdns rejected your request, likely because it couldn’t authenticate.

Did you set an environment variable when running your container?

I think you may have misunderstood what you were meant to do here. In the docs, it says to use {env.DUCKDNS_API_TOKEN}. This means that you should put that in your config, then set an environment variable called DUCKDNS_API_TOKEN to the value of your API token. You shouldn’t literally replace DUCKDNS_API_TOKEN with your actual token, because then when Caddy sees {env.<your actual token>} it will be looking for an environment variable called <your actual token> which will not exist.

1 Like

Done!

Fixed.

Removed.

Was a typo when I moved my config here but thanks.

Tried /var/log but it won’t write there maybe because of permission.

You are right. I fixed it. I do get a success with certificates but I am still getting errors.

Now:
When trying to access a service on the same host as Caddy:

{"level":"error","ts":1613187996.7787504,"logger":"http.log.error.log0","msg":"dial tcp 10.0.10.250:5800: i/o timeout","request":{"remote_addr":"10.0.10.45:57461","proto":"HTTP/2.0","method":"GET","host":"example.duckdns.org","uri":"/","headers":{"Dnt":["1"],"Upgrade-Insecure-Requests":["1"],"Te":["trailers"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"],"Accept-Language":["en-US,en;q=0.5"],"Accept-Encoding":["gzip, deflate, br"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","proto_mutual":true,"server_name":"example.duckdns.org"}},"duration":10.003052581,"status":502,"err_id":"82e93yhab","err_trace":"reverseproxy.statusError (reverseproxy.go:783)"}

Or when accessing a service that is on another host:

{"level":"error","ts":1613189162.164139,"logger":"http.log.error.log0","msg":"x509: cannot validate certificate for 10.0.10.1 because it doesn't contain any IP SANs","request":{"remote_addr":"10.0.10.45:58235","proto":"HTTP/2.0","method":"GET","host":"example.duckdns.org","uri":"/","headers":{"Accept-Language":["en-US,en;q=0.5"],"Accept-Encoding":["gzip, deflate, br"],"Dnt":["1"],"Upgrade-Insecure-Requests":["1"],"Te":["trailers"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","proto_mutual":true,"server_name":"example.duckdns.org"}},"duration":0.211937787,"status":502,"err_id":"1dwnzaz9h","err_trace":"reverseproxy.statusError (reverseproxy.go:783)"}

FYI, I am updating my Caddyfile accordingly for each service

example.duckdns.org {
 reverse_proxy https://10.0.10.1
 tls {
   dns duckdns {env.DUCKDNS_API_TOKEN}
 }
 log {
   output file /var/log/caddy.log
 }
}

or reverse_proxy 10.0.10.250:5800

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.