Setting up a Node.js application for production on Ubuntu 22.04 involves several crucial steps to ensure your application runs efficiently, securely, and reliably. This comprehensive guide will walk you through the process, from updating your system to deploying your application using PM2, Nginx, and securing it with SSL.
1: Deploying a Cloud Instance on Shape.host
- Log in to Shape.host Dashboard:
- Navigate to the Shape.host website and log in to your account.
- Create a New Instance:
- Click on the “Create” button located at the top right corner of the dashboard.
- From the dropdown menu, select “Instances”.
- Select Instance Location:
- Choose the desired location for your server. For this tutorial, we’ll select “New York, USA”.
- Choose a Plan:
- Select a plan that fits your requirements. For example, you might choose a plan with 2 cores CPU, 2 GB Memory, and 50 GB SSD disk space.
- Select an Operating System:
- Scroll down to the “Choose an image” section and select “Ubuntu 22.04”.
- Configure Additional Options:
- (Optional) You can configure additional options like User Data Configuration and IPv6 Networking.
- Enter a hostname for your instance, e.g., “Tutorial Ubuntu”.
- Click on the “Create instance” button to deploy the instance.
2: Connecting to Your Instance
- Retrieve SSH Credentials:
- Note the IP address of your newly created instance from the Shape.host dashboard.
- Connect via SSH:
- Open a terminal on your local machine.
- Use the following command to connect to your instance:
ssh root@your_instance_ip
- Replace
your_instance_ip
with the actual IP address of your instance.
3:Update and Upgrade System Packages
First, ensure your system is up-to-date:
apt update && apt upgrade -y
4:Install Node.js and npm
We’ll use the NodeSource repository to install the latest LTS version of Node.js:
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
sudo apt-get install -y nodejs
Verify the installation:
node --version
npm --version
5:Install Build Essentials
Some Node.js packages require compilation, so install build essentials:
apt install build-essential -y
6:Create a Node.js Application
Let’s create a simple Express application:
mkdir -p /var/www/myapp
cd /var/www/myapp
npm init -y
npm install express
Create an app.js
file:
nano app.js
Add the following content:
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.send('Hello World from my Node.js app!');
});
app.listen(port, () => {
console.log(`App listening at http://localhost:${port}`);
});
7:Install PM2
PM2 is a process manager for Node.js applications:
npm install pm2@latest -g
Start your application with PM2:
pm2 start app.js --name myapp
Set PM2 to start on system boot:
pm2 startup systemd
Save the current PM2 process list:
pm2 save
8:Install and Configure Nginx
Install Nginx:
apt install nginx -y
Create an Nginx server block configuration:
nano /etc/nginx/sites-available/myapp
Add the following configuration:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
location / {
proxy_pass http://localhost:3000;
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;
}
}
Enable the configuration:
ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
Test Nginx configuration:
nginx -t
If the test is successful, restart Nginx:
systemctl restart nginx
9:Set Up Firewall
Allow HTTP, HTTPS, and SSH traffic:
ufw allow 'Nginx Full'
ufw allow OpenSSH
ufw enable
10:Secure Your Application with SSL
Install Certbot:
apt install certbot python3-certbot-nginx -y
Obtain an SSL certificate:
certbot --nginx -d yourdomain.com
Follow the prompts to complete the certificate installation.
11:Set Up Environment Variables
Create a .env
file for environment variables:
nano /var/www/myapp/.env
Add your variables:
PORT=3000
NODE_ENV=production
Modify your app.js
to use these variables. Open the file:
nano /var/www/myapp/app.js
Update the content to:
require('dotenv').config();
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.send('Hello World from my Node.js app!');
});
app.listen(port, () => {
console.log(`App listening at http://localhost:${port}`);
});
Install the dotenv package:
npm install dotenv
12:Implement Basic Security Measures
Install and set up common security packages:
npm install helmet cors
Modify your app.js
. Open the file:
nano /var/www/myapp/app.js
Update the content to:
require('dotenv').config();
const express = require('express');
const helmet = require('helmet');
const cors = require('cors');
const app = express();
const port = process.env.PORT || 3000;
app.use(helmet());
app.use(cors());
app.get('/', (req, res) => {
res.send('Hello World from my secure Node.js app!');
});
app.listen(port, () => {
console.log(`App listening at http://localhost:${port}`);
});
13:Set Up Monitoring
Install a monitoring tool like Keymetrics:
pm2 install pm2-server-monit
pm2 link <secret-key> <public-key>
Replace <secret-key>
and <public-key>
with your Keymetrics keys.
14:Implement Logging
Install Winston for logging:
npm install winston
Create a logger.js
file:
nano /var/www/myapp/logger.js
Add the following content:
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
defaultMeta: { service: 'user-service' },
transports: [
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' }),
],
});
if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console({
format: winston.format.simple(),
}));
}
module.exports = logger;
Use the logger in your app.js
. Open the file:
nano /var/www/myapp/app.js
Update the content to:
require('dotenv').config();
const express = require('express');
const helmet = require('helmet');
const cors = require('cors');
const logger = require('./logger');
const app = express();
const port = process.env.PORT || 3000;
app.use(helmet());
app.use(cors());
app.get('/', (req, res) => {
logger.info('Home route accessed');
res.send('Hello World from my secure Node.js app!');
});
app.listen(port, () => {
logger.info(`App listening at http://localhost:${port}`);
});
15:Set Up Database Connection (Optional)
If your app uses a database, install the appropriate package (e.g., for MongoDB):
npm install mongoose
Open your app.js
file:
nano /var/www/myapp/app.js
Add database connection to your app.js
:
require('dotenv').config();
const express = require('express');
const helmet = require('helmet');
const cors = require('cors');
const logger = require('./logger');
const mongoose = require('mongoose');
const app = express();
const port = process.env.PORT || 3000;
mongoose.connect(process.env.MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => logger.info('MongoDB connected'))
.catch(err => logger.error('MongoDB connection error:', err));
app.use(helmet());
app.use(cors());
app.get('/', (req, res) => {
logger.info('Home route accessed');
res.send('Hello World from my secure Node.js app!');
});
app.listen(port, () => {
logger.info(`App listening at http://localhost:${port}`);
});
Remember to add the MONGODB_URI
to your .env
file:
nano /var/www/myapp/.env
Add the MongoDB URI:
MONGODB_URI=mongodb://username:password@host:port/database
By following these steps, you’ve set up a production-ready Node.js application on Ubuntu 22.04. Your application is now running with process management, reverse proxy, SSL encryption, basic security measures, monitoring, and logging.
For those seeking a more streamlined experience in deploying Node.js applications, Shape.host offers excellent Cloud VPS services. Their Ubuntu-based VPS solutions provide the perfect foundation for running Node.js applications in production, offering the flexibility and resources needed for optimal performance. With Shape.host’s Cloud VPS, you can focus on developing and scaling your Node.js applications, rather than worrying about the intricacies of server management and setup.