People arrive at container hosting expecting it to replace how their websites run. It usually does not, and understanding why saves a lot of wasted effort.
Your PHP sites keep running the way they always did — under their own Linux user, in their own PHP-FPM pool, behind the web server. Docker does not touch that. What Docker adds is a second lane on the same machine for the software that was never going to fit in the first lane: an analytics platform, a Git server, a message broker, an AI model runner, a photo library. Software that ships as a container image and expects to own its own dependencies.
So the honest mental model is: two runtimes, one server.
Both end at the same web server, and that is the important part. A container is not automatically reachable from the internet. It listens on a port on the host, and something has to route a hostname to that port with a certificate attached. Skip that step and you end up doing what half the internet does — publishing
Three things worth deciding before you start
Which lane does this app belong in? If it is WordPress, Laravel or anything PHP that you will edit over SFTP, it belongs in the website lane. Putting it in a container buys you an extra layer between you and the files for no benefit. If it is a packaged product you consume rather than develop, container.
How much memory can it have? Containers with no memory limit are the single most common cause of "my server died and I do not know why". The kernel OOM killer does not care that the process eating 6 GB was a photo indexer; it kills whatever it decides is the best candidate, and that is often your database.
What happens on reboot?
What Docker does not give you
It is not a security boundary between customers. A container escape is a smaller class of problem than a shell escape, but root inside a container is still root on a shared kernel unless you have gone out of your way with user namespaces, dropped capabilities and a seccomp profile. If you are hosting other people's code — not other people's websites, their code — that distinction matters enormously. Containers are a packaging and resource boundary first, and a security boundary a distant second.
What version are you all running? On this box it is Docker 29.6.2 with Compose v5.3.1, which is worth mentioning because half the tutorials still online use
Your PHP sites keep running the way they always did — under their own Linux user, in their own PHP-FPM pool, behind the web server. Docker does not touch that. What Docker adds is a second lane on the same machine for the software that was never going to fit in the first lane: an analytics platform, a Git server, a message broker, an AI model runner, a photo library. Software that ships as a container image and expects to own its own dependencies.
So the honest mental model is: two runtimes, one server.
Code:
your websites → user account → PHP-FPM pool → nginx/apache vhost
your applications → container → published port → reverse proxy vhost
Both end at the same web server, and that is the important part. A container is not automatically reachable from the internet. It listens on a port on the host, and something has to route a hostname to that port with a certificate attached. Skip that step and you end up doing what half the internet does — publishing
0.0.0.0:8080 and handing out a URL with a port number in it.Three things worth deciding before you start
Which lane does this app belong in? If it is WordPress, Laravel or anything PHP that you will edit over SFTP, it belongs in the website lane. Putting it in a container buys you an extra layer between you and the files for no benefit. If it is a packaged product you consume rather than develop, container.
How much memory can it have? Containers with no memory limit are the single most common cause of "my server died and I do not know why". The kernel OOM killer does not care that the process eating 6 GB was a photo indexer; it kills whatever it decides is the best candidate, and that is often your database.
What happens on reboot?
restart: unless-stopped in Compose, or the equivalent restart policy in your panel. Every container you deploy without one is a service that silently disappears the next time the machine reboots, and you will find out weeks later.What Docker does not give you
It is not a security boundary between customers. A container escape is a smaller class of problem than a shell escape, but root inside a container is still root on a shared kernel unless you have gone out of your way with user namespaces, dropped capabilities and a seccomp profile. If you are hosting other people's code — not other people's websites, their code — that distinction matters enormously. Containers are a packaging and resource boundary first, and a security boundary a distant second.
What version are you all running? On this box it is Docker 29.6.2 with Compose v5.3.1, which is worth mentioning because half the tutorials still online use
docker-compose with a hyphen and a v1 syntax that has been gone for years.