Learn how to set up a Strapi app on VPS, DigitalOcean, Linode with Ubuntu, MySQL.

Deploy Strapi on VPS with Ubuntu, MySQL

Ravgeet Dhillon

Ravgeet Dhillon

Updated on Oct 08, 2021 in Devops

⏱ 10 min read

Blog banner for Deploy Strapi on VPS with Ubuntu, MySQL

So you have built your Strapi project and the next thing you need to do is to deploy it on a production server. In this blog, you’ll learn to set up a Virtual Private Server(VPS) and then deploy your Strapi app. You can apply this guide to any kind of servers like Linode, DigitalOcean, and many more.



To follow along, make sure you have the following

  • Hostinger VPS Plan 1
  • Ubuntu 20.04

Replace all the values in <> with your own values while following this tutorial.

1. Create a Non-Root User

It is a good idea to create a non-root user with sudo privileges. All the commands will be run through this user. The first step is to log in as the root user.


The very first thing to do on a new machine is to update the packages and remove the older ones. To do so, run the following commands:

sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

Now your machine is up to date and you need to create a new user and log out of the session.

adduser <NEWUSER>
usermod -aG sudo <NEWUSER>

2. Create a Public-Private Key Pair

It is great to use Public-Private key pair to SSH into a remote server. You can create a new one by doing:


or copy the existing one’s public key onto your clipboard by running the following command:

xclip -selection clipboard -in ~/.ssh/hostinger_rsa.pub

3. SSH as a new user

Next, SSH as a new user using password authentication.


Once you are logged in, you need to create a directory for the new user identified by its name.

mkdir -p <NEWUSER>

4. Add SSH Key to Authorized Keys

Register your public key by adding it to your authorized keys so that you can log in using a private key.

mkdir -p  ~/.ssh/
sudo echo "<COPIED_PUBLIC_KEY>" >> ~/.ssh/authorized_keys

5. Configure Firewall

Now is the time to set up a firewall. A firewall is essential while setting up VPS to restrict unwanted traffic going out or into your VPS. Install ufw and configure a firewall to allow SSH operations by doing:

sudo apt install ufw -y
sudo ufw allow OpenSSH
sudo ufw enable -y
sudo ufw status

6. Remove Apache and Install Nginx

Nginx is a much better server than Apache. It is lightweight, easy to set up, and allows you to set up proxies.

Before installing Nginx, you can remove Apache which is available by default in Ubuntu 20.04 by running the following commands:

sudo systemctl stop apache2 && sudo systemctl disable apache2
sudo apt remove apache2 -y && sudo rm /var/www/html/index.html
sudo apt autoremove -y

Now install Nginx by doing:

sudo apt install nginx -y
sudo systemctl start nginx
sudo systemctl status nginx

Next, configure the firewall to allow HTTP and HTTPS traffic to pass through it.

sudo ufw allow 'Nginx Full'
sudo ufw enable -y
sudo ufw status

You can also allow either HTTP or HTTPS by using:

sudo ufw allow 'Nginx HTTP'
# or 
sudo ufw allow 'Nginx HTTPS'

To verify Nginx installation, visit the IP address of the VPS.
You can find IP address by curl -4 icanhazip.com.

7. Install Node Using NVM

Next, it is time to install Node using NVM. The following code helps you find the current nvm version:

nvmversion=$(curl --silent "https://api.github.com/repos/nvm-sh/nvm/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
curl -o- "https://raw.githubusercontent.com/nvm-sh/nvm/$nvmversion/install.sh" | bash

Some NPM packages require to refer to numerous packages needed for building software in general. So you’ll need to install the build-essential package by doing:

sudo apt install build-essential -y

8. Install PM2

PM2 is a process manager built for production-level apps. It can help you run your Strapi app when the server restarts. It can watch for file changes and restart the server automatically for us.

npm i -g pm2@latest
cd ~
pm2 startup systemd

Follow the rest of the instructions as specified on the terminal and then do pm2 save.

9. Install Database (MariaDB/MySQL)

MariaDB is a fork of MySQL with lots of performance gains. So, install this database server by doing:

sudo apt install mariadb-server -y
sudo mysql_secure_installation

Follow all the instructions and complete the setup.

Once your MariaDB server is installed, you need to create a non-root user with root privileges for database operations.

sudo mariadb

Once this is done, restart your database server by doing:

sudo systemctl restart mariadb

10. Create Nginx Server Blocks

It is always a good idea to server blocks rather than to change the default Nginx configuration. This helps you to host multiple websites on the same server. To create a server block, run the following command:

sudo nano /etc/nginx/sites-available/<YOUR_DOMAIN>

Then, add the following configuration code in it:

upstream <YOUR_DOMAIN> {
  keepalive 64;

server {
  server_name <YOUR_DOMAIN>;
  access_log /var/log/nginx/<YOUR_DOMAIN>-access.log;
  error_log /var/log/nginx/<YOUR_DOMAIN>-error.log;
  location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;
    proxy_set_header X-NginX-Proxy true;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_pass http://<YOUR_DOMAIN>;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_cache_bypass $http_upgrade;

server {
  listen 80;
  server_name <YOUR_DOMAIN>;

This configuration assumes that your Strapi app will run on

Once your configuration is set up, you need to enable your website by creating a symbolic link for your configuration file. To do so, run the following command:

sudo ln -s /etc/nginx/sites-available/<YOUR_DOMAIN> /etc/nginx/sites-enabled/

This is optional but if you are serving multiple domains or subdomains from your server, you need to edit your nginx.conf by uncommenting this line server_names_hash_bucket_size 64; using:

sudo nano /etc/nginx/nginx.conf

Quickly check that your configurations are error-free by running:

sudo nginx -t

The output will tell you whether an error exists or not. If any error comes up, you need to resolve it and then finally restart the server by doing:

sudo systemctl restart nginx

11. Setup DNS

In your domain provider, you need to add an A record to point your subdomain to the VPS as follows:


The DNS propagation can take upto 24 hours.

12. Install SSL

The final step is to issue an SSL certificate for your Strapi app. You can automate the process of issuing certificates to your domain using certbot. Running the following commands will help you issue a Let’s Encrypt SSL certificate for your domain.

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d <YOUR_DOMAIN>

Follow all the instructions on the terminal. Use the Redirect option to redirect HTTP traffic to HTTPS.

The advantage of the above commands is that the certbot process runs twice a day to check if any certificates will expire within a month. It automatically renews the certificates so you don’t have to worry about certificate expiration. You can verify this by running:

sudo systemctl status certbot.timer

13. Run Strapi App

Now that your server setup is complete and it is time to run your Strapi app using PM2 by running the following commands:

cd ~
cd api
pm2 start ecosystem.config.js

At this point, visit your Strapi domain and verify that your Strapi app is running.


Loved this post? Join our Newsletter.

We write about React, Vue, Flutter, Strapi, Python and Automation. We don't spam.

Please add a valid email.
By clicking submit button, you agree to our privacy policy.
Thanks for subscribing to our newsletter.
There was some problem while registering your newsletter subscription. Please try again after some time or notify the owners at info@ravsam.in


Ravgeet Dhillon

Ravgeet is a Co-Founder and Developer at RavSam. He helps startups, businesses, open-source organizations with Digital Product Development and Technical Content Writing. He is a fan of Jamstack and likes to work with React, Vue, Flutter, Strapi, Node, Laravel and Python. He loves to play outdoor sports and cycles every day.


Got a project or partnership in mind?

Let's Talk

Contact Us ->