Skip to content

Latest commit

 

History

History
286 lines (219 loc) · 7.67 KB

Docker.md

File metadata and controls

286 lines (219 loc) · 7.67 KB
  • A Docker Image is a read-only template used to create [[Containerization|containers]].
    • It includes everything needed to run an application, such as code, libraries, and environment variables.
  • A container is a runnable instance of a Docker image.
    • It is isolated from other containers and the host system.
    • In multi-container setups (such as with Docker Compose), each container has its own file system, which is isolated from other containers.
  • Docker Hub is a cloud-based registry where you can find and share Docker images.
    • Images can be pulled from Docker Hub or pushed for others to use.

Dockerfile

  • A script containing a series of instructions on how to build a Docker image.
  • Specifies the base image, application code, dependencies, and commands to run the application.
# Use the official Node.js image as a base
FROM node:14

# Set the working directory
WORKDIR /app

# Copy package.json and install dependencies
COPY package*.json ./
RUN npm install

# Copy the rest of the application code
COPY . .

# Expose the application port
EXPOSE 3000

# Command to run the application
CMD ["npm", "start"]
# Inside the Project Directory
# Build the Docker image
docker build -t my-node-app .

# Run the Docker container
docker run -p 3000:3000 my-node-app
  • Multi-stage Builds allow for the creation of more efficient and smaller production images.
    • Enable use of multiple FROM statements in a Dockerfile, each of which can use a different base image.
# Build stage
FROM node:14 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# Production stage
FROM node:14-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY package*.json ./
RUN npm install --only=production
EXPOSE 3000
CMD ["node", "dist/main.js"]
# Build up to a specific stage
docker build --target builder -t myapp:build .

Docker Compose

  • A tool for defining and running multi-container Docker applications.
  • Using a docker-compose.yml file, all of the application's services (such as databases), networks, and volumes can be configured in one place.
  • Each container has its own file system, which is isolated from other containers.
  • Containers cannot access files or directories from other containers unless explicitly configured to do so.
  • Volumes are used to share files or data between containers.
    • They are managed by Docker and can be mounted into one or more containers.
  • Anatomy
    • services - where you define the various containers that make up your application.
      • Each service corresponds to a container and can include various configurations such as the image to use, build context, environment variables, and more.
      • Services can refer to each other by their service names defined in the docker-compose.yml file.
    • build - used to build a custom image for a service.
      • It points to the directory containing the Dockerfile.
    • volumes - used to persist data generated by and used by Docker containers.
      • Used to ensure data is not lost when containers are stopped.
  • Commands
    • docker compose build - builds the image.
    • docker compose up - starts all services defined in the file.
    • docker compose down - stops and removes containers, networks, volumes, and images defined in a docker-compose.yml file.
my-fullstack-app/
├── frontend/
│   ├── src/
│   │   ├── App.js
│   │   └── index.js
│   ├── package.json
│   └── Dockerfile
├── backend/
│   ├── src/
│   │   └── index.js
│   ├── package.json
│   └── Dockerfile
├── docker-compose.yml
└── .env
# Backend Dockerfile
FROM node:14
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 5000
CMD ["npm", "start"]
# Frontend Dockerfile
FROM node:14
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npx", "serve", "-s", "build"]
# docker-compose.yml
version: '3'
services:
    frontend:
        build: ./frontend
        ports:
            - "3000:3000"
        depends_on:
            - backend
    backend:
        build: ./backend
        ports:
            - "5000:5000"
        environment:
            - DATABASE_URL=postgres://user:password@db:5432/todos
        depends_on:
            - db
    db:
        image: postgres:13
        environment:
            - POSTGRES_USER=user
            - POSTGRES_PASSWORD=password
            - POSTGRES_DB=todos
        ports:
            - "5432:5432"
        volumes:
            - postgres-data:/var/lib/postgresql/data

volumes:
    postgres-data:
# Run Locally
docker compose build

docker compose up -d

docker compose down

Important

localhost or 127.0.0.1 from within a container refers to the container’s own loopback interface, not the host machine or other containers. localhost or 127.0.0.1 can be still be used (outside of Docker) to access services running on your host machine.

Containers communicate using the internal Docker network. A service (e.g. backend) cannot use localhost to connect to another service (e.g. db) because localhost would refer to the backend container itself. Instead, it should use the service name (db) as defined in your docker-compose.yml to connect to that service.

CLI

# Build an image from a `Dockerfile` in the current directory
docker build -t <image_name>:<optional_tag> .

# Create and start a container
docker run -p <host_port>:<container_port> <img_name>:<tag>

# Pull an image from a registry
docker pull <image>

# Push an image to a registry
docker push myregistry.com/<img_name>:<tag>

# List local images
docker images

# List running containers
docker ps

# Stop a running container
docker stop <container_id>

# Remove a container
docker rm <container_id>

# Clean up unused Docker objects
docker <object> prune  # Object: network, volume, image, container

# View container logs
docker logs -f <container_id>

# Execute a command in a running container
docker exec -it <container_id> /bin/bash
# Docker Compose

# Start all services defined in docker-compose.yml
docker compose up

# Start specific services
docker compose up backend db

# Start services and rebuild images
docker compose up --build


# Stop and remove all containers, networks
docker compose down

# Also remove volumes
docker compose down -v

# Remove images as well
docker compose down --rmi all


# Build or rebuild all services
docker compose build

# Build specific services
docker compose build backend db


# List all containers
docker compose ps

# List containers for specific services
docker compose ps backend db


# View logs from all services
docker compose logs

# View logs for specific services
docker compose logs web db


# Run a command in a running container
docker compose exec backend npm run test

# Open a shell in a running container
docker compose exec db bash

Further

Learn 🧠

Roadmaps 🗺

Videos 🎥

Containerization Explained

Building Docker Images - Best Practices (YouTube)

Basic Microservices (3 NodeJS + 1 Load Balancer containers) with Docker Compose