Deploying Node.js Applications with Docker and PM2
Deploying a Node.js application efficiently requires tools that ensure scalability, reliability, and ease of management. Docker and PM2 are two popular tools used for deployment. Docker provides containerization, and PM2 helps manage Node.js processes. Let’s dive into how to use these tools effectively.
1. Introduction to Docker
Docker is a containerization platform that packages your application and its dependencies into a container, ensuring consistency across development, testing, and production environments.
A. Setting Up Docker
1. Install Docker
Download and install Docker from the official site.
2. Create a Dockerfile
A Dockerfile defines the environment and steps for containerizing the app:
# Use Node.js base image
FROM node:16
# Set working directory
WORKDIR /usr/src/app
# Copy package.json and install dependencies
COPY package*.json ./
RUN npm install
# Copy application code
COPY . .
# Expose the port the app runs on
EXPOSE 3000
# Start the application
CMD ["node", "app.js"]
3. Build the Docker Image
Build the container image:
docker build -t my-node-app .
4. Run the Docker Container
Run the application in a container:
docker run -p 3000:3000 my-node-app
B. Benefits of Docker
OAuth is commonly used for "Login with Google/Facebook" functionality.
2. Introduction to PM2
PM2 is a process manager for Node.js applications that provides features like load balancing, monitoring, and automatic restarts.
A. Installing PM2
Install PM2 globally: bash Copy code
npm install -g pm2
B. Starting a Node.js Application
1. Start the Application:
pm2 start app.js
2. View Process List:
pm2 list
3. Restart or Stop Processes:
pm2 restart app
pm2 stop app
C. PM2 Configuration File
Define process settings in an ecosystem.config.js file:
module.exports = {
apps: [
{
name: 'my-node-app',
script: './app.js',
instances: 'max', // Enables load balancing
exec_mode: 'cluster', // Cluster mode for multi-core CPUs
env: {
NODE_ENV: 'development',
},
env_production: {
NODE_ENV: 'production',
},
},
],
};
Start the app with the config file:
pm2 start ecosystem.config.js --env production
3. Combining Docker and PM2
Docker and PM2 can work together for scalable, efficient deployments.
A. Updating the Dockerfile
Modify the Dockerfile to include PM2:
FROM node:16
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install pm2 -g && npm install
COPY . .
EXPOSE 3000
CMD ["pm2-runtime", "start", "ecosystem.config.js"]
B. Building and Running the Image
1. Build the Image:
docker build -t my-node-app-pm2 .
2. Run the Container:
docker run -p 3000:3000 my-node-app-pm2
4. Deployment Best Practices
1. Environment Variables:
Use Docker’s .env files to store sensitive data:
docker run --env-file .env -p 3000:3000 my-node-app-pm2
2. Multi-Stage Builds:
Optimize image size by separating build and runtime stages:
FROM node:16 as builder
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
FROM node:16
WORKDIR /usr/src/app
COPY --from=builder /usr/src/app .
EXPOSE 3000
CMD ["pm2-runtime", "start", "ecosystem.config.js"]
3. Scaling with Docker Compose:
Use docker-compose for multi-container setups:
version: '3'
services:
app:
build: .
ports:
- "3000:3000"
environment:
NODE_ENV: production
Start the application:
docker-compose up
4. Monitor with PM2:
Use PM2’s built-in dashboard for monitoring:
pm2 monit