Docker Fundamentals

Level: Advanced Module: Virtualization & Containers 13 min read Lesson 58 of 66

Overview

  • What you’ll learn: How to build and run application containers with Docker, including Docker Engine architecture, images and layers, Dockerfiles for reproducible builds, container lifecycle commands, volumes for persistent data, and container networking fundamentals.
  • Prerequisites: Virtualization Concepts (Lesson 54), basic command-line and file editing skills
  • Estimated reading time: 22 minutes

Introduction

Docker revolutionized software deployment by popularizing application containers — lightweight, portable, self-contained environments that package an application with all its dependencies. Unlike system containers (LXD) that run full operating systems, Docker containers typically run a single process or application, following the Unix philosophy of doing one thing well.

Docker’s key innovation is the layered image system. Each Docker image is built from a series of read-only layers, with a thin writable layer added when a container is created. This architecture enables efficient storage (shared layers are stored only once), fast distribution (only changed layers need to be transferred), and reproducible builds through Dockerfiles.

In this lesson, you will install Docker Engine on Ubuntu, understand the image and layer architecture, write Dockerfiles to build custom images, manage container lifecycles with run, exec, and logs commands, configure volumes for persistent storage, and set up container networking.

Installing Docker Engine

Docker Engine is the core runtime that builds and runs containers. On Ubuntu, the recommended installation method uses Docker’s official APT repository to ensure you receive the latest stable version.

# Remove any old Docker packages
$ sudo apt remove -y docker docker-engine docker.io containerd runc

# Install prerequisites
$ sudo apt update
$ sudo apt install -y ca-certificates curl gnupg

# Add Docker's official GPG key
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | 
    sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# Add the Docker repository
$ echo "deb [arch=$(dpkg --print-architecture) 
  signed-by=/etc/apt/keyrings/docker.gpg] 
  https://download.docker.com/linux/ubuntu 
  $(lsb_release -cs) stable" | 
  sudo tee /etc/apt/sources.list.d/docker.list

# Install Docker Engine
$ sudo apt update
$ sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin

# Add your user to the docker group
$ sudo usermod -aG docker $USER
$ newgrp docker

# Verify the installation
$ docker version
Client: Docker Engine - Community
 Version:           24.0.7
Server: Docker Engine - Community
 Version:           24.0.7

$ docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.

Docker Engine consists of three components: the dockerd daemon that manages containers, the docker CLI client, and containerd as the underlying container runtime. Adding your user to the docker group avoids the need for sudo on every Docker command.

Images and Layers

Docker images are the blueprints for containers. Each image is composed of multiple read-only layers stacked on top of each other. When you pull an image, Docker downloads only the layers not already present on your system, making image distribution efficient.

# Pull an image from Docker Hub
$ docker pull ubuntu:22.04
22.04: Pulling from library/ubuntu
a1b2c3d4e5f6: Pull complete
Digest: sha256:abc123...
Status: Downloaded newer image for ubuntu:22.04

# List local images
$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
ubuntu       22.04     a1b2c3d4e5f6   2 weeks ago    77.8MB
hello-world  latest    d2c9e2f3a4b5   3 months ago   13.3kB

# Inspect image layers
$ docker history ubuntu:22.04
IMAGE          CREATED       CREATED BY                                 SIZE
a1b2c3d4e5f6   2 weeks ago   /bin/sh -c #(nop) CMD ["/bin/bash"]        0B
<missing>      2 weeks ago   /bin/sh -c #(nop) ADD file:abc123... in /  77.8MB

# Search for images on Docker Hub
$ docker search nginx
NAME       DESCRIPTION                STARS   OFFICIAL
nginx      Official build of Nginx.   18000   [OK]

# Remove an image
$ docker rmi hello-world

# Remove all unused images
$ docker image prune -a

Each layer in an image corresponds to an instruction in the Dockerfile that created it. Layers are identified by their content hash, so identical layers are shared across images. For example, if two images are both based on ubuntu:22.04, the base layer is stored only once on disk.

Writing Dockerfiles

A Dockerfile is a text file containing instructions for building a Docker image. Each instruction creates a new layer, and Docker caches layers to speed up subsequent builds. Well-structured Dockerfiles produce smaller, more efficient images.

# Example: Dockerfile for a Node.js application
FROM node:18-alpine

# Set working directory
WORKDIR /app

# Copy dependency files first (better layer caching)
COPY package.json package-lock.json ./

# Install dependencies
RUN npm ci --only=production

# Copy application source
COPY src/ ./src/

# Create non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

# Expose the application port
EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --retries=3 
  CMD wget -qO- http://localhost:3000/health || exit 1

# Start the application
CMD ["node", "src/index.js"]
# Build the image
$ docker build -t myapp:1.0 .
[+] Building 15.2s (12/12) FINISHED
 => [1/6] FROM node:18-alpine
 => [2/6] WORKDIR /app
 => [3/6] COPY package.json package-lock.json ./
 => [4/6] RUN npm ci --only=production
 => [5/6] COPY src/ ./src/
 => [6/6] RUN addgroup -S appgroup && adduser -S appuser -G appgroup
 => exporting to image
 => naming to docker.io/library/myapp:1.0

# Build with build arguments
$ docker build --build-arg NODE_ENV=production -t myapp:prod .

# Tag an image for a registry
$ docker tag myapp:1.0 registry.example.com/myapp:1.0

# Push to a registry
$ docker push registry.example.com/myapp:1.0

# Multi-stage build example for smaller images
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/index.js"]

Key Dockerfile best practices: place instructions that change infrequently (like dependency installation) before instructions that change often (like copying source code) to maximize layer caching. Use multi-stage builds to keep final images small by separating build-time dependencies from the runtime image. Always run applications as non-root users for security.

Running Containers

The docker run command creates and starts a container from an image. Docker provides extensive options for configuring container runtime behavior, including port mapping, environment variables, resource limits, and restart policies.

# Run a container in the foreground
$ docker run --name web ubuntu:22.04 echo "Hello from container"
Hello from container

# Run a container in the background (detached)
$ docker run -d --name nginx-web -p 8080:80 nginx:latest
a1b2c3d4e5f6...

# Run with environment variables and resource limits
$ docker run -d 
    --name myapp 
    -p 3000:3000 
    -e DATABASE_URL=postgres://db:5432/app 
    -e NODE_ENV=production 
    --memory=512m 
    --cpus=1.5 
    --restart=unless-stopped 
    myapp:1.0

# List running containers
$ docker ps
CONTAINER ID   IMAGE          COMMAND                  STATUS         PORTS
a1b2c3d4e5f6   nginx:latest   "/docker-entrypoint.…"  Up 5 minutes   0.0.0.0:8080->80/tcp
b2c3d4e5f6a1   myapp:1.0      "node src/index.js"     Up 3 minutes   0.0.0.0:3000->3000/tcp

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

# Execute a command in a running container
$ docker exec -it nginx-web bash
root@a1b2c3d4e5f6:/# nginx -v
nginx version: nginx/1.25.3
root@a1b2c3d4e5f6:/# exit

# View container logs
$ docker logs myapp
$ docker logs -f --tail 100 myapp    # follow with last 100 lines

# Inspect container details
$ docker inspect myapp

# Stop and remove containers
$ docker stop myapp
$ docker rm myapp

# Remove all stopped containers
$ docker container prune

The -d flag runs the container in detached mode (background). The -p 8080:80 flag maps host port 8080 to container port 80. The --restart=unless-stopped policy ensures the container restarts automatically after a crash or system reboot. The docker exec -it command opens an interactive shell inside a running container, which is invaluable for debugging.

Volumes and Persistent Storage

Containers are ephemeral by design — when a container is removed, all data written to its writable layer is lost. Docker volumes provide persistent storage that survives container lifecycle events and can be shared between containers.

# Create a named volume
$ docker volume create app-data

# List volumes
$ docker volume ls
DRIVER    VOLUME NAME
local     app-data

# Run a container with a named volume
$ docker run -d 
    --name postgres-db 
    -v app-data:/var/lib/postgresql/data 
    -e POSTGRES_PASSWORD=secret 
    postgres:15

# Bind mount a host directory
$ docker run -d 
    --name nginx-web 
    -v /home/user/website:/usr/share/nginx/html:ro 
    -p 8080:80 
    nginx:latest

# Inspect a volume
$ docker volume inspect app-data
[
    {
        "CreatedAt": "2025-12-01T10:00:00Z",
        "Driver": "local",
        "Mountpoint": "/var/lib/docker/volumes/app-data/_data",
        "Name": "app-data"
    }
]

# Backup a volume
$ docker run --rm -v app-data:/data -v $(pwd):/backup 
    ubuntu tar czf /backup/app-data-backup.tar.gz -C /data .

# Remove a volume
$ docker volume rm app-data

# Remove all unused volumes
$ docker volume prune

Named volumes are managed by Docker and stored under /var/lib/docker/volumes/. Bind mounts map a specific host path into the container, useful for development workflows where you want live code changes to be reflected immediately. The :ro suffix makes a mount read-only for security. Always use named volumes for production data that must persist.

Container Networking

Docker creates isolated networks for containers. By default, containers on the same Docker network can communicate using container names as hostnames, providing built-in service discovery.

# List networks
$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
a1b2c3d4e5f6   bridge    bridge    local
b2c3d4e5f6a1   host      host      local
c3d4e5f6a1b2   none      null      local

# Create a custom bridge network
$ docker network create --driver bridge app-network

# Run containers on the same network
$ docker run -d --name db --network app-network 
    -e POSTGRES_PASSWORD=secret postgres:15

$ docker run -d --name app --network app-network 
    -e DATABASE_HOST=db 
    -p 3000:3000 myapp:1.0

# Containers can resolve each other by name
$ docker exec app ping -c 2 db
PING db (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.1 ms

# Connect a running container to another network
$ docker network connect app-network nginx-web

# Inspect network details
$ docker network inspect app-network

# Remove a network
$ docker network rm app-network

Custom bridge networks provide automatic DNS resolution between containers, meaning the app container can reach the database simply by using db as the hostname. This is the foundation for multi-container applications. The default bridge network does not provide DNS resolution, so custom networks are recommended for all multi-container setups.

Key Takeaways

  • Docker packages applications with their dependencies into lightweight containers using a layered image architecture that enables efficient storage, fast distribution, and reproducible builds through Dockerfiles.
  • Dockerfiles define the build process for images, and best practices include ordering instructions for layer caching, using multi-stage builds for smaller images, and running as non-root users.
  • The docker run command creates containers with options for port mapping (-p), environment variables (-e), resource limits (–memory, –cpus), and restart policies for production reliability.
  • Volumes provide persistent storage that survives container removal; named volumes are recommended for production data while bind mounts are useful for development workflows.
  • Custom bridge networks enable automatic DNS-based service discovery between containers, forming the foundation for multi-container application architectures.

What’s Next

In Lesson 59, you will learn about Docker Compose and Orchestration, which allows you to define and manage multi-container applications using a single YAML configuration file, with built-in support for service dependencies, networking, scaling, and resource management.

繁體中文

概述

  • 學習目標:了解如何使用 Docker 建構和執行應用程式容器,包括 Docker Engine 架構、映像和分層、用於可重現建構的 Dockerfile、容器生命週期命令、用於持久資料的磁碟區以及容器網路基礎。
  • 先決條件:虛擬化概念(第 54 課),基本的命令列和檔案編輯技能
  • 預計閱讀時間:22 分鐘

簡介

Docker 透過普及應用程式容器而徹底改變了軟體部署——輕量級、可移植、自包含的環境,將應用程式與其所有相依性打包在一起。與執行完整作業系統的系統容器(LXD)不同,Docker 容器通常執行單一行程或應用程式,遵循 Unix 哲學中只做好一件事的原則。

Docker 的關鍵創新是分層映像系統。每個 Docker 映像由一系列唯讀層堆疊而成,建立容器時會加入一個薄的可寫入層。這種架構實現了高效儲存(共享層只儲存一次)、快速分發(只需傳輸變更的層)以及透過 Dockerfile 實現的可重現建構。

在本課程中,您將在 Ubuntu 上安裝 Docker Engine、了解映像和層架構、編寫 Dockerfile 來建構自訂映像、使用 run、exec 和 logs 命令管理容器生命週期、設定用於持久儲存的磁碟區,以及設定容器網路。

安裝 Docker Engine

Docker Engine 是建構和執行容器的核心執行時期。在 Ubuntu 上,建議使用 Docker 官方 APT 儲存庫進行安裝。

# 安裝先決條件
$ sudo apt update
$ sudo apt install -y ca-certificates curl gnupg

# 新增 Docker 官方 GPG 金鑰和儲存庫
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | 
    sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 安裝 Docker Engine
$ sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin

# 將使用者加入 docker 群組
$ sudo usermod -aG docker $USER

# 驗證安裝
$ docker version
$ docker run hello-world

映像和分層

Docker 映像是容器的藍圖。每個映像由多個唯讀層堆疊而成。當您拉取映像時,Docker 只下載系統中尚未存在的層。

# 從 Docker Hub 拉取映像
$ docker pull ubuntu:22.04

# 列出本機映像
$ docker images

# 檢查映像層
$ docker history ubuntu:22.04

# 搜尋映像
$ docker search nginx

# 移除映像
$ docker rmi hello-world

# 移除所有未使用的映像
$ docker image prune -a

撰寫 Dockerfile

Dockerfile 是包含建構 Docker 映像指令的文字檔案。每條指令建立一個新的層,Docker 會快取層以加速後續建構。

# 範例:Node.js 應用程式的 Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production
COPY src/ ./src/
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
EXPOSE 3000
CMD ["node", "src/index.js"]

# 建構映像
$ docker build -t myapp:1.0 .

# 為登錄檔標記映像
$ docker tag myapp:1.0 registry.example.com/myapp:1.0

# 推送到登錄檔
$ docker push registry.example.com/myapp:1.0

Dockerfile 最佳實踐:將不常變更的指令(如相依性安裝)放在經常變更的指令(如複製原始碼)之前,以最大化層快取。使用多階段建構使最終映像更小。始終以非 root 使用者執行應用程式以提高安全性。

執行容器

docker run 命令從映像建立並啟動容器。Docker 提供了廣泛的選項來配置容器執行行為。

# 在背景執行容器
$ docker run -d --name nginx-web -p 8080:80 nginx:latest

# 使用環境變數和資源限制執行
$ docker run -d 
    --name myapp 
    -p 3000:3000 
    -e DATABASE_URL=postgres://db:5432/app 
    --memory=512m 
    --cpus=1.5 
    --restart=unless-stopped 
    myapp:1.0

# 列出執行中的容器
$ docker ps

# 在執行中的容器內執行命令
$ docker exec -it nginx-web bash

# 查看容器日誌
$ docker logs -f --tail 100 myapp

# 停止和移除容器
$ docker stop myapp
$ docker rm myapp

磁碟區和持久儲存

容器本質上是臨時的——當容器被移除時,寫入其可寫入層的所有資料都會遺失。Docker 磁碟區提供在容器生命週期事件中存續的持久儲存。

# 建立命名磁碟區
$ docker volume create app-data

# 使用命名磁碟區執行容器
$ docker run -d 
    --name postgres-db 
    -v app-data:/var/lib/postgresql/data 
    -e POSTGRES_PASSWORD=secret 
    postgres:15

# 繫結掛載主機目錄
$ docker run -d 
    --name nginx-web 
    -v /home/user/website:/usr/share/nginx/html:ro 
    -p 8080:80 
    nginx:latest

# 備份磁碟區
$ docker run --rm -v app-data:/data -v $(pwd):/backup 
    ubuntu tar czf /backup/app-data-backup.tar.gz -C /data .

# 移除未使用的磁碟區
$ docker volume prune

容器網路

Docker 為容器建立隔離的網路。預設情況下,同一 Docker 網路上的容器可以使用容器名稱作為主機名稱進行通訊,提供內建的服務探索。

# 建立自訂橋接網路
$ docker network create --driver bridge app-network

# 在同一網路上執行容器
$ docker run -d --name db --network app-network 
    -e POSTGRES_PASSWORD=secret postgres:15

$ docker run -d --name app --network app-network 
    -e DATABASE_HOST=db 
    -p 3000:3000 myapp:1.0

# 容器可以透過名稱解析彼此
$ docker exec app ping -c 2 db

# 檢查網路詳細資訊
$ docker network inspect app-network

重點摘要

  • Docker 使用分層映像架構將應用程式及其相依性打包到輕量級容器中,實現高效儲存、快速分發和透過 Dockerfile 實現的可重現建構。
  • Dockerfile 定義映像的建構過程,最佳實踐包括為層快取排序指令、使用多階段建構使映像更小,以及以非 root 使用者執行。
  • docker run 命令建立容器,提供連接埠對映(-p)、環境變數(-e)、資源限制(–memory、–cpus)和重新啟動策略等選項。
  • 磁碟區提供在容器移除後仍然存在的持久儲存;命名磁碟區適用於生產資料,繫結掛載適用於開發工作流程。
  • 自訂橋接網路實現容器之間基於 DNS 的自動服務探索,構成多容器應用程式架構的基礎。

下一步

在第 59 課中,您將學習 Docker Compose 和編排,它允許您使用單一 YAML 配置檔案來定義和管理多容器應用程式,內建支援服務相依性、網路、擴展和資源管理。

日本語

概要

  • 学習内容:Docker でのアプリケーションコンテナの構築と実行方法。Docker Engine アーキテクチャ、イメージとレイヤー、再現可能なビルドのための Dockerfile、コンテナライフサイクルコマンド、永続データ用のボリューム、コンテナネットワーキングの基礎を含みます。
  • 前提条件:仮想化の概念(レッスン54)、基本的なコマンドラインとファイル編集スキル
  • 推定読了時間:22分

はじめに

Docker はアプリケーションコンテナを普及させることでソフトウェアデプロイメントに革命をもたらしました。軽量でポータブルな自己完結型環境で、アプリケーションとそのすべての依存関係をパッケージ化します。完全なオペレーティングシステムを実行するシステムコンテナ(LXD)とは異なり、Docker コンテナは通常、単一のプロセスまたはアプリケーションを実行し、「一つのことをうまくやる」という Unix 哲学に従います。

Docker の主要な革新はレイヤードイメージシステムです。各 Docker イメージは一連の読み取り専用レイヤーで構成され、コンテナ作成時に薄い書き込み可能レイヤーが追加されます。このアーキテクチャにより、効率的なストレージ(共有レイヤーは一度だけ保存)、高速な配布(変更されたレイヤーのみ転送が必要)、Dockerfile による再現可能なビルドが実現されます。

このレッスンでは、Ubuntu に Docker Engine をインストールし、イメージとレイヤーアーキテクチャを理解し、カスタムイメージを構築するための Dockerfile を書き、run、exec、logs コマンドでコンテナライフサイクルを管理し、永続ストレージ用のボリュームを構成し、コンテナネットワーキングをセットアップします。

Docker Engine のインストール

Docker Engine はコンテナを構築・実行するコアランタイムです。Ubuntu では、Docker の公式 APT リポジトリを使用したインストールが推奨されます。

# 前提条件をインストール
$ sudo apt update
$ sudo apt install -y ca-certificates curl gnupg

# Docker の公式 GPG キーとリポジトリを追加
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | 
    sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# Docker Engine をインストール
$ sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin

# ユーザーを docker グループに追加
$ sudo usermod -aG docker $USER

# インストールを確認
$ docker version
$ docker run hello-world

イメージとレイヤー

Docker イメージはコンテナのブループリントです。各イメージは複数の読み取り専用レイヤーで構成されています。イメージをプルする際、Docker はシステムにまだ存在しないレイヤーのみをダウンロードします。

# Docker Hub からイメージをプル
$ docker pull ubuntu:22.04

# ローカルイメージを一覧表示
$ docker images

# イメージレイヤーを検査
$ docker history ubuntu:22.04

# イメージを検索
$ docker search nginx

# イメージを削除
$ docker rmi hello-world

# 未使用のイメージをすべて削除
$ docker image prune -a

Dockerfile の書き方

Dockerfile は Docker イメージを構築するための命令を含むテキストファイルです。各命令は新しいレイヤーを作成し、Docker はレイヤーをキャッシュして以降のビルドを高速化します。

# 例:Node.js アプリケーション用の Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production
COPY src/ ./src/
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
EXPOSE 3000
CMD ["node", "src/index.js"]

# イメージをビルド
$ docker build -t myapp:1.0 .

# レジストリ用にイメージをタグ付け
$ docker tag myapp:1.0 registry.example.com/myapp:1.0

# レジストリにプッシュ
$ docker push registry.example.com/myapp:1.0

Dockerfile のベストプラクティス:レイヤーキャッシュを最大化するため、変更頻度の低い命令(依存関係のインストールなど)を変更頻度の高い命令(ソースコードのコピーなど)の前に配置します。最終イメージを小さくするためにマルチステージビルドを使用します。セキュリティのために常に非 root ユーザーとしてアプリケーションを実行します。

コンテナの実行

docker run コマンドはイメージからコンテナを作成・起動します。Docker はコンテナのランタイム動作を構成するための広範なオプションを提供します。

# バックグラウンドでコンテナを実行
$ docker run -d --name nginx-web -p 8080:80 nginx:latest

# 環境変数とリソース制限付きで実行
$ docker run -d 
    --name myapp 
    -p 3000:3000 
    -e DATABASE_URL=postgres://db:5432/app 
    --memory=512m 
    --cpus=1.5 
    --restart=unless-stopped 
    myapp:1.0

# 実行中のコンテナを一覧表示
$ docker ps

# 実行中のコンテナ内でコマンドを実行
$ docker exec -it nginx-web bash

# コンテナログを表示
$ docker logs -f --tail 100 myapp

# コンテナの停止と削除
$ docker stop myapp
$ docker rm myapp

ボリュームと永続ストレージ

コンテナは本質的に一時的です。コンテナが削除されると、書き込み可能レイヤーに書き込まれたすべてのデータが失われます。Docker ボリュームはコンテナのライフサイクルイベントを超えて永続するストレージを提供します。

# 名前付きボリュームを作成
$ docker volume create app-data

# 名前付きボリューム付きでコンテナを実行
$ docker run -d 
    --name postgres-db 
    -v app-data:/var/lib/postgresql/data 
    -e POSTGRES_PASSWORD=secret 
    postgres:15

# ホストディレクトリをバインドマウント
$ docker run -d 
    --name nginx-web 
    -v /home/user/website:/usr/share/nginx/html:ro 
    -p 8080:80 
    nginx:latest

# ボリュームをバックアップ
$ docker run --rm -v app-data:/data -v $(pwd):/backup 
    ubuntu tar czf /backup/app-data-backup.tar.gz -C /data .

# 未使用のボリュームを削除
$ docker volume prune

コンテナネットワーキング

Docker はコンテナに分離されたネットワークを作成します。デフォルトでは、同じ Docker ネットワーク上のコンテナはコンテナ名をホスト名として使用して通信でき、組み込みのサービスディスカバリを提供します。

# カスタムブリッジネットワークを作成
$ docker network create --driver bridge app-network

# 同じネットワーク上でコンテナを実行
$ docker run -d --name db --network app-network 
    -e POSTGRES_PASSWORD=secret postgres:15

$ docker run -d --name app --network app-network 
    -e DATABASE_HOST=db 
    -p 3000:3000 myapp:1.0

# コンテナは名前で互いを解決可能
$ docker exec app ping -c 2 db

# ネットワーク詳細を検査
$ docker network inspect app-network

重要ポイント

  • Docker はレイヤードイメージアーキテクチャを使用してアプリケーションとその依存関係を軽量コンテナにパッケージ化し、効率的なストレージ、高速な配布、Dockerfile による再現可能なビルドを実現します。
  • Dockerfile はイメージのビルドプロセスを定義し、ベストプラクティスにはレイヤーキャッシュのための命令の順序付け、小さなイメージのためのマルチステージビルド、非 root ユーザーとしての実行が含まれます。
  • docker run コマンドはポートマッピング(-p)、環境変数(-e)、リソース制限(–memory、–cpus)、本番環境の信頼性のための再起動ポリシーなどのオプションでコンテナを作成します。
  • ボリュームはコンテナ削除後も永続するストレージを提供します。名前付きボリュームは本番データに推奨され、バインドマウントは開発ワークフローに便利です。
  • カスタムブリッジネットワークはコンテナ間の DNS ベースの自動サービスディスカバリを可能にし、マルチコンテナアプリケーションアーキテクチャの基盤を形成します。

次のステップ

レッスン59では、Docker Compose とオーケストレーションについて学びます。単一の YAML 構成ファイルを使用してマルチコンテナアプリケーションを定義・管理し、サービス依存関係、ネットワーキング、スケーリング、リソース管理の組み込みサポートについて学びます。

You Missed