DEV Community

Cover image for Deploying Nestjs app to VPS with nginx, postgres, redis
Manuchehr
Manuchehr

Posted on • Originally published at Medium

Deploying Nestjs app to VPS with nginx, postgres, redis

Let’s deploy nestjs + postgres + redis + docker app to VPS. Everything is from scratch, hopefully understandable for beginners.

Written by Full stack developer (not a master devops :)

Setting up a basic nginx is not hard. Just a few things you should do:

  • Install nginx to Linux (ubuntu 20.04)
  • Create Nginx config file + proxy server
  • Generate an SSL certificate for your domain name (if you have one)
  • That’s all. Don’t worry we’ll cover all of these.

Starting nestjs app

First of all, clone your project to the server via git. After that, you run your project. First of all, you need nodejs to run nestjs application. If you use Docker, you can skip these steps & run the Dockerfile.

  1. I recommend to install nvm (Node Version Manager):
curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
source ~/.bashrc
Enter fullscreen mode Exit fullscreen mode

Once you’ve installed nvm, you need to install node (v18):

nvm i 18
Enter fullscreen mode Exit fullscreen mode

If you use yarn, install it too:

npm i -g yarn
Enter fullscreen mode Exit fullscreen mode

Then go to your project dir, and install packages via npm or yarn, then build your app. After that, install pm2 to run your app (forever):

npm i -g pm2
Enter fullscreen mode Exit fullscreen mode

Once you have installed pm2, check if it’s working:

pm2
Enter fullscreen mode Exit fullscreen mode

If so, you can run your app by following the command. If there is postgres or redis, you need to run them first then run your app (see 2)

pm2 start ./dist/main.js --name my-nestjs-app
# pm2 start <script_file_path.js> --name <name_optional>
Enter fullscreen mode Exit fullscreen mode
  1. If you use Postgres or Redis, I recommend using a Docker Compose for these. This is my sample docker-compose.yml file for Postgres and Redis:
version: "3"
services:
  postgres:
    image: postgres
    restart: always
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    ports:
      - '5432:5432'
    volumes:
      - my-nestjs-app:/var/lib/postgresql/data
  redis:
    image: "bitnami/redis:7.2"
    restart: unless-stopped
    ports:
      - "6379:6379"
#    volumes:
#      - "redis_data:/bitnami/redis/data"
    environment:
      REDIS_PASSWORD: ${REDIS_PASSWORD}
      REDIS_PORT: ${REDIS_PORT}
      REDIS_DB: ${REDIS_DB}
      REDIS_IO_THREADS: 4
      REDIS_IO_THREADS_DO_READS: yes
      REDIS_DISABLE_COMMANDS: FLUSHDB,FLUSHALL

volumes:
  my-nestjs-app:
Enter fullscreen mode Exit fullscreen mode

To run docker compose you need to have docker. Complete guide to install docker on ubuntu. Once you have installed docker, run docker-compose:

sudo docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Setup nginx

So let’s set up nginx for nestjs app. Before installing nginx, update your existing list of packages:

sudo apt update
Enter fullscreen mode Exit fullscreen mode

Then install nginx:

sudo apt install nginx
Enter fullscreen mode Exit fullscreen mode

Check nginx if it is working:

sudo systemctl status nginx
Enter fullscreen mode Exit fullscreen mode

You will get:
Image description
Create an nginx configuration file in /etc/nginx/sites-available/my-nestjs-app

sudo vim /etc/nginx/sites-available/my-nestjs-app
Enter fullscreen mode Exit fullscreen mode

Then copy/paste this configuration:

server {
    server_name domain.com;
    client_max_body_size 300M;

    # add_header 'Access-Control-Allow-Origin' '*';

    location = /favicon.ico { access_log off; log_not_found off; }

    location / {
        proxy_set_header Host $http_host;
        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 https;
        proxy_pass http://127.0.0.1:3000;
    }
}
Enter fullscreen mode Exit fullscreen mode

Let’s understand this configuration:

  • server_name — According to nginx docs: it is used for a given request. They may be defined using exact names, wildcard names (like domain.com sub.dobmain.com), or regular expressions.
  • client_max_body_size — the maximum size of a client request body. If this size is exceeded, nginx returns a 413 status code error. If you don’t want that just comment it.
  • location / — means if the request matches this “/” or the value of location then nginx runs “the code inside of its block”. We used proxy_set_header and proxy_pass directives. proxy_set_header sets the header for the defined request. proxy_pass kinda forwards requests to the given URL or path. We set localhost 3000 so, every request in server_name and location forwards to location 3000 (domain.com/ -> localhost:3000/)

After that, save the file (in vim type :wq) and test the conf file with nginx command:

sudo nginx -t
Enter fullscreen mode Exit fullscreen mode

Image description

If you make a syntax error, it will be shown. If everything is ok, create a link:

sudo ln -s /etc/nginx/sites-available/my-nestjs-app /etc/nginx/sites-enabled/my-nestjs-app
Enter fullscreen mode Exit fullscreen mode

then test nginx & restart nginx:

sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

Setup domain name

First of all, you need to forward the domain name to your VPS. Go to your domain provider dashboard > DNS Records > create a record with A name, and put the IP address of your VPS in the “name” field (example). Then check it’s forwarded to your IP address ($ hostname -I to see IP):

ping domain.com
Enter fullscreen mode Exit fullscreen mode

Image description
If these IP addresses are not the same as the IP address of your VPS, you should wait to be the same (it might take minutes to days depending on your domain registrar), otherwise you will face problems.

You need to add an SSL certificate to your domain. It’s easy with certbot, so install cerbot:

sudo apt update
sudo apt install certbot python3-certbot-nginx
Enter fullscreen mode Exit fullscreen mode

After that run this command to generate SSL certificates for your domain:

sudo certbot --nginx -d example.com
Enter fullscreen mode Exit fullscreen mode

After that test the nginx conf file:

sudo nginx -t
Enter fullscreen mode Exit fullscreen mode

If it’s ok, restart nginx:

sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

That’s all! I apologize for any mistake I made. If you find any mistake, please let me know.
I hope it’s helpful

Top comments (0)