Docker: アプリケーションのコンテナか

最終更新:2026-08-26

フェーズ 2 のちしきをくみあわせ、ソースコードからほんばんむけイメージまで、Web アプリケーションをかんぜんにコンテナかします。

1. まなべること



2. レガシープロジェクトをひきついだはなし

(1) こまりごと: Docker でうごかないレガシープロジェクト

Alice がひきついだ Python プロジェクトは、Dockerfile が 1.2 GB のイメージをつくり、ビルドに 10 ぷんかかっていました。ヘルスチェックはなく、ログはコンテナないにかかれてさいきどうでうしなわれ、root でうごき、かんきょうへんすうもハードコードされていました。デプロイには 30 ぷんかかり、あんていしません。

(2) かんぜんなコンテナかによるかいけつ

Bob はいぞんかんけいをしらべ、マルチステージ Dockerfile、ログえいぞくか、ヘルスチェック、root ではないユーザーでのじっこうをせっていしました。そのけっか、ビルドとデプロイは 3 ぷんみまんになりました。

DOCKERFILE
# ほんばんむけマルチステージ Dockerfile
FROM python:3.12-slim AS builder
# ... さいてきかした venv をビルド

FROM python:3.12-slim
# ... venv をコピーし、root ではないユーザーとヘルスチェックをせってい

(3) こうか: 30 ぷんから 3 ぷんへ

しひょう さいてきかまえ さいてきかご
イメージサイズ 1.2 GB 150 MB
ビルドじかん 10 ぷん 3 ぷん
デプロイじかん 30 ぷん 3 ぷん
セキュリティスコア 45 85


3. プロジェクトアーキテクチャ

(1) アプリケーションのこうせい

このレッスンでは Flask + PostgreSQL + Nginx の Todo リストアプリケーションをコンテナかします。

100%
graph TB
    USER["ブラウザー"] --> NGX["Nginx<br/>リバースプロキシ + スタティックファイル"]
    NGX -->|"proxy_pass :5000"| APP["Flask アプリ<br/>Todo API + UI"]
    APP -->|"psycopg2 :5432"| DB["PostgreSQL<br/>Todo データベース"]
    DB --> VOL["なまえつきボリューム<br/>pg-data"]
    APP --> LOGS["なまえつきボリューム<br/>app-logs"]

(2) コンテナかのほうしん

コンポーネント ベースイメージ ポリシー
Flask アプリ python:3.12-slim マルチステージ + root ではないユーザー + HEALTHCHECK
PostgreSQL postgres:15-alpine オフィシャルイメージ + なまえつきボリューム
Nginx nginx:1.25-alpine オフィシャルイメージ + せっていファイルのバインドマウント


4. Flask アプリの Dockerfile

(1) プロジェクトこうせい

TEXT 📖 参照専用
todo-app/
├── app.py              # Flask アプリケーション
├── requirements.txt    # Python のいぞんかんけい
├── templates/          # HTML テンプレート
│   └── index.html
├── Dockerfile          # ほんばんむけマルチステージビルド
├── .dockerignore       # いらないファイルをのぞく
├── nginx.conf          # Nginx リバースプロキシせってい
└── docker-run.sh       # ワンクリックデプロイスクリプト

▶ サンプル: マルチステージ Dockerfile をかく (むずかしさ: ⭐⭐⭐)

DOCKERFILE
# ============================================
# Flask Todo アプリのマルチステージ Dockerfile
# ステージ 1: かそうかんきょうをビルド
# ステージ 2: ほんばんランタイム
# ============================================

# ---------- ステージ 1: ビルダー ----------
FROM python:3.12-slim AS builder

WORKDIR /build

# キャッシュ: いぞんかんけいをさきにインストール
COPY requirements.txt .
RUN python -m venv /opt/venv && \
    /opt/venv/bin/pip install --no-cache-dir -r requirements.txt

# ---------- ステージ 2: ほんばん ----------
FROM python:3.12-slim

# ヘルスチェックように curl をインストール
RUN apt-get update && \
    apt-get install -y --no-install-recommends curl && \
    rm -rf /var/lib/apt/lists/*

# root ではないユーザーをさくせい
RUN groupadd -r appgroup && \
    useradd -r -g appgroup -u 1000 -m -d /home/appuser appuser

WORKDIR /app

# ビルダーからかそうかんきょうをコピー
COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"

# アプリケーションコードをコピー
COPY --chown=appuser:appgroup . .

# ログディレクトリをさくせい
RUN mkdir -p /app/logs && chown appuser:appgroup /app/logs

# root ではないユーザーへきりかえ
USER appuser

# かんきょうへんすうはじっこうじにうわがきできる
ENV FLASK_ENV=production \
    LOG_LEVEL=info \
    APP_PORT=5000

EXPOSE 5000

# ヘルスチェック
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
  CMD curl -f http://localhost:5000/health || exit 1

# アプリケーションをかいし
CMD ["python", "app.py"]

(2) .dockerignore

TEXT 📖 参照専用
# .dockerignore
__pycache__
*.pyc
*.pyo
.git
.env
venv
.venv
*.md
Dockerfile
docker-compose*.yml


5. かんきょうせっていのかんり

(1) かんきょうへんすうのゆうせんじゅんい

レベル ほうほう ゆうせんど むいているばめん
Dockerfile ENV デフォルトち ひくい (1) きょうつうのデフォルト
docker run -e じっこうじのうわがき ふつう (2) デプロイせってい
.env ファイル --env-file たかい (3) たくさんのへんすう
Docker Secrets --secret もっともたかい センシティブなじょうほう

▶ サンプル: かんきょうへんすうをせっていする (むずかしさ: ⭐⭐)

BASH
# カスタムかんきょうへんすうでじっこう
docker run -d \
  --name todo-app \
  -e FLASK_ENV=production \
  -e DATABASE_URL="postgresql://appuser:apppass@todo-db:5432/tododb" \
  -e LOG_LEVEL=warning \
  -p 5000:5000 \
  todo-app:1.0

▶ サンプル: .env ファイルをつかう (むずかしさ: ⭐⭐)

BASH
# .env ファイルをさくせい
cat > .env << 'EOF'
FLASK_ENV=production
DATABASE_URL=postgresql://appuser:apppass@todo-db:5432/tododb
LOG_LEVEL=warning
APP_PORT=5000
EOF

# --env-file でじっこう
docker run -d \
  --name todo-app \
  --env-file .env \
  -p 5000:5000 \
  todo-app:1.0


6. ログのえいぞくか

▶ サンプル: ログをえいぞくかする (むずかしさ: ⭐⭐)

BASH
# アプリログようになまえつきボリュームをマウント
docker run -d \
  --name todo-app \
  -v app-logs:/app/logs \
  -e LOG_LEVEL=info \
  todo-app:1.0

(1) ログポリシーのくらべかた

ほうほう メリット デメリット
コンテナないのログファイル かんたん コンテナさくじょでうしなわれる
ボリュームえいぞくか コンテナさくじょごものこる ローテーションをてさぎょうでかんり
stdout + log driver Docker ひょうじゅんのかんり せっていがふくざつ
しゅうやくログ (ELK/Loki) すべてをけんさくできる ついかのインフラがひつよう


7. イメージタグとバージョンかんり

(1) タグのつけかた

ほうしん タグのかたち サンプル むいているばめん
セマンティックバージョン vMajor.Minor.Patch v2.1.0 ほんばんリリース
Git SHA sha-<commit> sha-a1b2c3d CI/CD のトレース
latest latest latest かいはつやクイックスタート
ブランチめい <branch> main, dev かいはつかんきょう

▶ サンプル: ふくすうタグをプッシュする (むずかしさ: ⭐⭐)

BASH
# ふくすうのタグでビルド
docker build -t todo-app:v1.0.0 -t todo-app:latest .

# すべてのタグをプッシュ
docker push localhost:5000/todo-app:v1.0.0
docker push localhost:5000/todo-app:latest


8. フルスタックのデプロイ

▶ サンプル: Flask + PostgreSQL + Nginx をまとめてデプロイ (むずかしさ: ⭐⭐⭐)

BASH
# ============================================
# ワンクリックデプロイスクリプト
# ============================================

# 1. ネットワークとボリュームをさくせい
docker network create todo-net
docker volume create pg-data
docker volume create app-logs

# 2. PostgreSQL をかいし
docker run -d \
  --name todo-db \
  --network todo-net \
  -e POSTGRES_USER=appuser \
  -e POSTGRES_PASSWORD=apppass \
  -e POSTGRES_DB=tododb \
  -v pg-data:/var/lib/mysql \
  --restart=unless-stopped \
  postgres:15-alpine

# 3. PostgreSQL のしょきかをまつ
sleep 15

# 4. Flask アプリをビルドしてかいし
docker build -t todo-app:1.0 ./todo-app
docker run -d \
  --name todo-app \
  --network todo-net \
  -e DATABASE_URL="postgresql://appuser:apppass@todo-db:5432/tododb" \
  -v app-logs:/app/logs \
  --restart=unless-stopped \
  todo-app:1.0

# 5. Nginx リバースプロキシをかいし
docker run -d \
  --name todo-nginx \
  --network todo-net \
  -p 80:80 \
  -v $(pwd)/todo-app/nginx.conf:/etc/nginx/conf.d/default.conf \
  --restart=unless-stopped \
  nginx:1.25-alpine

# 6. かくにん
docker ps
curl http://localhost/health


9. けんしょうとさいてきかのけっか

(1) dive でさいてきかをけんしょう

BASH
# マルチステージイメージをぶんせき
dive todo-app:1.0

# きたいち: こうりつスコア > 90%、むだなスペースなし

(2) イメージサイズのくらべかた

バージョン Dockerfile イメージサイズ ビルドじかん
V1 シングルステージ FROM python:3.12 + COPY . . + RUN pip install 1.2 GB 5 ふん
V2 さいてきかしたベース FROM python:3.12-slim + キャッシュクリア 350 MB 3 ぷん
V3 マルチステージ builder + slim + root ではないユーザー + HEALTHCHECK 150 MB 3 ぷん (キャッシュヒットなら 30 びょう)


10. かんぜんなサンプル: Todo リストアプリのコンテナか

BASH
# ============================================
# Flask アプリをコンテナかするながれ
# Dockerfile、ビルド、マルチコンテナデプロイ
# ============================================

# 1. さいてきかイメージをビルド
docker build -t todo-app:v1.0.0 -t todo-app:latest ./todo-app

# 2. イメージをかくにん
docker images todo-app
docker history todo-app:v1.0.0

# 3. インフラをさくせい
docker network create todo-net
docker volume create pg-data
docker volume create app-logs

# 4. えいぞくストレージつき PostgreSQL をかいし
docker run -d \
  --name todo-db \
  --network todo-net \
  -e POSTGRES_USER=appuser \
  -e POSTGRES_PASSWORD=apppass \
  -e POSTGRES_DB=tododb \
  -v pg-data:/var/lib/postgresql/data \
  --restart=unless-stopped \
  postgres:15-alpine

# 5. Flask アプリをかいし
docker run -d \
  --name todo-app \
  --network todo-net \
  -e DATABASE_URL="postgresql://appuser:apppass@todo-db:5432/tododb" \
  -v app-logs:/app/logs \
  --restart=unless-stopped \
  todo-app:v1.0.0

# 6. Nginx リバースプロキシをかいし
docker run -d \
  --name todo-nginx \
  --network todo-net \
  -p 8080:80 \
  -v $(pwd)/todo-app/nginx.conf:/etc/nginx/conf.d/default.conf \
  --restart=unless-stopped \
  nginx:1.25-alpine

# 7. フルスタックをかくにん
echo "=== Containers ===" && docker ps
echo "=== Health Check ===" && docker inspect todo-app --format='{{.State.Health.Status}}'
echo "=== App Response ===" && curl -s http://localhost:8080/health

# 8. プライベートレジストリへプッシュ
docker tag todo-app:v1.0.0 localhost:5000/todo-app:v1.0.0
docker push localhost:5000/todo-app:v1.0.0

# 9. クリーンアップ
# docker stop todo-nginx todo-app todo-db
# docker rm todo-nginx todo-app todo-db

❓ よくある質問

Q ひとつのコンテナではひとつのプロセスだけをうごかしますか?
A Flask、Nginx、PostgreSQL をべつべつのコンテナにする「1 コンテナ、1 プロセス」がおすすめです。こべつにスケールやこうしんができ、しょうがいもきりはなせます。
Q ログはコンテナないとボリュームのどちらへかきますか?
A アプリから stdout とファイルのりょうほうへだし、ファイルはボリュームへほぞんできます。ほんばんでは stdout と ELK/Loki などのしゅうやくログをくみあわせるほうほうがおすすめです。
Q ビルドでかいはつとほんばんをわけるにはどうしますか?
A Dockerfile.dev と Dockerfile.prod をわけるか、マルチステージビルドと --target をつかいます。ENV にデフォルトをおき、docker run -e でうわがきするほうほうもあります。
Q イメージのバージョンはどうかんりしますか?
A SemVer の v2.1.0 と、トレースようの Git SHA タグをつかいます。latest はさいしんのあんていばんをしめせますが、ほんばんではせいかくなバージョンをしていしてください。
Q コンテナのタイムゾーンはどうせっていしますか?
A docker run -e TZ=Asia/Tokyo をつかうか、-v /etc/localtime:/etc/localtime:ro でホストのタイムゾーンをつかいます。Alpine では TZ に tzdata がひつようです。

📖 まとめ


📝 練習問題

  1. きほん (むずかしさ: ⭐): オープンソースの Flask または Express プロジェクトへ Dockerfile をかき、イメージをビルドしてじっこうしてください。
  2. おうよう (むずかしさ: ⭐⭐): マルチステージ Dockerfile をかき、シングルステージとのイメージサイズをくらべてください。
  3. ちょうせん (むずかしさ: ⭐⭐⭐): dive でさいてきかずみイメージをしらべ、さらにさくげんできるレイヤーをみつけてなおし、サイズのへんかをたしかめてください。
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%