Launching a Node.js application on a virtual machine (VM) is a vital process for ensuring that your application remains stable, dependable, and capable of scaling. While many suggest using tools like PM2 and Tmux for managing Node.js applications, it is entirely feasible to deploy your app using a service manager like systemd. This article will provide you with a step-by-step guide to deploying your Node.js application on a VM utilizing systemd.
Why Not Use PM2 or Tmux?
While PM2 and Tmux are excellent tools for managing Node.js applications, there are several reasons to consider using systemd instead:
- Built-in Service Management: systemd is a native service manager for many Linux distributions, providing process management capabilities without additional dependencies.
- System Integration: Since systemd is integrated into the system's init process, it allows for better control over service lifecycles and resource management.
- Automatic Restart: With systemd, you can easily configure services to restart automatically on failure, providing high availability.
Setting Environment
To begin with Node deployment:
- Setup the node environment.
- Checkout the application code.
- Install the dependencies of the application. Either it’s frontend or backend application.
- Setup Reverse proxy like nginx or apache2 if you want to run multiple application on same server (vm), by adding virtual hosts configurations.
- Create a service file
Let's begin with installing the dependencies like NodeJS and if willing then nginx or apache.
Update the machine with:
apt update & apt upgrade
Install Node version, where X as minor version:
curl -sL https://deb.nodesource.com/setup_20.x -o /tmp/nodesource_setup. sh
Verify the node install script:
sudo bash /tmp/nodesource_setup.sh
Begin the node install and nginx
sudo apt install nodejs nginx
Running Application For first Time
Clone Your Application Repository
git clone https://github.com/your-repository/node-app.git
cd node-app
After cloning the repo, install the required dependencies: npm install
or pnpm install
Run app: npm start
or npm start
Build the application, so it not compile each time: pnpm run build
or npm run build
Now location the application folder by going inside app folder and running pwd
command. This will return path like: /opt/yourapp/
Now locate the npm
or node
executable path:
which node
or which npm
, it will return:
/usr/local/bin/node
or /usr/local/bin/npm
Create a Systemd Service File
Now write the service file for the app, mentioning the paths and executables. Along with pid name, service name,runner. As below:
sudo vim /etc/systemd/system/my-node-app.service
[Unit]
Description=My Node.js Application
After=network.target
[Service]
ExecStart=/usr/local/bin/node node-app/app.js
# OR
# ExecStart=/usr/local/bin/npm start
WorkingDirectory=/opt/destination
Environment=PATH=/usr/local/bin:/usr/bin:/bin
Environment=NODE_ENV=production
Restart=always
User=ubuntu
Group=root
StandardOutput=append:/var/log/mylogs/output.log
StandardError=append:/var/log/mylogs/error.log
[Install]
WantedBy=multi-user.target
Key Components of the Service File:
[Unit]: This section contains metadata and dependencies. The After=network.target line ensures that the service starts after the network is available.
[Service]: This section defines how the service behaves:
- ExecStart: The command to start your Node.js application.
- Restart: This setting specifies that the service should always restart if it fails.
- User and Group: Specify the user and group under which the service will run.
- Environment: Sets environment variables for your application, like NODE_ENV=production.
- WorkingDirectory: Defines the directory from which your Node.js application runs.
Service Creation Post task:
sudo mkdir –p /var/log/mylogs/
sudo chown –R ubuntu:root /var/log/mylogs/
Reload Systemd and Start Your Service
After creating the service file, reload the systemd manager configuration and start your service:
# Reload systemd to recognize the new service
sudo systemctl daemon-reload
# Start the Node.js service
sudo systemctl start my-node-app
# Enable the service to start on boot
sudo systemctl enable my-node-app
These last 3 commands are for service.
Strat: sudo service my-node-app start
Stop: sudo service my-node-app stop
Restart: sudo service my-node-app restart
Monitoring and Optimization
To ensure your application runs smoothly, regularly monitor the logs and resource usage. You can also configure resource limits in your service file if needed. Adding parameters like LimitNOFILE, MemoryLimit, and CPUShares can help manage system resources effectively.
If need to use nginx as reverse proxy your application, you may follow below steps: as nginx is already installed.
sudo nano /etc/nginx/sites-available/nodeapp
server {
listen 80;
server_name nodeapp.example.com;
location / {
proxy_pass http://localhost:3000; # Change the port if your app runs on a different 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;
}
# Optional: Serve static files from a directory
location /static {
alias /path/to/your/static/files; # Update with your static files directory
}
# Optional: Add a location for error pages
error_page 404 /404.html;
location = /404.html {
root /path/to/your/error/pages; # Update with your error pages directory
}
# Optional: Redirect to HTTPS (if you have SSL)
# listen 443 ssl;
# ssl_certificate /path/to/your/certificate.crt;
# ssl_certificate_key /path/to/your/private.key;
}
Enable the Configuration
sudo ln -s /etc/nginx/sites-available/nodeapp /etc/nginx/sites-enabled/
Test Nginx Configuration
sudo nginx -t
Restart Nginx
sudo systemctl restart nginx
Conclusion
Utilizing systemd to deploy a Node.js application on a virtual machine offers a reliable and streamlined approach to application management, eliminating the need for external tools such as PM2 or Tmux. By taking advantage of systemd's built-in service management features, you can guarantee that your application remains operational, automatically recover from unexpected failures, and achieve smooth integration with the operating system.
This guide will empower you to set up and oversee your Node.js application effectively, allowing you to concentrate on coding rather than on tedious process management. If you prioritize stability and straightforward management, deploying your Node.js applications with systemd is a superb option.
Hope you find this helpful !!!
Do share your views...
Deploying a Node.js Application on a Virtual Machine Using a Service Manager