Docker使い方メモ

Programming

以前作成したWEBアプリのバックエンドとフロントエンドを再作成するのみDockerを使ってみる。

Dockerとは

Dockerは、アプリケーションをコンテナという単位でパッケージ化し、どの環境でも同じように動作させるための技術です。

コンテナ化技術 アプリケーションとその実行に必要なすべて(ライブラリ、設定ファイルなど)を1つのパッケージにまとめます。これにより「私のパソコンでは動くのに…」という問題が解決されます。

軽量で高速 仮想マシンと違い、OS全体を丸ごと起動する必要がないため、数秒で起動でき、システムリソースも少なくて済みます。

どこでも動く 開発環境、テスト環境、本番環境のどこでも同じように動作します。Windows、Mac、Linuxなど、プラットフォームを問いません。

dockerとdocker compose

Docker(基本)

単一のコンテナを管理するツールです。

  • 1つのアプリケーションやサービスをコンテナとして実行
  • コマンド例:docker rundocker 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 buildDockerfile からイメージを作成
コンテナ起動docker run -d -p 5000:5000 myappdocker compose up -dコンテナを起動(compose は複数まとめて)
コンテナ停止docker stop <コンテナ名>docker compose stopコンテナを停止
コンテナ削除docker rm <コンテナ名>docker compose downコンテナを削除(ネットワークやボリュームもまとめて消せる)
ログ確認docker logs <コンテナ名>docker compose logs <サービス名>コンテナの標準出力ログを見る
コンテナ内に入るdocker exec -it <コンテナ名> /bin/bashdocker 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

タイトルとURLをコピーしました