I’m looking into the possibility of migrating our customers’ web sites into containers, and would like to make administration of such a platform as convenient as possible. I am currently using the excellent nginx-proxy in a different container environment, which makes deployment very simple by enabling reverse proxying simply by setting an environment variable on a container, indicating its server name. I might have continued using it, but Caddy seems to integrate Let’s Encrypt more conveniently. I found caddy-docker-proxy, which appears to serve a similar purpose, so that’s a start.
So, I’m thinking Caddy Docker Proxy as the entrypoint, reverse proxying a number of PHP containers labelled accordingly. I appreciate that this might not strictly be related to Caddy, but I’m not entirely sure of how the PHP bits would work. We currently use PHP-FPM with Apache. There exists official images for PHP with Apache (mod-php) and PHP-FPM. I understand PHP-FPM is the more modern option, and that Caddy has the php_fastcgi directive intended for this (not sure about Caddy Docker Proxy, however), but also that there are certain risks involved with exposing FastCGI. It won’t be exposed to the Internet, of course, but between containers. I would rather not create a separate network for each site, that the proxy would then have to join.
Most, if not all, sites are going to be WordPress and similar platforms.
Mainly looking for feedback on the overall idea. Any immediate issues or flaws? And perhaps more specifically whether the combination of Caddy Docker Proxy and PHP-FPM containers is a good idea?
CDP can do everything vanilla Caddy can. It’s just a plugin on top of it to read Docker labels and generate a Caddyfile from them.
Not… really? I mean, you don’t want to expose it to the public, no, but you’d only be exposing it to your Docker network so that Caddy can reach it. No problem with that. In fact, that’s what you must do.
Yeah that’s fine, you only need one network.
Yeah it would work just fine.
Just one thing to keep in mind though, the CDP/Caddy container itself needs to have filesystem access to the files for each site. This is important so that Caddy can see if a file exists on disk to perform rewrites, and serve static files directly (CSS, JS, images, etc). Any request that doesn’t map to a static file gets routed to your PHP app.
That part can be a bit tricky though, because then you need to make sure you have volumes (possibly marked external) so that you can add them to CDP. And unfortunately if you need to add a new one, you’d need to restart CDP so that the volume gets added (because volumes can’t be added while a container is running).
A different approach you could take is to make CDP simply a proxy using reverse_proxy and have each of your WordPress apps have their own webserver container (you can use Caddy in each stack as well). Keep in mind that you’ll want to configure trusted_proxies in your php_fastcgi config on those Caddy instances so that they trust the incoming X-Forwarded-* headers coming from the downstream Caddy proxy, so your client IP addresses are preserved in your app.
WARNING: the FastCGI protocol is inherently trusting, and thus extremely insecure to expose outside of a private container network – unless you know exactly what you are doing (and are willing to accept the extreme risk), do not use Docker’s --publish (-p) flag with this image variant.
I understand it won’t be exposed to the Internet. Just concerned whether it would be a security risk to expose it between the containers.
Regarding web serving, I was considering running the FPM image due to the saved resources from not needing a web server for each container, but it seems then that doing so might not be worth the effort/complexity.
I have not actually used Caddy before. Are there any notable differences or otherwise good things to know regarding using Caddy compared to nginx or Apache for this purpose?
No, that disclaimer is saying that it should only be accessible from other containers (i.e. “private container network”). That’s exactly what you’re doing here. It’s the only way you can really use it anyway. (Well, you could connect over a unix socket shared via a volume instead of TCP, but either way, same deal).
FPM is still much more efficient than mod_php, even if you have servers involved. But if you’re truly concerned, do some benchmarking. Either way, unless you’re under extremely high load, the difference will not be noticeable. It won’t matter until you’re really pushing the boundaries. And at that point, you’d want to scale out your apps (run multiple app servers for the same site, load balancing, etc).
That’s vague. There are differences and there are similarities. But it’s not something that can be easily recapped. If you have any specific concerns then I could speak to that.