Docker完全ガイド:概要から実践まで

1. Dockerとは何か

Dockerは、アプリケーションとその依存関係を軽量なコンテナにパッケージ化し、どこでも実行できるようにするコンテナ化プラットフォームです。「Build once, run anywhere」(一度構築すれば、どこでも実行)の理念のもと、開発者が環境の違いを気にすることなく、一貫したアプリケーションの実行環境を提供します。

1.1 仮想化との違い

従来の仮想化技術(VMware、VirtualBoxなど)では、ハードウェア全体を仮想化し、各仮想マシンが独自のOSを持ちます。一方、Dockerはホストマシンのカーネルを共有し、アプリケーションレベルでの仮想化を実現します。これにより、軽量で高速な起動が可能になります。

2. Dockerの特徴

2.1 軽量性

  • コンテナは仮想マシンよりもはるかに軽量
  • 秒単位での起動・停止が可能
  • リソース使用量が最小限

2.2 ポータビリティ

  • 開発環境、テスト環境、本番環境での一貫性を保証
  • 異なるホストマシンで同じように動作
  • クラウドプロバイダー間での移植性

2.3 スケーラビリティ

  • 負荷に応じた自動スケーリング
  • マイクロサービスアーキテクチャとの親和性
  • オーケストレーション技術との連携

2.4 イミュータビリティ

  • コンテナイメージは不変
  • 一度作成されたイメージは変更されない
  • 環境の一貫性を保証

2.5 隔離性

  • アプリケーション間の分離
  • セキュリティの向上
  • 依存関係の競合を回避

3. Dockerの歴史

3.1 誕生と初期の発展

  • 2013年3月: Solomon Hykes率いるdotCloudによってDockerが発表
  • 2013年10月: Docker Inc.として独立
  • 2014年6月: Docker 1.0リリース

3.2 主要なマイルストーン

  • 2014年: Docker Hubのローンチ
  • 2015年: Docker Composeの統合
  • 2016年: Docker Swarmの発表
  • 2017年: Docker CEとDocker EEの分離
  • 2019年: Docker Desktop for Windowsの改良
  • 2020年: Dockerのオープンソース化推進

3.3 現在の状況

Dockerは現在、コンテナ化技術の事実上の標準となり、Kubernetes、Amazon ECS、Google Cloud Runなど、多くのクラウドサービスで採用されています。

4. 使用方法

4.1 基本的なDockerコマンド

# Docker バージョン確認
docker --version

# イメージの検索
docker search nginx

# イメージのダウンロード
docker pull nginx

# イメージ一覧の表示
docker images

# コンテナの実行
docker run -d -p 8080:80 nginx

# 実行中のコンテナ一覧
docker ps

# 全てのコンテナ一覧
docker ps -a

# コンテナの停止
docker stop <コンテナID>

# コンテナの削除
docker rm <コンテナID>

# イメージの削除
docker rmi <イメージID>

4.2 Dockerfileの基本

# ベースイメージの指定
FROM node:18-alpine

# 作業ディレクトリの設定
WORKDIR /app

# パッケージファイルのコピー
COPY package*.json ./

# 依存関係のインストール
RUN npm install

# アプリケーションのコピー
COPY . .

# ポートの公開
EXPOSE 3000

# 実行コマンド
CMD ["npm", "start"]

4.3 Docker Composeの使用

version: '3.8'

services:
  web:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - .:/app
    depends_on:
      - db
    environment:
      - NODE_ENV=development

  db:
    image: postgres:13
    environment:
      - POSTGRES_DB=myapp
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

5. 関連フレームワークとツール

5.1 オーケストレーションツール

Kubernetes

  • 大規模なコンテナ管理
  • 自動スケーリング
  • サービスディスカバリー
  • ローリングアップデート

Docker Swarm

  • Dockerネイティブのオーケストレーション
  • 簡単なセットアップ
  • 内蔵ロードバランサー

5.2 CI/CDツール

GitHub Actions

name: Docker Build and Push

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Build Docker image
      run: docker build -t myapp .
    - name: Push to registry
      run: docker push myapp

GitLab CI

stages:
  - build
  - deploy

build:
  stage: build
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

5.3 監視・ログ管理

Prometheus + Grafana

version: '3.8'

services:
  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml

  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
    depends_on:
      - prometheus

6. コーディング例

6.1 Node.js Webアプリケーション

app.js

const express = require('express');
const app = express();
const port = process.env.PORT || 3000;

app.get('/', (req, res) => {
  res.json({
    message: 'Hello from Docker!',
    timestamp: new Date().toISOString(),
    environment: process.env.NODE_ENV || 'development'
  });
});

app.get('/health', (req, res) => {
  res.status(200).json({ status: 'healthy' });
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

package.json

{
  "name": "docker-node-app",
  "version": "1.0.0",
  "description": "Sample Node.js app with Docker",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js"
  },
  "dependencies": {
    "express": "^4.18.2"
  },
  "devDependencies": {
    "nodemon": "^2.0.20"
  }
}

Dockerfile

FROM node:18-alpine

WORKDIR /app

COPY package*.json ./

RUN npm ci --only=production

COPY . .

EXPOSE 3000

USER node

CMD ["npm", "start"]

6.2 Python Flask アプリケーション

app.py

from flask import Flask, jsonify
import os
from datetime import datetime

app = Flask(__name__)

@app.route('/')
def hello():
    return jsonify({
        'message': 'Hello from Docker!',
        'timestamp': datetime.now().isoformat(),
        'environment': os.environ.get('FLASK_ENV', 'development')
    })

@app.route('/health')
def health():
    return jsonify({'status': 'healthy'}), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

requirements.txt

Flask==2.3.3
gunicorn==21.2.0

Dockerfile

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 5000

CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]

6.3 マルチステージビルド例

# Build stage
FROM node:18-alpine AS builder

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .
RUN npm run build

# Production stage
FROM nginx:alpine

COPY --from=builder /app/dist /usr/share/nginx/html

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

7. ベストプラクティス

7.1 セキュリティ

  • 最小権限の原則
  • non-rootユーザーでの実行
  • 機密情報の環境変数管理
  • 定期的なイメージの更新

7.2 パフォーマンス

  • レイヤーキャッシュの活用
  • .dockerignoreファイルの使用
  • マルチステージビルドの採用
  • 不要なパッケージの削除

7.3 保守性

  • 明確な命名規則
  • 適切なタグ付け
  • ドキュメンテーションの充実
  • 定期的なクリーンアップ

8. まとめ

Dockerは現代のソフトウェア開発において不可欠なツールとなっています。その軽量性、ポータビリティ、スケーラビリティにより、開発からデプロイまでの全プロセスを効率化できます。

継続的な学習と実践を通じて、Dockerの力を最大限に活用し、より効率的で信頼性の高いアプリケーション開発を実現しましょう。マイクロサービスアーキテクチャやクラウドネイティブ開発において、Dockerは今後も重要な役割を果たし続けることでしょう。

この記事は役に立ちましたか?

もし参考になりましたら、下記のボタンで教えてください。

コメント

この記事へのコメントはありません。