- Published on
NextJS is Not Hard to Self Host
- Authors
- Name
- Alex Lee
- @alexjoelee
Method 1: Use Coolify
On your VPS, deploy Coolify by following the installation instructions in the Coolify docs.
Make sure to create a DNS "A" record for your application pointing to your VPS IP address.
Create a New Project
Click into the Production environment and add a new Resource
Select a Git repository type, public or private
Configure the application:
Repository: Paste the URL to the Git repository or add one with a key if it's private. This way, when the repository is updated, Coolify will automatically deploy the latest updates.
Branch: Select the branch you want to deploy (e.g., main or master).
Build Pack: Nixpacks
Port: 3000 is usually default
- Select Continue, then Deploy. After deployment, on the Configuration page, add the domain you created for your application in the "Domains" box, click Save, then click Restart.
After a few minutes, Coolify will automatically provision an SSL certificate for your domain and you'll be able to access your app there.
Learn more about deploying with Coolify on the Coolify docs website.
Method 2: Use Kamal 2
On your own machine, deploy Ruby and the Kamal Gem by following the instructions in the Kamal docs.
Kamal works by using SSH to access a remote VPS and set it up for you.
Make sure to create a DNS "A" record for your application pointing to your VPS IP address.
- Initialize kamal with:
$> kamal init
This creates a few files, most importantly a config/deploy.yaml
and .env
if it doesn't already exist.
- Open the
.env
file and add your Docker Hub username and password to it, if the Docker container you want to deploy is private:
KAMAL_REGISTRY_USERNAME="Docker Hub Username"
KAMAL_REGISTRY_PASSWORD="Docker Hub Password"
- Edit your deploy.yaml file:
service: myapplicationserver (You can name this anything you like - it is used as the container name prefix)
image: myusername/myapplication (This matches what you published on Docker Hub)
servers:
- 1.2.3.4 (Your VPS Public IP)
registry:
username:
- KAMAL_REGISTRY_USERNAME
password:
- KAMAL_REGISTRY_PASSWORD
port: 3000 (This is the HTTP port your service runs on)
proxy:
ssl: true
host: app.myapplication.com
- Direct Kamal to set up your application:
$> kamal setup
- Direct Kamal to deploy your application:
$> kamal deploy
After a few minutes, you should be able to access your application at the domain you created earlier, e.g. app.myapplication.com.
Learn more about Kemal 2 in the Kemal 2 docs site
Method 3: PM2 + Caddy
On your VPS, install Caddy Web Server, Node.js, and NPM
Part 1: Get your NextJS application running
- Install PM2
$> npm install pm2 -g
- Create your PM2 configuration file for NextJS:
module.exports = {
apps : [{
name: "myapplication",
script: "npm",
args: "start",
cwd: "/var/www/next/myapplication",
watch: true,
env: {
NODE_ENV: "production",
}
}]
};
- Clone your project to a new folder, let's make one:
mkdir /var/www/next/
cd /var/www/next/
git clone https://wherever-you-host-your-repos.com/apps/myapplication
- Run PM2
$> pm2 start ecosystem.config.js
You should now be able to access your web application on port 3000, but let's secure this with Caddy.
Part 2: Securing with automatic SSL and reverse proxy
- Replace your Caddyfile with the following:
app.myapplication.com {
reverse_proxy * localhost:3000
}
- Enable and start Caddy:
$> systemctl start caddy
You should now be able to access your application at the domain you created earlier, e.g. app.myapplication.com.
Wrapping Up
These three methods of self-hosting NextJS should give you a good idea of the options available to you for migrating away from expensive platforms. You can always localize or accelerate your application by using Georouting or CDN services.
Note: If you plan to use this tutorial to deploy your NextJS application to production, you must take additional time and care to secure your VPS with proper firewall rules, intrusion prevention (such as fail2ban or CrowdSec), and other common-sense hardening tactics.