First start with what are our main objectives:
- All domains served from the VPS should automatically receive an SSL certificate, without human intervention.
- The newly deployed sites and domains should be available right after they are deployed and the domains are routed to the VPS.
- The projects should have environments completely separated each other.
- Version control the project configurations.
- The projects should have separately configurable stacks. This means one project could run on specific versions of PHP, MySQL, Apache, Nginx or whatever, another project could run a completely different version of the same (or on a completely different stack).
- Keep the VPS configuration on the bare minimum, in order to have a fast escape plan to another VPS if something goes bad.
The requirements above can be achieved by an infrastructure based on Docker:
- Every project contains its own production configuration. This means they have to "ship" a complete service set (web server, database, PHP) in their e.g.
- The project will have its own stand-alone web server, with a specific set of domains defined in its section of
docker-compose.yml. The reverse proxy will route the requests to this web server if the domain matches one of the domains specified in that set.
- Only the reverse proxy is available from the Internet.
- The reverse proxy listens on ports 80 and 443, but every request is automatically redirected to HTTPS.
- The certificates needed for HTTPS are automatically generated by its companion container via Let's Encrypt.
Below is an illustration of this infrastructure: