Docker seems to cache Caddyfile

I have installed docker 26.1.5+dfsg1 and trying to install the frankenphp image which includes Caddy.
But I figured out, that I always get the same warning about /etc/frankenphp/Caddyfile. I changed a lot in Caddyfile, the warning is always the same. Last I have renamed Caddyfile to xCaddyfilex, the warning is always the same.
So I believe that this file seems to br cached, when it always show the same warning even the file not longer exist.

georg@hpradio1:~$ docker run -p 80:80 -p 443:443 -v $PWD:/app dunglas/frankenphp
{"level":"info","ts":1765790016.298575,"msg":"maxprocs: Leaving GOMAXPROCS=4: CPU quota undefined"}
{"level":"info","ts":1765790016.2987885,"msg":"GOMEMLIMIT is updated","package":"github.com/KimMachineGun/automemlimit/memlimit","GOMEMLIMIT":7499999232,"previous":9223372036854775807}
{"level":"info","ts":1765790016.2989192,"msg":"using config from file","file":"/etc/frankenphp/Caddyfile"}
{"level":"warn","ts":1765790016.2990096,"msg":"No files matching import glob pattern","pattern":"Caddyfile.d/*.caddyfile"}
{"level":"info","ts":1765790016.3003488,"msg":"adapted config to JSON","adapter":"caddyfile"}
{"level":"warn","ts":1765790016.3003647,"msg":"Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies","adapter":"caddyfile","file":"/etc/frankenphp/Caddyfile","line":5}
{"level":"info","ts":1765790016.3303647,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
{"level":"info","ts":1765790016.33072,"logger":"http.auto_https","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":1765790016.3307493,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1765790016.3308015,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000465080"}
{"level":"info","ts":1765790016.3310869,"logger":"pki.ca.local","msg":"root certificate trust store installation disabled; unconfigured clients may show warnings","path":"storage:pki/authorities/local/root.crt"}
{"level":"info","ts":1765790016.3312361,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
{"level":"info","ts":1765790016.3313773,"msg":"failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 7168 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details."}
{"level":"info","ts":1765790016.3315046,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
{"level":"warn","ts":1765790016.3315735,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
{"level":"warn","ts":1765790016.3315833,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
{"level":"info","ts":1765790016.3315861,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
{"level":"info","ts":1765790016.3315895,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["localhost"]}
{"level":"info","ts":1765790016.3351142,"logger":"tls.obtain","msg":"acquiring lock","identifier":"localhost"}
{"level":"info","ts":1765790016.3373432,"logger":"tls","msg":"cleaning storage unit","storage":"FileStorage:/data/caddy"}
{"level":"info","ts":1765790016.3398829,"logger":"tls.obtain","msg":"lock acquired","identifier":"localhost"}
{"level":"info","ts":1765790016.3399513,"logger":"tls.obtain","msg":"obtaining certificate","identifier":"localhost"}
{"level":"info","ts":1765790016.342669,"logger":"tls","msg":"finished cleaning storage units"}
{"level":"info","ts":1765790016.3507185,"logger":"tls.obtain","msg":"certificate obtained successfully","identifier":"localhost","issuer":"local"}
{"level":"info","ts":1765790016.3507931,"logger":"tls.obtain","msg":"releasing lock","identifier":"localhost"}
{"level":"warn","ts":1765790016.3511708,"logger":"tls","msg":"stapling OCSP","identifiers":["localhost"]}
{"level":"info","ts":1765790016.3678062,"logger":"frankenphp","msg":"FrankenPHP started 🐘","php_version":"8.5.0","num_threads":8,"max_threads":8}
{"leve`georg@hpradio1:~$ docker run -p 80:80 -p 443:443 -v $PWD:/app dunglas/frankenphp
{"level":"info","ts":1765790016.298575,"msg":"maxprocs: Leaving GOMAXPROCS=4: CPU quota undefined"}
{"level":"info","ts":1765790016.2987885,"msg":"GOMEMLIMIT is updated","package":"github.com/KimMachineGun/automemlimit/memlimit","GOMEMLIMIT":7499999232,"previous":9223372036854775807}
{"level":"info","ts":1765790016.2989192,"msg":"using config from file","file":"/etc/frankenphp/Caddyfile"}
{"level":"warn","ts":1765790016.2990096,"msg":"No files matching import glob pattern","pattern":"Caddyfile.d/*.caddyfile"}
{"level":"info","ts":1765790016.3003488,"msg":"adapted config to JSON","adapter":"caddyfile"}
{"level":"warn","ts":1765790016.3003647,"msg":"Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies","adapter":"caddyfile","file":"/etc/frankenphp/Caddyfile","line":5}
{"level":"info","ts":1765790016.3303647,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
{"level":"info","ts":1765790016.33072,"logger":"http.auto_https","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":1765790016.3307493,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1765790016.3308015,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000465080"}
{"level":"info","ts":1765790016.3310869,"logger":"pki.ca.local","msg":"root certificate trust store installation disabled; unconfigured clients may show warnings","path":"storage:pki/authorities/local/root.crt"}
{"level":"info","ts":1765790016.3312361,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
{"level":"info","ts":1765790016.3313773,"msg":"failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 7168 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details."}
{"level":"info","ts":1765790016.3315046,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
{"level":"warn","ts":1765790016.3315735,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
{"level":"warn","ts":1765790016.3315833,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
{"level":"info","ts":1765790016.3315861,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
{"level":"info","ts":1765790016.3315895,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["localhost"]}
{"level":"info","ts":1765790016.3351142,"logger":"tls.obtain","msg":"acquiring lock","identifier":"localhost"}
{"level":"info","ts":1765790016.3373432,"logger":"tls","msg":"cleaning storage unit","storage":"FileStorage:/data/caddy"}
{"level":"info","ts":1765790016.3398829,"logger":"tls.obtain","msg":"lock acquired","identifier":"localhost"}
{"level":"info","ts":1765790016.3399513,"logger":"tls.obtain","msg":"obtaining certificate","identifier":"localhost"}
{"level":"info","ts":1765790016.342669,"logger":"tls","msg":"finished cleaning storage units"}
{"level":"info","ts":1765790016.3507185,"logger":"tls.obtain","msg":"certificate obtained successfully","identifier":"localhost","issuer":"local"}
{"level":"info","ts":1765790016.3507931,"logger":"tls.obtain","msg":"releasing lock","identifier":"localhost"}
{"level":"warn","ts":1765790016.3511708,"logger":"tls","msg":"stapling OCSP","identifiers":["localhost"]}
{"level":"info","ts":1765790016.3678062,"logger":"frankenphp","msg":"FrankenPHP started 🐘","php_version":"8.5.0","num_threads":8,"max_threads":8}
{"level":"info","ts":1765790016.3739095,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1765790016.3739412,"msg":"serving initial configuration"}
`l":"info","ts":1765790016.3739095,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1765790016.3739412,"msg":"serving initial configuration"}

The used docker run instraction is shown on the beginng of the console output.
What I have to do that docker is not using cached files lich Caddyfile.
Thanks for your support!

I assume you mount the Caddyfile from the host to the container. Docker will not cache those files. If you see a file in the container, that is either mounted from the host or it is generated in the container or coming from the base image. You mount the current directory to /app in the container, but the Caddyfile in the log is under /etc, not /app.

If the Caddyfile is in the image, you either need to rebuild your image with a new Caddyfile, or mount one from your host to the path in the log.

By the way

This looks like Docker installed from the repository of the Linux distribution, not from Docker’s official APT repository. That one is not supported by Docker, but the maintainer of the Linux distribution.

I run this image from frankenphp and the Caddyfile is placed from frankenphp.
What is your prosal, remove docker and install a new version from docker?

In general, especially when you want to be able to report bugs to Docker’s official github repositories, or ask help from Docker support, the official Docker from the documentation is recommended.

Both are based on the ā€œMobyā€ project (GitHub - moby/moby: The Moby Project - a collaborative project for the container ecosystem to assemble container-based systems), but we don’t know what they change, but diffently they build the binary from source, and can have different supported versions. For example official Docker is at v29 now. You can use the one from the maintainers of the Linux distribution, but we weill mostly be able to help with the official one and whenever you notice a bug, we will ask you to try it with an official Docker installation to confirm it is a Docker bug and doesn’t come from a custom build.

Regrding your issue, it looks like a general issue with using Docker, so you will need to mount a Caddyfile to where Caddy expects it to be. Or run Caddy in a way so it looks for your file under /app (if you mounted it to there)

Hi @rimelek thank you. I have deleted the the old version and now installed 29.1.3.
I have installed the Caddyfile and still get the same warnings.
I think there are frankenphp somewhere stored. How I can remove it?

Where did you change it? I hope you didn’t change it inside the container, as this is not the way to go. Containers are disposable by design.

You either want to create your own Dockerfile that includes the changes you want and build a new image based on it, or you eclipse the configuration file by binding a config file as volume from your host into the container path I have no idea where caddy requires it’s config file.

I am surprised it’s not mentioned directly in the image description on Docker Hub, or the documentation that is linked in the Docker Hub description.

update: I found it in the docs, just not in the directly linked page. The paths for the config files are described here. https://frankenphp.dev/docs/config/#docker

Those are the container paths:

  • /etc/frankenphp/Caddyfile: the main configuration file
  • /etc/frankenphp/caddy.d/*.caddy: additional configuration files that are loaded automatically

Thus, you can use the arguments -v path/to/local/Caddyfile:/etc/frankenphp/Caddyfile. Make sure the image name remains the last argument, otherwise it will become an argument to the process inside the container, and not to the container creation.

You could also map a whole folder into a container path: -v path/to/local/caddy.d:/etc/frankenphp/caddy.d. This way you could place additional configurations in path/to/local/caddy.d and the container would see and use them (unless you use a Caddyfile that doesn’t include the folder anymore)

The path path/to/local/ is just a placeholder for a relative or absolute path on the host. Use whated path makes sense to you,

I followed the instruction in https://docs.docker.com/engine/install/debian

When you installed 29.1.3 it was already obvious that you must have installed docker-ce, as distro version are usually older than the latest versions from docker’s official repositories.

It was in the error message.

I’m not sure how to interpret that sentence, but @meyay explained what you would need to do with examples. I just mentioned mounting assuming you knew what it meant, since you already mounted your current working directory into the container.

Do you still need help with that? I feel you got all the information, but if you still don’t understand something, please, quote parts of previous posts that you don’t understand

This -v will only bind-mount your working directory into /app inside the container. But this is probably not where the Caddyfile needs to go.

This is why your Caddyfile does not change in the container, it’s using a different file inside the image at a different path, which exists as a default.

So add a second bind-mount of your Caddyfile to the correct path inside your container, see previous post.

Thank you all of you.
I’m some steps further. I’ve setup a docker-compose.yml file and have run docker-compose up. It started but not finished! If I press C it stops the service.

georg@hpradio1:/var/www/html/CRadio$ docker compose up
Attaching to app-1
app-1  | {"level":"warn","ts":1765989487.3125427,"logger":"admin","msg":"admin endpoint disabled"}
app-1  | {"level":"info","ts":1765989487.3130116,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000474b80"}
app-1  | {"level":"info","ts":1765989487.356649,"logger":"frankenphp","msg":"FrankenPHP started 🐘","php_version":"8.5.0","num_threads":8,"max_threads":8}
app-1  | {"level":"warn","ts":1765989487.3580763,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":8080"}
app-1  | {"level":"warn","ts":1765989487.358091,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":8080"}
app-1  | {"level":"info","ts":1765989487.3582854,"logger":"http.log","msg":"server running","name":"php","protocols":["h1","h2","h3"]}
app-1  | {"level":"info","ts":1765989487.3584948,"msg":"Caddy serving PHP app on :8080"}
app-1  | {"level":"info","ts":1765989487.3622327,"logger":"tls","msg":"storage cleaning happened too recently; skipping for now","storage":"FileStorage:/data/caddy","instance":"e3fe47d6-545e-4bbe-8531-f565c166fe1a","try_again":1766075887.3622298,"try_again_in":86399.999999462}
app-1  | {"level":"info","ts":1765989487.3623846,"logger":"tls","msg":"finished cleaning storage units"}


w Enable Watch   d Detach

Could somebody tell me what is wrong?

Can you share what you mean by ā€œwhat is wrong?ā€. What is the behavior you expected?

Maybe you want to run docker compose up --detach?