Deployment
Last updated
Last updated
This is usually the last step that I take when launching an app from the ground up. We will break deployment down into five steps. The motif of this project is to self-host, so you won't see a Vercel deployment step here anywhere in the meantime. But if anyone wants to deploy this project using Vercel message me if you need help.
There are a lot of ways to self-host a NextJS app. You can do it by setting up SSL Certs + A process manager for Node like PM2 + Reverse Proxy like Nginx. But I want to try Coolify for engineering's sake, and all of the things that I mentioned are set up using a single command, except for PM2 because Coolify uses Docker to host your apps, and this way I can deploy any app written in any programming language.
Steps overview:
Obtaining a Domain Name
Setting up your VPS with Coolify
Setting up your Github Container Registry details
Setting up the deployment pipeline (Continuous Delivery)
Setting up your Coolify App
If you want to launch an app, a domain name is one of the key things that you should get. Cloudflare is my go-to domain name registrar because it doesn't only provide the registration but it also provides DDoS protection, tunneling (we'll discuss this later on), S3 bucket alternative, etc. The list goes on. If you want to go for another provider it's your choice, but I'll discuss Cloudflare here.
Sign up for a Cloudflare account
Go to this page called Register Domains
Search for the domain name that you would like to purchase then click the purchase button once it pops up. You should be able to see this screen below, input your contact details, and card details, and then click complete purchase.
Your domain should be able to show up here after a while
That's it your domain name is ready to use. We will use that later on.
For the VPS it depends on you on where you will buy it, and the location where you would like it to be placed. As much as possible place it near to your database location, so latency can be minimized. I tried DigitalOcean, Hetzner, OVH, and Vultr. Right now, I am using OVH to host this project because it's cheap, for 3 USD you can have a 2 Core and 2GB RAM machine. I would suggest Hetzner and OVH if we're talking about pricing here. But regardless of where you buy it, choose Ubuntu the latest one as your operating system. Once you have purchased a VPS, proceed with the steps below.
Run this command to install Coolify. Coolify will help us automate deployments and manage our apps.
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
Once installed, it should be able to give you the location of its dashboard. e.g 192.168.1.1:8000
Create your Coolify account and proceed with the onboarding. Choose localhost on the onboarding step, because we will both host Coolify and the apps inside the same VPS.
Once you're done with the onboarding, click the Projects tab and create a new project.
Click "Add New Resource"
Click "Existing Docker Image". Our NextJS app shall be Docker-based and will be built inside a GitHub Action instance, which you will see later on.
Select "localhost" for the server and you will see this screen that prompts you to input a docker image. Our docker images shall be stored in GHCR (Github Container Registry), if you want you can use Dockerhub but I don't see the point of splitting out the GitHub Action and the Container Image registry since they work hand in hand. As you can see below the format is :
<registry_name>/<your_github_username>/<app_image_name>:<version>
Just replace erehwonmi with your GitHub username, then click save
This page should appear once you click save, for now, leave it as it is.
Obviously, you need a GitHub account.
Fork / Clone the TheNextStartup repository to your GitHub account.
Create a GitHub Personal Access Token. You will need this to authenticate with GHCR. Go to Settings > Developer Settings > Tokens (classic) then Generate new token (classic)
Fill up token details as shown below then generate the token.
SSH to your VPS, then login to your registry by typing this command. That command should allow Coolify to pull up any container image from your registry so that it can spin up the app.
docker login ghcr.io -u <username> -p <your_generated_token>
In this section, I'll explain what's happening on the deployment script via code comments. The continuous delivery script should help you push changes automatically to your application on the server. Both the web app and the admin app contain the same configuration of the CD pipeline.
Each app has a unique COOLIFY_WEBHOOK in order to notify Coolify that it needs to pull the latest image from the registry and redeploy our app. You can obtain this webhook URL by going back to the Coolify app that you made in the previous step. Copy the URL that is inside that red circle and store it inside your repository's GitHub secrets.
For the COOLIFY_TOKEN. Go to Keys & Tokens > API Tokens and create a new token with the following configuration. Copy that key and store it inside your repository's GitHub secrets.
For the Dockerfile the TLDR is it has a multi-stage build that enables us to build and containerize our NextJS app.
In this step, we will establish a tunnel from Cloudflare to your VPS. In this way, only Cloudflare can talk with your VPS and you can serve your apps to the internet without exposing any ports (except SSH port 22 you need to expose this). You can skip this part if you don't want to do this. You can set up an A Record for your app.
Go to Cloudflare Account > Zero Trust > Network > Tunnels > Create a Tunnel > Select Cloudflared and just complete the steps
At some point, you will stumble upon this, select Debian copy that command, and the SSH to your VPS paste it then run it.
After setting that up, your Tunnel should appear healthy
Click your Tunnel name > Click Edit > Add a public hostname then mimic details below. Your purchased domain name should pop up. Cloudflare talks to your app internally via HTTP localhost. The generated public hostname should be able to point to your web app and expose it to the internet.
Copy the generated public hostname to your Coolify app to the Domains input box, then click Save. The button right beside General.
Go back to your cloned TheNextStartup repository, then go to the Actions tab and manually trigger the workflow via Run workflow. This will run the build step and deploy your app to Coolify.
You can also set a public hostname for your Coolify app instance by doing the previous step and pointing it here (Instance's Domain) then click Save. If Saving doesn't work, you have to restart your VPS.
After all of those steps, your app is finally live. Moving forward if you need to create another app the TLDR is just to Create a Coolify App > Create Cloudflare Public Hostname > Point public hostname to Coolify App > Manually Trigger Github Action > App is now live.
Once your app is live don't forget to set up your payment provider's (Stripe / Lemonsqueezy) webhook API endpoint and secret environment variables.