Skip to main content

Command Palette

Search for a command to run...

Complete Beginner's Guide to DevOps: Node.js, Nginx & Docker Step-by-Step

Published
โ€ข8 min read
Complete Beginner's Guide to DevOps: Node.js, Nginx & Docker Step-by-Step
P

Cloud DevOps Engineer with hands-on experience in containerization, orchestration, and CI/CD pipelines. Proficient in AWS services, Docker, Kubernetes, and infrastructure automation with expertise in deploying scalable web applications and managing cloud infrastructure


My DevOps Learning Journey: Node.js, Nginx & Docker Basics

This week has been an incredible journey through the fundamentals of DevOps, focusing on practical skills that every developer needs. From understanding cloud services to containerizing applications, I've gained hands-on experience with the core technologies that power modern software deployment.

Week Overview: What I Accomplished

Cloud & DevOps Foundations

  • AWS Services: Explored EC2 instances, S3 storage, and CloudFront CDN

  • Networking: Understood VPC architecture with public and private subnets

  • Storage: Deep-dived into S3 storage classes and use cases

  • Methodologies: Compared Waterfall vs Agile/Scrum approaches

Node.js & Process Management

  • Node.js Ecosystem: Mastered NVM, NPM, and package management

  • Process Management: Used PM2 for production-ready Node.js applications

  • Deployment: Successfully deployed a static Node.js application

Containerization Journey

  • Docker Fundamentals: Built custom Dockerfiles and ran containers

  • Container Registry: Pulled and ran images from DockerHub

  • Virtualization: Experimented with containerization concepts

๐Ÿ”ง Setting Up Node.js with Nginx

Step 1: Install Node.js and NPM

bash# Install Node.js (Ubuntu/Debian)
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs

# Verify installation
node --version
npm --version

Step 2: Create a Simple Node.js Application

javascript// app.js
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {
    res.json({
        message: 'Hello World from Node.js!',
        timestamp: new Date().toISOString()
    });
});

app.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});
json// package.json
{
    "name": "my-node-app",
    "version": "1.0.0",
    "main": "app.js",
    "scripts": {
        "start": "node app.js"
    },
    "dependencies": {
        "express": "^4.18.2"
    }
}

Step 3: Install and Run the Application

bash# Install dependencies
npm install

# Run the application
npm start

Step 4: Install and Configure Nginx

bash# Install Nginx
sudo apt update
sudo apt install nginx

# Start Nginx service
sudo systemctl start nginx
sudo systemctl enable nginx

# Check if Nginx is running
sudo systemctl status nginx

Step 5: Configure Nginx for Node.js

bash# Create Nginx configuration file
sudo nano /etc/nginx/sites-available/nodejs-app

Add the following basic configuration:

nginxserver {
    listen 80;
    server_name localhost;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Step 6: Enable the Nginx Configuration

bash# Enable the site
sudo ln -s /etc/nginx/sites-available/nodejs-app /etc/nginx/sites-enabled/

# Remove default configuration
sudo rm /etc/nginx/sites-enabled/default

# Test Nginx configuration
sudo nginx -t

# Restart Nginx
sudo systemctl restart nginx

Step 7: Test the Setup

bash# Start your Node.js application
npm start

# In another terminal, test the setup
curl http://localhost

๐Ÿณ Docker Basics: Step-by-Step Guide

Step 1: Install Docker

bash# Update package index
sudo apt update

# Install Docker
sudo apt install docker.io

# Start Docker service
sudo systemctl start docker
sudo systemctl enable docker

# Add user to docker group (to run without sudo)
sudo usermod -aG docker $USER

# Verify installation
docker --version

Step 2: Basic Docker Commands

bash# Check Docker info
docker info

# List running containers
docker ps

# List all containers (including stopped)
docker ps -a

# List Docker images
docker images

# Pull an image from Docker Hub
docker pull hello-world

# Run a container
docker run hello-world

# Run container in interactive mode
docker run -it ubuntu bash

# Run container in background (detached mode)
docker run -d nginx

# Stop a running container
docker stop container-id

# Remove a container
docker rm container-id

# Remove an image
docker rmi image-name

Step 3: Running Containers with Port Mapping

bash# Run Nginx container with port mapping
docker run -d -p 8080:80 nginx

# Run Node.js container with port mapping
docker run -d -p 3000:3000 node:18-alpine

# Check what's running on specific port
docker ps

Step 4: Create a Basic Dockerfile

Create a Dockerfile in your project directory:

dockerfile# Use official Node.js image
FROM node:18-alpine

# Set working directory
WORKDIR /app

# Copy package.json
COPY package.json .

# Install dependencies
RUN npm install

# Copy application files
COPY . .

# Expose port
EXPOSE 3000

# Start the application
CMD ["npm", "start"]

Step 5: Build Your Docker Image

bash# Build image from Dockerfile
docker build -t my-node-app .

# List images to verify
docker images

# Check image details
docker inspect my-node-app

Step 6: Run Your Custom Container

bash# Run your custom container
docker run -d -p 3000:3000 my-node-app

# Check if container is running
docker ps

# Test your application
curl http://localhost:3000

Step 7: Container Management Commands

bash# View container logs
docker logs container-id

# Execute command inside running container
docker exec -it container-id bash

# Copy files from container to host
docker cp container-id:/app/file.txt ./file.txt

# Copy files from host to container
docker cp ./file.txt container-id:/app/

# Get container resource usage
docker stats container-id

๐Ÿ“ Complete Project Structure

Here's how your project should be organized:

my-node-app/
โ”œโ”€โ”€ app.js
โ”œโ”€โ”€ package.json
โ”œโ”€โ”€ Dockerfile
โ””โ”€โ”€ .dockerignore

Create .dockerignore File

# .dockerignore
node_modules
npm-debug.log
.git
.gitignore
README.md

๐Ÿ”„ Complete Workflow: From Code to Container

Step 1: Prepare Your Application

bash# Create project directory
mkdir my-node-app
cd my-node-app

# Initialize npm project
npm init -y

# Install Express
npm install express

# Create your app.js file (as shown above)

Step 2: Test Locally

bash# Run application locally
npm start

# Test in browser or with curl
curl http://localhost:3000

Step 3: Create Dockerfile

dockerfileFROM node:18-alpine
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]

Step 4: Build and Run with Docker

bash# Build Docker image
docker build -t my-node-app .

# Run Docker container
docker run -d -p 3000:3000 --name my-app my-node-app

# Check if it's running
docker ps

# Test the containerized app
curl http://localhost:3000

Step 5: Configure Nginx (Optional)

bash# If using Nginx as reverse proxy
sudo systemctl start nginx

# Test through Nginx
curl http://localhost

๐Ÿ› ๏ธ Essential Linux Commands Used

During this journey, these Linux commands were essential:

bash# File operations
ls -la                  # List files with details
cd /path/to/directory   # Change directory
mkdir my-project        # Create directory
touch filename          # Create empty file
cp source dest          # Copy files
mv source dest          # Move/rename files

# Process management
ps aux                  # List running processes
kill PID               # Stop a process
top                    # Monitor system processes

# System services
sudo systemctl start service    # Start service
sudo systemctl stop service     # Stop service
sudo systemctl status service   # Check service status
sudo systemctl restart service  # Restart service

# Network and ports
netstat -tulpn         # Check listening ports
curl http://localhost  # Test HTTP endpoints
wget url              # Download files

๐Ÿ“Š Key Learnings: Agile vs Waterfall

Waterfall Approach

  • Sequential phases: Requirements โ†’ Design โ†’ Implementation โ†’ Testing โ†’ Deployment

  • Documentation-heavy: Extensive planning and documentation

  • Less flexible: Changes are difficult once a phase is complete

  • Best for: Projects with clear, stable requirements

Agile/Scrum Approach

  • Iterative cycles: Short sprints with continuous feedback

  • Adaptive: Welcomes changing requirements

  • Collaborative: Daily standups and frequent communication

  • Best for: Dynamic projects with evolving requirements

In DevOps, Agile principles align perfectly with:

  • Continuous Integration/Continuous Deployment (CI/CD)

  • Infrastructure as Code

  • Automated testing and deployment

  • Rapid iteration and feedback loops

๐ŸŽฏ Next Steps and Best Practices

Docker Best Practices Learned

  1. Use specific image tags instead of latest

  2. Minimize image layers by combining RUN commands

  3. Use .dockerignore to exclude unnecessary files

  4. Run containers as non-root users for security

  5. Keep images small using alpine variants

Nginx Best Practices

  1. Use proxy headers for proper client information

  2. Configure SSL for production environments

  3. Set up logging for monitoring and debugging

  4. Use upstream blocks for load balancing

  5. Implement health checks for reliability

Node.js Deployment Best Practices

  1. Use process managers like PM2 for production

  2. Set NODE_ENV=production for optimized performance

  3. Implement proper error handling and logging

  4. Use environment variables for configuration

  5. Monitor application metrics and health

๐Ÿš€ Real-World Application

This week's learning has practical applications:

  • Web Application Deployment: Using Nginx as a reverse proxy for Node.js applications

  • Microservices Architecture: Containerizing individual services with Docker

  • Development Workflow: Using containers for consistent development environments

  • Cloud Migration: Preparing applications for cloud deployment with containerization

๐Ÿ’ก Final Thoughts

This journey through DevOps fundamentals has been incredibly rewarding. The combination of Node.js for backend development, Nginx for web server configuration, and Docker for containerization creates a powerful foundation for modern application deployment.

Key takeaways:

  • Start with basics and build incrementally

  • Practice with real projects, not just tutorials

  • Understand the "why" behind each tool and practice

  • Documentation and community resources are invaluable

  • Every error is a learning opportunity

The beauty of DevOps lies in how these technologies work together to create efficient, scalable, and maintainable systems. As I continue this journey, I'm excited to dive deeper into orchestration, monitoring, and advanced deployment strategies.

Keep building, keep learning! ๐ŸŒŸ


This blog represents my hands-on learning experience with practical examples you can follow along. Each command and configuration has been tested and verified to work in real environments.

More from this blog

P

Pratik Raundale | DevOps Engineer | CI/CD | AWS | Jenkins | Linux Enthusiast

16 posts

Explore DevOps guides, real-world issues, and solutions by Pratik Raundale. Dive into Jenkins, AWS EC2, CI/CD, Linux automation, and cloud best practices.