Automatically Deploy Apps to VPS with Git Triggers & Coolify

This is an introduction to Coolify, a project that can deploy custom applications based on Git events. It's similar to a self-hosted Netlify or Heroku.

I make a lot of silly projects, and one things I’ve wanted for a long time is a way to automate the deployment process using Git. So in this blog post, we are going to be tackling just that.

First things first, let’s settle on what the target is. What I want is a system with the following:

  • Automated deploy when a new commit lands in my git repo.
  • Hands-off system. I don’t want to have to touch it once it’s set up.
  • Easy to setup new projects without too much fuss.

I’ve been looking into this for a while and a lot of the solutions I’ve come across generally fall into a few categories:

These would work to some degree, but they all fall short of my target in one way or another. They either still need some level of manual attention on my part, or they aren’t respondent to actual git events, or they are just too much ceremony to set up on new projects. I build a lot of different projects that each have their own build steps so I can’t expect the same simple script to work for every one.

For a while I thought I was going to have to build my dream project myself out of a series of complex scripts all cobbled together, but I recently found a project called Coolify that looks like just the ticket.

I don’t have proof that it’s not, itself, a series of complex scripts all cobbled together, but it’s open-source and it’s packaged up nicely, so it’s better than anything else I’ve got.

You can find more details at where you’ll see that it advertises itself as `self-hosting, made simple’ and ‘an alternative to Heroku and Netlify.`

Sounds great!

Setup & Install

I’ll be setting it up on Linode. Here is a screenshot of my pretty basic settings for my server.

Screenshot showing a Linode setup screen with the following settings: Image: Debian 11, Region: Fremont, CA, Linode Plan: Shared CPU Nanode 1 GB, Linode Label: coolify-example, Password: hidden text, SSH keys: austin_gil.

(Not necessary, but if you want to follow along with a new Linode account, )

Once our server’s up and running, I can ssh into the server using the IP address (your would be different):

ssh root@

Then I can go back to the Coolify website, copy their install script into the terminal:

wget -q -O; sudo bash ./

This part takes a bit, but once it’s finished, prompts us to go to the server’s IP address and port 3000,

When we open that link, we get this sweet login page.

Coolify login screen

I can’t log in because there isn’t any account set up, so I’m gonna go ahead and register as a new user with my email and password. Once I do, I’m in!

So the first thing I want to do is change the domain name. In my DNS records, I can add a new A record pointing to Then I can click the cog icon in the bottom left of the Coolify screen to get to the settings page. Once I change to URL to and hit save, Coolify will handle getting and an SSL certificate for me.

And once that’s done, I should be able to go to and see the same login screen, but at a much easier to remember domain name, and with an HTTPS connection.

Coolify dashboard with 1 Local Docker destination

I really don’t want to understate how awesome that is. It’s awesome. Really!

Ok, log back in.

Connect GitHub

The next thing to do is connect to my GitHub repo to automate deployments. To do that, I need to add a new “Git source” under the “Create New Resource” menu.

Coolify dashboard with the "Create new resource" menu open and highlighting "Git source"

In this case, I’ll tell Coolify it’s coming from GitHub and all the default look fine to me.

Coolify's "New Git Source" screen setup to add a new source

I think I can just leave that all the same.

Once I save save it redirects me to GitHub and walks me through creating a new GitHub app. This app will send the signal whenever my GitHub repo receives a new commit. That signal will eventually trigger a new deployment.

GitHub's "Create GitHub App" screen with the name prefilled as "coolify-austingil-com"

With the GitHub app, created I’m once again redirected back to my Coolify instance only for a moment, but then I’m prompted to install the app I just created and select which repos it has access to.

Screenshot of "Install coolify-austingil-com" GitHub app set to install on all repositories

Deploy Application

Ok, with everything hooked up and configured, if I go back to my Coolify dashboard, I have my Git source created and I should be able to create a new resource for an application.

Coolify's dashboard with the "Create New Resource" menu open and highlighting the "Application" option

I now have the option to choose as a source, which will load my repositories, and I can find the one I’m looking for by searching “battle”, then select the main branch.

Coolify's new application screen prompting to "Select a repository". There is also an input to select the branch next.

Next, I see a bunch of options for run times. Today it’s just a static website, but it’s so nice to have options readily available.

With the static option selected, it’s gonna ask me for the configuration for this new project. There will always be some random name, but I’ll call mine “battle bannerz” because why not?

I’ll give it a custom domain, But for this to work, I have to create another A record in my DNS pointing bb to Once again, Coolify will take care of the SSL certificate as long as the DNS is configured first.

Coolify application configuration screen. These settings have been changed from the default: Name - Battle Bannerz; URL -; Build image - node:lts; Install command - npm install; Build command - npm run build; Publish directory - dist

My repo only contains source files, so I also need to configure Coolify to run npm install to download all the dev dependencies, then npm run build to build the production assets. My project puts all the production assets from the build command into the /dist folder, so I also need to tell Coolify to treat that as the root of the project.

So with that set up, I hit save and then it will ask me if I want to deploy, and yes I do, and after a short bit of time, we get the moment of truth.

Screenshot of Coolify's build page with all the processes finished and a success message.

I see the purpler “open” button. Clicked it and…

Screenshot of the Battle Bannerz project

Omg, that is so freaking cool!!! I can’t believe that worked. That is so awesome!!!

Okay, last thing to test is if new commits will trigger redeploys. One quick way to do that is through the GitHub UI. I just made a small change to App.vue.

Screenshot editing the App.vue file in GitHub's UI

And back in Coolify, it looks like it tracked that “webhook_commit” and began rebuilding the projects.

Screenshot of Coolify's build page with a new set of processes started in response to a "webhook_commit" event.

Sure enough, forty seconds later I saw the success message and found the updated version of the website deployed.


Alright, that’s enough of an introduction for today. We see that it works as advertised, but there’s even more features that I didn’t get into:

  • Deploy previews for development branches
  • Deploying to remote Docker or Kubernetes instances
  • Using it for Databases
  • Totally custom Docker and Docker Compose stacks

There’s also something to be said from this being an open-source, self-hosted solution. Which means, you are entirely in control of what’s happening in your system, you aren’t dependent on someone else, and all your data remains in your control.

So if you’re the kind of person that wants to go the self-hosted route, but also wants the benefits of automated Git deploys, definitely check out Coolify. I don’t know if that’s going to be most readers, but for me, this is such a blessing.

And again, if you want some credits to get started on Linode, .

Thank you so much for reading. If you liked this article, and want to support me, the best ways to do so are to share it, sign up for my newsletter, and follow me on Twitter.

Originally published on

Leave a Reply

Your email address will not be published. Required fields are marked *