Docker初心者向け：ComposeとSwarmで作る管理しやすい開発環境

## 記事を書いた人

こんにちは！
株式会社マーズフラッグの城倉です。
現在、SREを担当しております。
社内での業務に取り組みながら、知識の拡充を目指して日々成長を追求しています。
この記事が皆さんのDocker活用の一歩になれば幸いです！
## この記事について
この記事では、MacOS環境を中心に、DockerのComposeとSwarmを使って開発環境をより管理しやすくする方法を紹介します。Docker ComposeやSwarmを聞いたことがあっても、実際どうやって使うのかがわからない方に向けて、分かりやすく説明しています。

### 対象読者
- 「Docker ComposeやSwarmを使いたいけど、使い方が分からない」
- 「MacOS環境でのDockerの設定方法が知りたい」という方

### 対象環境
基本的な考え方や設定ファイルの内容は、WindowsやLinuxでもほぼ同じなので、コマンドを適宜読み替えれば他のOSでも問題なく使えます。具体的な動作確認は、以下の環境で実施しています。

- MacOS
- Docker Desktop for Mac

WindowsやLinux環境の方は、細かなコマンドや設定を自身の環境に合わせて調整してください。


## はじめに

開発現場でよくある困りごとを見てみましょう：

- 「開発環境の構築に時間がかかる...」
- 「本番環境でコンテナが落ちた時の対応が大変...」
- 「複数のサーバーでコンテナを動かすのが難しい...」

これらの課題を解決するのが、ComposeとSwarmです！

## Docker Composeって何？

### 簡単に言うと...
「複数のDockerコンテナをまとめて管理するための道具」です。

例えば、こんな感じでWebアプリの環境を作れます：

```yaml
services:
  web:
    image: nginx
    ports:
      - "80:80"
  
  app:
    image: python:3.9
    volumes:
      - ./app:/app
    working_dir: /app
    command: python app.py
  
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: myapp
```

### メリット
- 📝 設定がYAMLファイルで簡単に書ける
- 🚀 `docker compose up`コマンド1つで環境が立ち上がる
- 🔄 開発メンバー全員が同じ環境を使える

### デメリット
- 1台のサーバーでしか動かせない
- サーバーが落ちたときの自動復旧ができない

## Docker Swarmって何？

### 簡単に言うと...
「複数のサーバーでDockerを管理するための仕組み」です。

### メリット
- 🔄 サーバー障害時に自動で復旧
- 💪 負荷に応じて自動でスケールアップ/ダウン
- 🔒 セキュリティ機能が標準装備

### デメリット
- 最初の設定が少し複雑
- 勉強することが多い


## 実践：ComposeとSwarmを組み合わせて使ってみよう

### まずは全体像を理解しよう！

今回作りたいのは、こんな環境です：

1. **本番用のWebサービス**
   - Swarmで動かす（自動で復旧してほしいから）
   - 例：Nginx（Webサーバー）

2. **管理用のツール**
   - Composeで動かす（簡単に起動/停止したいから）
   - 例：Prometheus（監視）、Grafana（可視化）

### なぜ分けて管理するの？

実は、全部Swarmで動かすこともできます。でも、分けて管理するメリットがあるんです：

1. **管理ツールは気軽に操作したい**
   - 設定変更するとき
   - バージョンアップするとき
   - リソースを節約したいとき

2. **本番サービスは安定して動かしたい**
   - ユーザーが使っているから
   - 24時間365日動いていてほしい
   - 問題が起きたら自動で直してほしい

つまり、**役割の違う**サービスを**それぞれに合った方法**で管理すると便利なんです！

### Docker SwarmとComposeのローカル環境構築ガイド（Mac用）

#### 前提条件
- macOS環境
- Docker Desktop for Macがインストール済み
  - 確認方法: ターミナルで`docker --version`を実行

### 1. Docker Swarmの初期化

#### 手順
```bash
# Swarmモードを初期化
docker swarm init
```

#### 確認方法
```bash
docker info | grep Swarm
```
✅ "Swarm: active" と表示されれば成功

### 2. Webサービス（Nginx）のデプロイ

#### 手順
```bash
# Nginxサービスを2レプリカで起動
docker service create --name web --replicas 2 --publish 80:80 nginx
```

#### 確認方法
```bash
# サービスの状態確認
docker service ls

# より詳細な情報を確認
docker service ps web
```
✅ REPLICASが"2/2"と表示されれば成功

### 3. 管理ツール用の環境準備

#### 手順
#### 作業ディレクトリの作成
```bash
mkdir docker-management-tools
```
```bash
cd docker-management-tools
```
#### docker-compose.ymlの作成
```bash
cat << 'EOF' > docker-compose.yml
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
EOF
```
- 何をしているのか？
    - docker-compose.ymlという設定ファイルを作成しています
    - このファイルには、2つのサービス（PrometheusとGrafana）の設定が含まれています
- 詳細
    - Docker Composeを使って、これらのツール（PrometheusとGrafana）をコンテナとして簡単に立ち上げ、管理するためです
    - Prometheus
        - prom/prometheusというDockerイメージを使い、ポート9090を開けてコンテナを起動します
        - 設定ファイルprometheus.ymlを使うように指定しています
    - Grafana
        - grafana/grafanaというDockerイメージを使い、ポート3000でコンテナを起動します
        - GrafanaはPrometheusが起動した後に起動されるようにdepends_onで依存関係を指定しています
#### prometheus.ymlの作成
```bash
cat << 'EOF' > prometheus.yml
global:
    scrape_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']
EOF
```
- 何をしているのか？
    - Prometheusの設定ファイルprometheus.ymlを作成しています
    - これはPrometheusがどのデータをどの間隔で収集するかを定義するファイルです
- 詳細
    - Prometheusが自分自身（localhost:9090）を監視対象とし、15秒ごとにデータを収集するように設定しています
    - この設定で、Prometheus自身のステータスやパフォーマンスデータが収集されます

### 4. 管理ツールの起動

#### 手順
```bash
docker compose up -d
```

#### 確認方法
```bash
docker compose ps
```
✅ prometheusとgrafanaが"Up"状態で表示されれば成功

### 5. 動作確認

#### Webサービス（Nginx）の確認
1. ブラウザで http://localhost にアクセス
2. Nginxのデフォルトページが表示されることを確認

#### 管理ツールの確認
1. Prometheus: http://localhost:9090 にアクセス
2. Grafana: http://localhost:3000 にアクセス
   - 初期ログイン情報：admin/admin

### 6. Swarmの自動復旧機能テスト

#### 手順
```bash
# 現在実行中のNginxコンテナを確認
docker ps | grep nginx

# コンテナIDをメモして1つ目のコンテナを停止
docker stop <コンテナID>

# サービスの状態を監視（新しいコンテナが自動作成されるのを確認）
docker service ps web
```

✅ 確認ポイント：
- 停止したコンテナが "Shutdown" 状態になる
- 新しいコンテナが自動的に作成される
- http://localhost でNginxページが継続して表示される

### 7. クリーンアップ（必要な場合）

#### 手順
```bash
# Swarmサービスの削除
docker service rm web

# 管理ツールの停止
cd docker-management-tools
docker compose down

# Swarmモードの終了
docker swarm leave --force
```

## トラブルシューティング

### ポートが既に使用されている場合
```bash
# 使用中のポートを確認
lsof -i :80
lsof -i :9090
lsof -i :3000

# 必要に応じて該当プロセスを終了
kill <PID>
```

### Swarm初期化エラーの場合
```bash
# 既存のSwarm設定をクリア
docker swarm leave --force
# 再度初期化
docker swarm init
```

## まとめ

以上の手順で、Mac のローカル環境で Swarm と Compose を組み合わせた環境を構築し、動作確認ができます。Swarm で運用している本番サービス (この場合は Nginx) は自動復旧する一方で、Compose で管理しているツール群は簡単に起動/停止できることが確認できたはずです。

この環境をベースに、実際のプロジェクトに合わせてカスタマイズしていくことができます。少しずつ試しながら、チームに最適な構成を見つけていくことをおすすめします。

### この構成のいいところを詳しく見てみよう

1. **管理がラクになる理由**
   - 本番サービス（Swarm）
     - サーバーが落ちても自動で復旧
     - 負荷が高くなったら自動で増やせる
   - 管理ツール（Compose）
     - 設定変更が簡単
     - 起動/停止が思いのまま
     - アップデートも簡単

2. **障害対応が楽になる理由**
   - 本番サービスは自動復旧するから安心
   - 管理ツールは手動で確実に対応できる
   - それぞれに合った対応ができる

3. **開発チームが助かる理由**
   - 本番サービスの動作が安定する
   - 管理ツールの操作が簡単
   - みんなが同じ方法で扱える

### よくある疑問

Q: 全部Composeで良くない？  
A: 本番サービスが落ちたとき、自動で復旧できません。夜中に起きたくないですよね？

Q: 全部Swarmで良くない？  
A: 管理ツールの設定変更やバージョンアップが面倒になります。シンプルな操作が複雑になってしまいます。

Q: 他の管理ツールは？  
A: Prometheusの代わりにDatadog、Grafanaの代わりにKibanaなど、チームの好みに応じて変更OK！考え方は同じです。


## 参考リンク
- [Docker公式ドキュメント](https://docs.docker.com/)
- [Docker Compose概要とインストール](https://docs.docker.com/compose/)
- [Docker Compose入門ガイド](https://docs.docker.com/compose/gettingstarted/)
- [Docker Swarm概要](https://docs.docker.com/engine/swarm/)
- [Docker Swarm入門ガイド](https://docs.docker.com/engine/swarm/swarm-tutorial/)

### 日本語のリソース
- [Docker Document日本語化プロジェクト](https://docs.docker.jp/)
- [Docker Composeファイルリファレンス（日本語）](https://docs.docker.jp/compose/compose-file.html)
- [Docker Swarmモード（日本語）](https://docs.docker.jp/engine/swarm/index.html)

---