以前作成したWEBアプリのバックエンドとフロントエンドを再作成するのみDockerを使ってみる。
Dockerとは
Dockerは、アプリケーションをコンテナという単位でパッケージ化し、どの環境でも同じように動作させるための技術です。
コンテナ化技術 アプリケーションとその実行に必要なすべて(ライブラリ、設定ファイルなど)を1つのパッケージにまとめます。これにより「私のパソコンでは動くのに…」という問題が解決されます。
軽量で高速 仮想マシンと違い、OS全体を丸ごと起動する必要がないため、数秒で起動でき、システムリソースも少なくて済みます。
どこでも動く 開発環境、テスト環境、本番環境のどこでも同じように動作します。Windows、Mac、Linuxなど、プラットフォームを問いません。
dockerとdocker compose
Docker(基本)
単一のコンテナを管理するツールです。
- 1つのアプリケーションやサービスをコンテナとして実行
- コマンド例:
docker run、docker buildなど - 1つずつコンテナを起動・管理する
例えば: Webサーバーだけを起動する、データベースだけを起動する、といった単体での利用に向いています。
Docker Compose
複数のコンテナをまとめて管理するツールです。
- 複数のサービス(コンテナ)を一度に定義・起動できる
docker-compose.ymlというファイルに設定を記述- 1つのコマンドで全てのコンテナを起動・停止できる
- コンテナ間のネットワークや依存関係も簡単に設定可能
例えば: Webアプリケーション全体を動かす場合
- Webサーバー(Nginx)
- アプリケーションサーバー(Node.js)
- データベース(PostgreSQL)
- キャッシュサーバー(Redis)
これら全てを1つのdocker-compose.ymlに書いて、docker-compose upコマンド1つで全部まとめて起動できます。
基本コマンド
| 操作 | docker コマンド(単体) | docker compose コマンド(複数サービス) | 説明 |
|---|---|---|---|
| イメージ一覧 | docker images | – | ローカルにあるイメージを表示 |
| コンテナ一覧 | docker ps(稼働中)docker ps -a(全て) | docker compose ps | コンテナの状態を確認 |
| イメージ作成 | docker build -t myapp . | docker compose build | Dockerfile からイメージを作成 |
| コンテナ起動 | docker run -d -p 5000:5000 myapp | docker compose up -d | コンテナを起動(compose は複数まとめて) |
| コンテナ停止 | docker stop <コンテナ名> | docker compose stop | コンテナを停止 |
| コンテナ削除 | docker rm <コンテナ名> | docker compose down | コンテナを削除(ネットワークやボリュームもまとめて消せる) |
| ログ確認 | docker logs <コンテナ名> | docker compose logs <サービス名> | コンテナの標準出力ログを見る |
| コンテナ内に入る | docker exec -it <コンテナ名> /bin/bash | docker compose exec <サービス名> /bin/bash | コンテナに入ってコマンド実行 |
| 再起動 | docker restart <コンテナ名> | docker compose restart <サービス名> | コンテナを再起動 |
| イメージ削除 | docker rmi <イメージID> | – | イメージを削除 |
| 全リソース削除 | docker system prune | – | 不要なコンテナ/ネットワーク/イメージを一括削除 |
docker-compose.yml の書き方
Docker Composeの設定ファイル docker-compose.yml の書き方を説明します。
基本構造
version: '3.8' # Docker Composeのバージョン
services: # 起動するコンテナ(サービス)を定義
サービス名1:
# 設定内容
サービス名2:
# 設定内容
volumes: # データを永続化する場合(オプション)
networks: # ネットワーク設定(オプション)
実践的な例
例1:シンプルなWebアプリ + データベース
version: '3.8'
services:
# Webアプリケーション
web:
image: nginx:latest # 使用するイメージ
ports:
- "8080:80" # ホスト:コンテナ のポート番号
volumes:
- ./html:/usr/share/nginx/html # ファイル共有
depends_on:
- db # dbの起動を待つ
# データベース
db:
image: postgres:15
environment: # 環境変数
POSTGRES_PASSWORD: mypassword
POSTGRES_USER: myuser
POSTGRES_DB: mydb
volumes:
- db-data:/var/lib/postgresql/data # データ永続化
ports:
- "5432:5432"
volumes:
db-data: # 名前付きボリューム
例2:自作アプリをビルドする場合
version: '3.8'
services:
app:
build:
context: . # Dockerfileの場所
dockerfile: Dockerfile # Dockerfileの名前
ports:
- "3000:3000"
environment:
NODE_ENV: development
DATABASE_URL: postgresql://user:pass@db:5432/mydb
volumes:
- .:/app # コード変更を即反映
- /app/node_modules # node_modulesは除外
command: npm run dev # 起動コマンド
depends_on:
- db
- redis
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: password
volumes:
- postgres-data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres-data:
主要な設定項目
イメージ関連
image:– Docker Hubからイメージを取得build:– Dockerfileからビルド
ポート
ports:– ホストとコンテナのポートをマッピング
環境変数
environment:– 環境変数を設定env_file:– .envファイルから読み込み
ボリューム(データ保存)
volumes:– ファイル共有やデータ永続化
その他
command:– コンテナ起動時のコマンドdepends_on:– 起動順序の制御restart:– 再起動ポリシー(always,unless-stoppedなど)networks:– ネットワーク設定
Dockerfileの書き方
Dockerfileの書き方を説明します。Dockerfileは、Dockerイメージを作成するための設計図です。
基本構造
# ベースイメージの指定
FROM イメージ名:タグ
# 作業ディレクトリの設定
WORKDIR /app
# ファイルのコピー
COPY ソース 宛先
# コマンドの実行
RUN コマンド
# 環境変数の設定
ENV 変数名=値
# ポートの公開
EXPOSE ポート番号
# コンテナ起動時のコマンド
CMD ["実行ファイル", "引数"]
実践的な例
例1:Node.jsアプリケーション
# ベースイメージ
FROM node:18-alpine
# 作業ディレクトリを設定
WORKDIR /app
# package.jsonをコピー(依存関係のインストール用)
COPY package*.json ./
# 依存関係をインストール
RUN npm install
# アプリケーションのコードをコピー
COPY . .
# アプリケーションが使用するポート
EXPOSE 3000
# コンテナ起動時に実行するコマンド
CMD ["npm", "start"]
例2:Pythonアプリケーション
FROM python:3.11-slim
WORKDIR /app
# 依存関係ファイルをコピー
COPY requirements.txt .
# Pythonパッケージをインストール
RUN pip install --no-cache-dir -r requirements.txt
# アプリケーションコードをコピー
COPY . .
EXPOSE 8000
# Flaskアプリを起動
CMD ["python", "app.py"]
例3:マルチステージビルド(本番用)
# ビルド用ステージ
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
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
COPY package*.json ./
EXPOSE 3000
CMD ["node", "dist/index.js"]
主要な命令
FROM
FROM ubuntu:22.04
FROM node:18-alpine # alpine = 軽量版
ベースとなるイメージを指定
WORKDIR
WORKDIR /app
作業ディレクトリを設定(以降のコマンドはここで実行される)
COPY vs ADD
COPY ./src /app/src # 推奨:シンプルなファイルコピー
ADD archive.tar.gz /app # 自動解凍機能あり(特別な理由がない限りCOPYを使う)
RUN
RUN apt-get update && apt-get install -y \
curl \
git \
&& rm -rf /var/lib/apt/lists/* # キャッシュ削除で軽量化
イメージビルド時にコマンドを実行
ENV
ENV NODE_ENV=production
ENV PORT=3000
環境変数を設定
EXPOSE
EXPOSE 8080
コンテナが使用するポートを宣言(ドキュメント的な意味合い)
CMD vs ENTRYPOINT
# CMD:上書き可能
CMD ["npm", "start"]
# ENTRYPOINT:上書きされない(引数は追加可能)
ENTRYPOINT ["python", "app.py"]
# 組み合わせ
ENTRYPOINT ["python"]
CMD ["app.py"] # デフォルト引数
ベストプラクティス
1. レイヤーを最小化
# ❌ 悪い例(レイヤーが増える)
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y git
# ✅ 良い例(1つにまとめる)
RUN apt-get update && apt-get install -y \
curl \
git \
&& rm -rf /var/lib/apt/lists/*
2. キャッシュを活用
# 変更が少ないものを先にコピー
COPY package.json .
RUN npm install
# 変更が多いものは後で
COPY . .
3. .dockerignoreを使う
プロジェクトルートに .dockerignore を作成:
node_modules
.git
.env
*.log
dist
ビルドと実行
# イメージをビルド
docker build -t myapp:latest .
# タグ付きでビルド
docker build -t myapp:v1.0 .
# 特定のDockerfileを指定
docker build -f Dockerfile.prod -t myapp:prod .
# コンテナを起動
docker run -p 3000:3000 myapp:latest

