How can I format v1 Caddyfile to v2 Caddyfile?

1. Caddy version (caddy version):

v2.1.1

2. How I run Caddy:

caddy run --config caddyfile

a. System environment:

Arch Linux 5.7.8

b. My complete Caddyfile or JSON config:

epliar.com

root * /home/epi/website/public
encode gzip
header {
  Strict-Transport-Security max-age=31536000; includeSubDomains; preload;
}

3. The problem I’m having:

{"config_file": "caddyfile", "config_adapter": ""} run: loading initial config: decoding request body: invalid character 'e' looking for beginning of value

On caddy v1,original caddyfile is:

https://epliar.com {
    gzip
    log /home/epi/website/log
    root /home/epi/website/public
    header / {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
    }
}

Is my grammar wrong? Or is it something else? The documentation doesn’t give the full caddyfile.

Caddy expects files using Caddyfile syntax to start with Caddyfile, with the uppercase C to assume that it is a Caddyfile config, otherwise it assumes it’s JSON.

Your options are to either rename your file from caddyfile to Caddyfile, or also specify the --adapter caddyfile CLI argument:

1 Like

Edit: Derp, I read too fast, I read your Caddy v1 config and skimmed past your Caddy v2 config :man_facepalming:

Ignore the following, but leaving it in because :man_shrugging:


Oh also, you’ll have a few syntax issues with your Caddyfile due to differences between v1 and v2.

Caddy will parse the first argument for root as being a path matcher because it starts with /. Instead, you’ll need to put a * as the first argument to root to avoid that issue.

root * /home/epi/website/public

Also, in general, path matching in Caddy v2 is exact-match, so the matcher / for the header directive will only match requests to / and not /foo. You can simply omit the / for Caddy to assume *, meaning “all requests”.

And finally, the log directive does not work the same way as in Caddy v1. Please refer to the docs for this one.

The upgrade guide covers all this information:

Scratch most of the above comment… but… there is a problem with your header directive. I’ll want to wrap the header value in quotes so that Caddy parses the value as a single token.

Should be:

header {
  Strict-Transport-Security "max-age=31536000; includeSubDomains; preload;"
}
2 Likes

This is a Caddyfile before I edit it. Is there any error?

{
    email e@epliar.com
}
https://epliar.com {
    encode gzip
    root * /home/epi/website/public
    log {
      output file         /home/epi/website/log
      format single_field common_log
    }
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
    }
}

The ; needs to be inside the quotes, not outside.

Otherwise, looks okay to me!

But it still failed on run.

2020/07/16 05:28:14.565	INFO	using provided configuration	{"config_file": "Caddyfile", "config_adapter": ""}
run: loading initial config: loading new config: starting caddy administration endpoint: listen tcp: lookup localhost on 8.8.8.8:53: no such host

DNS :b:roke

(For some reason, your system is not resolving localhost to 127.0.0.1 and is redirecting queries for localhost to 8.8.8.8, which is Google’s public resolver! You will need to address this abnormal behaviour in order for Caddy to run properly.)

2 Likes

Now, it won’t exit automatically.

But there is a new problem, it has encountered problems in applying for a ssl certificate.

There are some useful log (maybe)

2020/07/16 06:50:36 http: TLS handshake error from 127.0.0.1:54670: EOF
2020/07/16 06:50:37 http: TLS handshake error from 127.0.0.1:54672: EOF
2020/07/16 06:50:41 [ERROR] error: one or more domains had a problem:
[dfrt.epliar.com] acme: error: 403 :: urn:ietf:params:acme:error:unauthorized :: Cannot negotiate ALPN protocol "acme-tls/1" for tls-alpn-01 challenge, url:
2020/07/16 06:50:41 [INFO] Deactivating auth: https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/78077916
2020/07/16 06:50:42 [INFO] Unable to deactivate the authorization: https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/78077916
2020/07/16 06:50:42 [ERROR] error: one or more domains had a problem:
[epliar.com] acme: error: 403 :: urn:ietf:params:acme:error:unauthorized :: Cannot negotiate ALPN protocol "acme-tls/1" for tls-alpn-01 challenge, url:

Am I missing some of the settings?

{
    email e@epliar.com
    acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}
https://epliar.com {
    reverse_proxy localhost:9999
    encode gzip
    root * /home/epi/website/public
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload;"
    }
}

https://dfrt.epliar.com {
    encode gzip
    root * /home/epi/website/dfrt
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload;"
    }
}

This means that LetsEncrypt tried to challenge Caddy via ALPN (essentially some additional negotiation that happens while TLS is being established) but couldn’t.

This pretty much only ever happens if there’s something in front of Caddy terminating TLS - like an additional proxy layer. If LetsEncrypt is talking directly to Caddy, TLS-ALPN challenges generally Just Work™️.

Maybe there is something wrong and I couldn’t solve it. Thank you.

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