Learnwizy Technologies Logo

Learnwizy Technologies

Class 37: Docker & Containerization

A common challenge in software development is ensuring that an application runs consistently across different environments (developer's machine, testing server, production server). This is often referred to as the "It works on my machine!" problem. Containerization, with Docker as its leading platform, solves this by packaging an application and all its dependencies into a single, isolated unit.


What is Containerization?

Containers vs. Virtual Machines

Introduction to Docker

Docker is the world's leading software containerization platform. It enables developers to build, ship, and run applications in containers.


Basic Docker Commands

First, ensure you have Docker Desktop installed (includes Docker Engine, CLI, Docker Compose).


Creating a Dockerfile for a Node.js Application

A Dockerfile is a text file that contains a sequence of commands that Docker uses to build an image.

Let's create a Dockerfile for a simple Node.js Express app.

# Dockerfile for a Node.js Express app

# Stage 1: Build Stage (for installing dependencies)
FROM node:18-alpine AS builder

# Set the working directory inside the container
WORKDIR /app

# Copy package.json and package-lock.json (or yarn.lock)
# to leverage Docker's caching for dependencies
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application code
COPY . .

# Stage 2: Production Stage (for running the application)
FROM node:18-alpine

# Set the working directory
WORKDIR /app

# Copy only the necessary files from the builder stage
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/.env ./.env # If you use .env in production (though not recommended)
COPY --from=builder /app/server.js ./server.js
COPY --from=builder /app/package.json ./package.json # Keep package.json for npm start
# Copy other app files like routes, models, config, etc.
COPY --from=builder /app/config ./config
COPY --from=builder /app/models ./models
COPY --from=builder /app/middleware ./middleware
COPY --from=builder /app/utils ./utils
COPY --from=builder /app/knexfile.js ./knexfile.js
COPY --from=builder /app/db ./db

# Expose the port your app runs on
EXPOSE 3000

# Command to run the application when the container starts
CMD ["node", "server.js"]

Key Dockerfile Instructions:

Building and Running the Docker Image:

# Build the Docker image (from the directory containing Dockerfile)
# -t: tag the image with a name (e.g., my-node-app)
# .: build context (current directory)
docker build -t my-node-app .

# Run the Docker container
# -p 3000:3000: map host port 3000 to container port 3000
# --name: give a name to your container
# my-node-app: the image name to run
docker run -p 3000:3000 --name my-running-app my-node-app

Now, your Node.js application is running inside a Docker container, isolated from your host system! You can access it via http://localhost:3000.


Multi-Stage Docker Builds

The Dockerfile above uses a multi-stage build. This is a best practice to create optimized and smaller production images.


Docker Networking

Docker containers can communicate with each other. By default, containers on the same Docker network can resolve each other by their container names.


Managing Persistent Data with Docker Volumes

Containers are designed to be ephemeral (temporary). If you stop and remove a container, any data written inside it is lost. To persist data (e.g., for databases), you use Docker Volumes.


Introduction to Docker Compose

For multi-container applications (like a backend API, a database, and a frontend server), manually managing individual docker run commands becomes tedious. Docker Compose is a tool for defining and running multi-container Docker applications.


Introduction to CI/CD with Docker (Conceptual)

Continuous Integration (CI) and Continuous Delivery/Deployment (CD) are practices that automate the software release process. Docker plays a crucial role in enabling CI/CD pipelines.

Docker and containerization are transformative technologies that have revolutionized how applications are developed, shipped, and run. They provide consistency, efficiency, and scalability, making them indispensable for modern full-stack development. In the next class, we'll explore Serverless Functions, another powerful cloud deployment paradigm.