Empowering Self-Hosting: A Journey from PaaS to Coolify for Symfony Projects
Some Context...
Since the recent dramas with Netlify and other PaaS (Product as a Service) on Twitter, regarding excessively high billing, I decided to take back control of my projects (even though I wouldn't have had billing issues) and migrate them to Coolify.
This also allowed me to host my PHP/Symfony projects without having to rely on a compatible PaaS (Scalingo, Scaleway, Platform.sh, etc.) which were too expensive for what I wanted to do.
Don't get me wrong, they're all very good (especially Platform.sh with Symfony / Symfony CLI integration), but I don't want to spend money on external services for very low traffic projects, and especially since I have my own server at home!
What is Coolify?
Coolify is an open-source self-hosted alternative to Heroku, Netlify, Vercel, etc.
Coolify allows easy deployment of projects through a good web interface, Docker containers, custom domain names and free SSL certificates, auto-deployment via webhooks, and more...
No installation tutorial, let's get straight to the point :)
Symfony Application
Kévin Dunglas, the author of FrankenPHP, a super modern and performant PHP application server, has provided a Symfony project template that works with FrankenPHP.
I migrated my PHP/Symfony projects to use this template (hugo.alliau.me, OpenGraph Image Generator, etc.), but only for production; for now, I prefer the ease of use of Symfony CLI for development.
Configuration in Coolify
After creating the project on Coolify (for example, via a GitHub repository), you'll need to configure it as follows:
-
Domains for Php
: This is the URL that will be configured in Traefik to redirect the HTTP request to the correct container. -
Docker Compose Location
: Make sure to specify the Docker Compose configuration file for production, in our casecompose.prod.yaml
.
If everything is okay, the Docker Compose configuration used by Coolify (Docker Compose Content
) should refresh correctly.
Optionally, probably due to the architecture of my server (on my NAS, I have Caddy acting as a proxy to a virtual machine where Coolify and my projects are located), I had to disable the Forcs Https
option to avoid infinite redirection issues, but maybe I don't need it anymore today:
Then you need to configure the environment variables, firstly those defined in our compose.prod.yaml
which are mandatory, and optionally those from your Symfony application's .env
:
-
APP_SECRET
: Used for certain critical parts of the code, it is imperative to have a different value between production and that of.env
. -
SERVER_NAME
: Here I configured:80
, because in my case I don't want FrankenPHP/Caddy to handle host management and SSL certificate generation, everything is done upstream in the Caddy server acting as a proxy.
tip
Since the symfony-docker template is well made, the composer dump-env prod
command is run on each container build.
This avoids parsing .env.*
files for each request, thus gaining in performance.
Deployment
It's now time to launch the first deployment of the Symfony app:
- either do it manually, via the dedicated button on the interface, which is the simplest at the moment
- or via webhooks, very convenient for automatically triggering a deployment after pushing a commit to
main
If all goes well, something similar should be displayed, and the application should be accessible: