This project demonstrates how to set up a basic Express web server, containerize it using Docker, and proxy multiple instances of the app using NGINX. Additionally, the tutorial also covers how to secure your connection with SSL certificates.
- Node.js
- Docker
- NGINX
- SSL certificates (for secure connection)
- Project Overview
- Setting Up the Express Web Server
- Containerizing the Application
- Creating Multiple Instances with Docker Compose
- Setting Up NGINX as a Reverse Proxy
- Creating a Secure Encrypted Connection
This project demonstrates:
- A basic Express web server serving HTML files.
- Dockerizing the application.
- Running multiple instances of the app using Docker Compose.
- Using NGINX as a reverse proxy to balance requests across multiple app instances.
- Securing the connection using SSL certificates.
Create a simple index.html file.
Create a server.js file with the following code:
const express = require('express');
const path = require('path');
const app = express();
const port = 3000;
app.use('/images', express.static(path.join(__dirname, 'images')));
app.use('/', (req, res) => {
res.sendFile(path.join(__dirname, 'index.html'));
console.log("Request served by node app");
});
app.listen(port, () => {
console.log(`Node app is listening on port ${port}`);
});Run the following command to install dependencies:
npm installRun the server with:
node server.jsCreate a Dockerfile with the following content:
FROM node:14
WORKDIR /app
COPY server.js .
COPY index.html .
COPY images ./images
COPY package.json .
RUN npm install
EXPOSE 3000
CMD ["node", "server.js"]Build the Docker image:
docker build -t myapp:1.0 .Run the Docker container:
docker run -p 3000:3000 myappDefine multiple app instances in docker-compose.yaml:
services:
app1:
build: .
environment:
- APP_NAME=App1
ports:
- "30001:3000"
app2:
build: .
environment:
- APP_NAME=App2
ports:
- "30002:3000"
app3:
build: .
environment:
- APP_NAME=App3
ports:
- "30003:3000"Update the server.js to include the app name in the logs:
const express = require('express');
const path = require('path');
const app = express();
const port = 3000;
const replicaApp = process.env.APP_NAME;
app.use('/images', express.static(path.join(__dirname, 'images')));
app.use('/', (req, res) => {
res.sendFile(path.join(__dirname, 'index.html'));
console.log(`Request served by ${replicaApp}`);
});
app.listen(port, () => {
console.log(`${replicaApp} is listening on port ${port}`);
});Build and start the instances:
docker-compose up --build -dCheck the logs to ensure the multiple instances are running correctly:
docker-compose logsInstall NGINX using:
sudo apt install nginxCreate an NGINX configuration file (nginx.conf) with the following content:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
upstream nodejs_cluster {
least_conn;
server 127.0.0.1:30001;
server 127.0.0.1:30002;
server 127.0.0.1:30003;
}
server {
listen 8080;
server_name localhost;
location / {
proxy_pass http://nodejs_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
}
}
}Ensure NGINX is running and handling requests on port 8080.
Generate a self-signed SSL certificate using:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout nginx-selfsigned.key -out nginx-selfsigned.crtUpdate the NGINX configuration to use SSL:
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /path/to/nginx-selfsigned.crt;
ssl_certificate_key /path/to/nginx-selfsigned.key;
location / {
proxy_pass http://nodejs_cluster;
}
}Restart NGINX to apply the changes.
With this setup, you have:
- A basic Express web server.
- Dockerized the application and run multiple instances.
- Used NGINX as a reverse proxy for load balancing.
- Secured the connection using SSL certificates.