DEV Community

Cover image for Deploy Next.js to Contabo VPS
Ihor Filippov
Ihor Filippov

Posted on

Deploy Next.js to Contabo VPS

Introduction

A few days ago I experienced a significant increase users count on one of my web services.

The current server capabilities became insufficient, so I started thinking about scaling.

For hosting my service, I used PaaS (Platform as a Service) render.com

For those who are unfamiliar with PaaS - it's a service that helps you deploy your code in just a few clicks. All you need to do is connect your GitHub repository and add a few settings to your environment variables (host, port, database URL, etc.). On the other hand, such ease of setup comes at a relatively high cost for maintenance. Here are the pricing plans of render.com.

Image description

And here are the pricing plans of Contabo.

Image description

As you can see, the difference is huge!

I don't want to offend render.com in any case - if you need to quickly deploy an MVP and test the viability of your idea, it’s a great and very reliable service.

Getting started

In this tutorial, I will cover the following topics:

  • Setting VPS server with Contabo
  • Nginx and pm2
  • Installing a domain name with Namecheap and adding a SSL certificate to serve website through the HTTPS.

First of all, we need to visit Contabo, register and choose a pricing plan.

I chose the simplest one for $5.50. Next, select the term length and region. I chose US East, which cost me an additional $1.35. Default one Storage Type and raw Ubuntu OS for the image.

Image description

Then, choose a password for your root user. This information is essential to connect to your vps via ssh.

Next, visit the https://my.contabo.com/vps. You should see something like this.

Image description

Now, let’s connect to our server.

Open your terminal and type:



ssh root@<ip address>


Enter fullscreen mode Exit fullscreen mode
  • your password.

Update your server



sudo apt-get update


Enter fullscreen mode Exit fullscreen mode

Install Node.js and npm



sudo apt-get install nodejs
sudo apt-get install npm


Enter fullscreen mode Exit fullscreen mode

And check actual version



node -v
npm -v


Enter fullscreen mode Exit fullscreen mode

In my case, Node.js version 10 was installed, which was not suitable for my needs. You might encounter the same issue, so I will show you an alternative way to install Node.js.

First, you need to add the NodeSource repository to your system. NodeSource provides up-to-date versions of Node.js. To do this, we need first to install curl and then run this command followed by a bash script from NodeSource.



sudo apt-get install curl
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install nodejs


Enter fullscreen mode Exit fullscreen mode

Instead of 18, you can chose any Node.js version you need.

Then, let’s add Next.js app to our VPS.



mkdir app && cd app
git clone <repository_name>
cd <repository_name>


Enter fullscreen mode Exit fullscreen mode

Install dependencies, build and run our app.



npm install
npm run build
npm start


Enter fullscreen mode Exit fullscreen mode

Now, by visiting http://<ip_address>:3000, you can see that your application is already running. The only issue is that we can't execute any other commands in the terminal. Also, if the terminal is closed, the application will stop working.

To resolve this issue, let's install pm2.



npm install -g pm2


Enter fullscreen mode Exit fullscreen mode

PM2 is a popular process manager for Node.js applications. It's used to manage and keep Node.js applications online 24/7, ensuring they are kept running in the background even after the system reboots or crashes.

Then, let’s create a configuration file in our <repository_name> directory.



nano ecosystem.config.js


Enter fullscreen mode Exit fullscreen mode


module.exports = {
  apps: [{
    name: "next-app",
    script: "npm",
    args: "start",
    instances: 1,
    autorestart: true,
    watch: false,
    max_memory_restart: "8G",
    exec_mode: "cluster"
 }]
}


Enter fullscreen mode Exit fullscreen mode

Here we define the name of our application for pm2. Number of instances to run. Also, we are setting that if the application uses more than 8 gigabytes of memory, pm2 will restart it automatically.

watch: false is need to tell the pm2 to not restart our app every time when the files in the current directory change.

Now, let’s start our app.



pm2 start next-app


Enter fullscreen mode Exit fullscreen mode

To stop, reload or get current status of the app you can use following commands.



pm2 stop next-app
pm2 reload next-app
pm2 status


Enter fullscreen mode Exit fullscreen mode

Setting up Nginx

Nginx is a powerful open-source web server software. It's known for its high performance, stability, rich feature set, scalability, and low resource consumption. Nginx is used not just as a web server but also as a reverse proxy, load balancer, and HTTP cache.

Install nginx



sudo apt-get install nginx


Enter fullscreen mode Exit fullscreen mode

Add custom configuration file



cd /etc/nginx/conf.d
nano next_app.conf


Enter fullscreen mode Exit fullscreen mode


server {
    server_name yourdomain.com www.yourdomain.com;

    location / {
        proxy_pass <ip_address>:<port>;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-For $scheme;
    }

    error_page 405 =200 $uri;
}


Enter fullscreen mode Exit fullscreen mode

This configuration sets up a reverse proxy for a web application, directing traffic from yourdomain.com and www.yourdomain.com to a Next.js app.

Setting up domain

We need to visit a Namecheap, register and buy domain.

For simplicity, I will use yourdomain.com as a placeholder for your domain.

After purchasing a domain, you should see something like this.

Image description

Now, go back to the Contabo and navigate to the https://my.contabo.com/dns (DNS Zone Management).

Here we need to put yourdomain.com and select ip address.

Image description

Then, visit edit DNS Zone for yourdomain.com page. If everything is fine you will see something like this.

Image description

Now, go back to the Namecheap and press Manage button for yourdomain.com.

In the nameservers section, select Custom DNS and put following values into it.

Image description

Please note that after adding your domain name from Namecheap and pointing it to a Contabo VPS server IP address, it may take up to 48 hours to complete the propagation process. But in most cases, the domain propagation process can occur in a few minutes.

SSL Certificate

We are planning to serve our app over the HTTPS, so it is essential to setup an ssl certificate at our server.

It can be done in two ways.

  • Buy your own SSL certificate.
  • Obtain Let's Encrypt certificate, which is free and much easier to setup.

In this tutorial I will use the second approach.



sudo apt-get update
sudo apt-get install certbot python3-certbot-nginx
sudo certbot --nginx -d  yourdomain.com -d www.yourdomain.com


Enter fullscreen mode Exit fullscreen mode

Certbot will modify your Nginx configuration automatically and obtain the certificate.

Now all we have to do is to test our nginx configuration



sudo nginx -t


Enter fullscreen mode Exit fullscreen mode

and run the server



sudo service nginx start


Enter fullscreen mode Exit fullscreen mode

Top comments (5)

Collapse
 
enitan_odupitan_2f41c813a profile image
Enitan Odupitan

Thanks so much, these steps taught me all I needed to know and got everything working on my side. But a quick question, how can you replicate this process for two or more apps that you want to be running on same VPS server. Also how does the server understands from the client's request which repository location that needs to be rendered

Collapse
 
developer991 profile image
Devloper991

You forgot to include the pm2 save command

Collapse
 
dsaga profile image
Dusan Petkovic

Why not just installing a VPS instance with Docker, then just using a container to host the app instead of directly installing nodejs versions?

Collapse
 
igorfilippov3 profile image
Ihor Filippov

I shared my own experience. I work alone on my projects, so I don't use Docker.

Collapse
 
steravy profile image
Stefan Vitoria

Very usefull man. Worked just fine and my app is up and running.