Docker
Dockerfile
Example
FROM ubuntu
RUN apt-get update
RUN apt-get install -y python-is-python3
RUN apt-get install -y python3-pip
RUN pip3 install flask
WORKDIR /opt/source-code
COPY app.py /opt/source-code
EXPOSE 5000
ENTRYPOINT ["flask","run","--host=0.0.0.0"]FROM
基礎 イメージを指定 します。すべてのビルドはここから始 まります。
FROM ubuntu:20.04
FROM golang:1.21-alpineCOPY
ホストからコンテナにファイルを複製 します。
# 単一ファイルを複製
COPY app.go /app/
# ディレクトリ全体を複製
COPY src/ /app/src/ADD
COPY と似 ていますが、追加 機能 があります:ファイルの解凍 、URL からのダウンロード。
# 自動解凍
ADD app.tar.gz /app/
# URL からダウンロード
ADD https://example.com/file.txt /app/RUN
コマンドを実行 し、新 しい Layer を作成 します。
# パッケージをインストール
RUN apt-get update && apt-get install -y curl
# 複数行コマンドを実行
RUN set -ex \
&& apt-get update \
&& apt-get install -y \
python3 \
python3-pipCMD
コンテナ起動 時 のデフォルトコマンド。
# 実行形式
CMD ["executable", "param1", "param2"]
# Shell 形式
CMD echo "Hello World"ENTRYPOINT
コンテナ起動 時 のメインコマンドを設定 します。上書 きされにくい。
ENTRYPOINT ["nginx", "-g", "daemon off;"]
# CMD と組み合わせて使用
ENTRYPOINT ["echo"]
# docker run のパラメータで上書き可能
CMD ["Hello World"]CMD vs ENTRYPOINT
# hard code
FROM ubuntu
CMD ["sleep","5"]
# flex
FROM ubuntu
CMD ["sleep"]
# combined
FROM ubuntu
ENTRYPOINT ["sleep"]
CMD ["5"]LABEL
イメージに metadata を追加 します。
LABEL version="1.0"
LABEL description="This is my app" \
maintainer="user@example.com"EXPOSE
コンテナが使用 するネットワークポートを宣言 します。
EXPOSE 80
EXPOSE 80/tcp
EXPOSE 80/udpENV
環境 変数 を設定 します。
ENV APP_HOME /app
ENV VERSION=1.0 DEBUG=trueVOLUME
マウントポイントを作成 します。
VOLUME /data
VOLUME ["/data", "/logs"]USER
コマンドを実行 するユーザーを指定 します。
# ユーザー名を使用
USER nginx
# UID を使用
USER 1000WORKDIR
作業 ディレクトリを設定 します。
WORKDIR /app
WORKDIR /app/srcARG
ビルド時 の変数 を定義 します。
ARG VERSION=latest
ARG BUILD_DATE
FROM ubuntu:${VERSION}ONBUILD
子 イメージビルド時 のトリガー命令 を定義 します。
ONBUILD COPY . /app/src
ONBUILD RUN /app/src/build.shSTOPSIGNAL
コンテナを停止 する時 に送信 するシステムシグナルを設定 します。
STOPSIGNAL SIGTERM
STOPSIGNAL 9SHELL
# Windows コンテナ例
SHELL ["powershell", "-Command"]
# Linux コンテナ例
SHELL ["/bin/bash", "-c"]Multi-Stage Builds
マルチステージビルド例 。最終 イメージサイズを削減 するために使用 します。
# ビルドステージ
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .
# 最終ステージ
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/main .
CMD ["./main"]Examples
Go
# ビルドステージ
FROM golang:1.21-alpine AS builder
# ビルドツールをインストール
RUN apk add --no-cache git
# 作業ディレクトリを設定
WORKDIR /app
# go mod ファイルを複製
COPY go.mod go.sum ./
# 依存パッケージをダウンロード
RUN go mod download
# ソースコードを複製
COPY . .
# アプリケーションをビルド
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
# 最終ステージ
FROM alpine:latest
# 基本ツールをインストール
RUN apk --no-cache add ca-certificates tzdata
# 非 root ユーザーを作成
RUN adduser -D appuser
# 作業ディレクトリを設定
WORKDIR /app
# ビルドステージから実行ファイルを複製
COPY --from=builder /app/main .
# 所有者を変更
RUN chown -R appuser:appuser /app
# 非 root ユーザーに切り替え
USER appuser
# ポートを公開
EXPOSE 8080
# アプリケーションを実行
CMD ["./main"]Java
# ビルドステージ
FROM maven:3.8.4-openjdk-17 AS builder
# 作業ディレクトリを設定
WORKDIR /app
# pom.xml を複製
COPY pom.xml .
# 依存パッケージをダウンロード(Docker レイヤーキャッシュを活用)
RUN mvn dependency:go-offline
# ソースコードを複製
COPY src ./src
# アプリケーションをビルド
RUN mvn clean package -DskipTests
# 最終ステージ
FROM eclipse-temurin:17-jre-alpine
# 作業ディレクトリを設定
WORKDIR /app
# 非 root ユーザーを作成
RUN addgroup -S spring && adduser -S spring -G spring
# Java オプションを設定
ENV JAVA_OPTS="-Xmx512m -Xms256m"
# タイムゾーンを設定
ENV TZ=Asia/Taipei
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# ビルド成果物(.jar ファイル)を複製
COPY --from=builder /app/target/*.jar app.jar
# 所有者を変更
RUN chown spring:spring /app
# 非 root ユーザーに切り替え
USER spring
# ポートを公開
EXPOSE 8080
# アプリケーションを起動
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]Architecture
flowchart LR C((Client)) Di((Docker image)) C --->|REST API| Di
Layer Architecture
FROM
RUN
RUN
COPY
ENTRYPOINTイメージをビルド:
docker build Dockerfile -t lexyu/my-custom-appコンテナを実行 (COPY-ON-WRITE メカニズム):
docker run lexyu/my-custom-app
Image
イメージはコンテナの基礎 として、コンテナの作成 と実行 に使用 されます。軽量 で不変 のソフトウェアパッケージで、アプリケーション実行 に必要 なすべてを含 みます:
- 簡素化 された OS(Cut-down OS)
- 必要 な実行 環境
- アプリケーションファイル
- サードパーティライブラリ
- 環境 変数
Engine

Containerization
各 コンテナ:
flowchart TD
Ns((Namespace))
PID(Process ID)
UT(Unix Timesharing)
M(Mount)
IP(InterProcess)
Nw(Network)
Ns <--> PID
Ns <--> UT
Ns <--> M
Ns <--> IP
Ns <--> Nw
Namespace - PID

cgroups

Network
Default Networks

User-defined Networks

Built-in DNS

Multiple Port Mapping

Volume
データ共有 を許可 :
- ホストとコンテナ間
- コンテナとコンテナ間

docker run -v /data/mysql:/var/lib/mysql mysql
--mount を -v の代
わりに使用
:
docker run --mount type=bind,source=/data/mysql,target=/var/lib/mysql mysql
Add Volume into Container From Host
docker run --name website -v ($pwd):/usr/share/nginx/html:ro -d -p 9000:80 nginx
Share Volumes from Specific Container
docker run --name website-copy --volumes-from website -d -p 9001:80 nginx
Docker Registry
すべての Docker イメージの中央 リポジトリ:
[Registry]/[User/Account]/[Image/Repository]gcr.io/kubernetes-e2e-test-images/dnsutilsdocker.io/nginx/nginx
Docker Storage
Linux に Docker をインストールした時 のファイルシステム:
./var/lib/docker
|_ aufs
|_ containers
|_ image
|_ volumesContainer vs Virtual Machines
Container コンテナ
アプリケーションを実行 するための隔離 された環境 。複数 のアプリケーションを隔離 された環境 で実行 できます:
- 軽量
- ホストの OS を使用
- 起動 が速 い
- ハードウェアリソースが少 なくて済 む

Virtual Machines 仮想マシン
マシン(物理 ハードウェア)の抽象化 。問題点 :
- 各 仮想 マシンに完全 な OS が必要
- 起動 が遅 い
- リソースを多 く消費

ハイパーバイザー(Hypervisor):仮想 マシンを管理 するプログラム。
Docker on Windows
