Introduction: Why VPS is the Best Choice for Production
Developing a JavaScript application on Node.js is only half the battle. The second, equally important part is deployment to a production server. Many beginner developers use free hosting services (Heroku, Render, Vercel), but for serious projects, a VPS (Virtual Private Server) will eventually be needed.
A VPS gives you full control over the environment: you choose the Node.js version, configure the web server, manage processes and resources. In this article, we'll walk through the step-by-step process of deploying a JavaScript application to a VPS using modern tools: Nginx as a reverse proxy, PM2 for process management, Let's Encrypt for SSL, and GitHub Actions for automation.
Step 1: Server Preparation and Installing Required Software
The first step is connecting to your VPS (usually via SSH) and installing a basic set of tools. Let's assume you are using Ubuntu 22.04 LTS.
# Update packagessudo apt update && sudo apt upgrade -y
# Install Node.js (recommended via NodeSource)curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -sudo apt install -y nodejs
# Check versionsnode -vnpm -v
# Install Git (if not already installed)sudo apt install git -y
# Install Nginxsudo apt install nginx -yAlso, be sure to configure a basic firewall (UFW):
sudo ufw allow OpenSSHsudo ufw allow 'Nginx Full'sudo ufw enableStep 2: Cloning the Repository and Configuring the Application
Now you need to transfer the application code to the server. The simplest way is to clone the repository from GitHub/GitLab.
# Navigate to the /var/www directory (standard for web projects)cd /var/www
# Clone the repository (replace with your URL)sudo git clone https://github.com/your-username/your-repository.git myapp
# Give permissions to the current usersudo chown -R $USER:$USER /var/www/myapp
# Navigate to the application foldercd /var/www/myapp
# Install dependenciesnpm install --productionCreate a .env file for environment variables (port, API keys, database connection string):
# Example .envPORT=3000NODE_ENV=productionDATABASE_URL=mongodb://localhost:27017/myappJWT_SECRET=your-secret-keyStep 3: Configuring PM2 for Process Management
PM2 is a process manager for Node.js that automatically restarts the application if it crashes and keeps it running in the background.
# Install PM2 globallysudo npm install -g pm2
# Start the application (if entry point is app.js or server.js)pm2 start app.js --name "myapp"
# Save the process list for auto-start on rebootpm2 savepm2 startup systemdAfter running pm2 startup, you will see a command that needs to be executed with root privileges. Copy and run it.
You can check the status with the command pm2 status. If the application is running, it will be accessible at http://your-ip:3000 (the port from .env).
Step 4: Configuring Nginx as a Reverse Proxy
Direct access to Node.js via port 3000 is not a best practice. It's better to use Nginx as a proxy server, which will accept requests on port 80 (HTTP) and forward them to your application.
Create a configuration file for your domain (or IP):
sudo nano /etc/nginx/sites-available/myappInsert the following code:
server { listen 80; server_name your-domain.ru www.your-domain.ru;
location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connectio