[docker-compose] 基本をおさらいし、各種項目とnetworksについて理解を深めよう！


## Docker Composeの基本 

### Docker Composeとは 
 
- **概要** : 複数のコンテナを定義し、まとめて管理・起動するためのツール
 
- **メリット** : 一つの設定ファイルで全てのコンテナを設定・管理できるため、環境構築が容易になる

### docker-compose.ymlファイルの構成 
 
- **version** : Composeファイルのバージョン指定
 
- **services** : 起動するコンテナの定義
 
- **volumes** : データ永続化のためのボリューム定義
 
- **networks** : コンテナ間通信のためのネットワーク定義

## サンプル docker-compose.ymlの解説 

```sample-docker-compose.yml
version: "3.9"

services:
  db:
    container_name: db
    build:
      context: .
      dockerfile: containers/postgres/Dockerfile
    volumes:
      - db_data:/var/lib/postgresql/data
    healthcheck:
      test: pg_isready -U "${POSTGRES_USER:-postgres}" || exit 1
      interval: 10s
      timeout: 5s
      retries: 5
    env_file:
      - .env
    ports:
      - "5432:5432"
    networks:
      - backend_app_db
  app:
    container_name: app
    build:
      context: .
      dockerfile: containers/django/Dockerfile
    command: sh -c "/usr/local/bin/entrypoint.sh"
    env_file:
      - .env
    volumes:
      - ./application:/code/
      - ./static:/static
    ports:
      - "8000:8000"
      - "8080:8080"
    depends_on:
      db:
        condition: service_healthy
    networks:
      - backend_app_web
      - backend_app_db
  nginx:
    container_name: web
    build:
      context: .
      dockerfile: containers/nginx/repo/Dockerfile
    volumes:
      - ./static:/static
    ports:
      - 80:80
    depends_on:
      - app
    networks:
      - backend_app_web
  localstack:
    image: localstack/localstack
    container_name: localstack
    ports:
      - "4566:4566"
    env_file:
      - .env
    environment:
      - SERVICES=sns
      - DEBUG=1
      - DATA_DIR=/tmp/localstack/data
    networks:
      - backend_app_web
volumes:
  db_data:
  static:
  localstack_data:
  localstack_bin:

networks:
  backend_app_web:
  backend_app_db:

```

### version 


```yaml
version: "3.9"
```
 
- **意味** : Docker Composeファイルのバージョンを指定。最新の機能を使用可能にするために3.9を指定

### services 
 
- 各サービスの設定を行うセクション。ここでは`db`, `app`, `nginx`, `localstack`の4つのサービスが定義されている

#### dbサービス 


```yaml
db:
  container_name: db
  build:
    context: .
    dockerfile: containers/postgres/Dockerfile
  volumes:
    - db_data:/var/lib/postgresql/data
  healthcheck:
    test: pg_isready -U "${POSTGRES_USER:-postgres}" || exit 1
    interval: 10s
    timeout: 5s
    retries: 5
  env_file:
    - .env
  ports:
    - "5432:5432"
  networks:
    - backend_app_db
```
 
- **container_name** : コンテナの名前を`db`に設定
 
- **build** : コンテナのビルド設定。`context`でビルドコンテキストを指定し、`dockerfile`でDockerfileのパスを指定
 
- **volumes** : ホストとコンテナ間のデータ永続化。`db_data`ボリュームを`/var/lib/postgresql/data`にマウント
 
- **healthcheck** : ヘルスチェックの設定。PostgreSQLの`pg_isready`コマンドを使用
 
- **env_file** : 環境変数ファイルを指定
 
- **ports** : ホストとコンテナ間のポートフォワーディング。`5432:5432`でPostgreSQLのデフォルトポートを指定
 
- **networks** : `backend_app_db`ネットワークに接続

#### appサービス 


```yaml
app:
  container_name: app
  build:
    context: .
    dockerfile: containers/django/Dockerfile
  command: sh -c "/usr/local/bin/entrypoint.sh"
  env_file:
    - .env
  volumes:
    - ./application:/code/
    - ./static:/static
  ports:
    - "8000:8000"
    - "8080:8080"
  depends_on:
    db:
      condition: service_healthy
  networks:
    - backend_app_web
    - backend_app_db
```
 
- **container_name** : コンテナの名前を`app`に設定
 
- **build** : コンテナのビルド設定。DjangoアプリケーションのDockerfileを指定
 
- **command** : コンテナ起動時に実行するコマンドを指定
 
- **env_file** : 環境変数ファイルを指定
 
- **volumes** : ホストとコンテナ間のディレクトリ共有
    - `./application`ディレクトリを`/code`に、`./static`ディレクトリを`/static`にマウント
 
- **ports** : ホストとコンテナ間のポートフォワーディング。`8000:8000`および`8080:8080`を指定
 
- **depends_on** : `db`サービスがヘルシー状態であることを条件に依存関係を設定
 
- **networks** : `backend_app_web`および`backend_app_db`ネットワークに接続

#### nginxサービス 


```yaml
nginx:
  container_name: web
  build:
    context: .
    dockerfile: containers/nginx/repo/Dockerfile
  volumes:
    - ./static:/static
  ports:
    - 80:80
  depends_on:
    - app
  networks:
    - backend_app_web
```
 
- **container_name** : コンテナの名前を`web`に設定
 
- **build** : コンテナのビルド設定。NginxのDockerfileを指定
 
- **volumes** : ホストとコンテナ間のディレクトリ共有。`./static`ディレクトリを`/static`にマウント
 
- **ports** : ホストとコンテナ間のポートフォワーディング。`80:80`を指定
 
- **depends_on** : `app`サービスに依存
 
- **networks** : `backend_app_web`ネットワークに接続

#### localstackサービス 


```yaml
localstack:
  image: localstack/localstack
  container_name: localstack
  ports:
    - "4566:4566"
  env_file:
    - .env
  environment:
    - SERVICES=sns
    - DEBUG=1
    - DATA_DIR=/tmp/localstack/data
  networks:
    - backend_app_web
```
 
- **image** : Localstackの公式イメージを使用
 
- **container_name** : コンテナの名前を`localstack`に設定
 
- **ports** : ホストとコンテナ間のポートフォワーディング。`4566:4566`を指定
 
- **env_file** : 環境変数ファイルを指定
 
- **environment** : 環境変数を直接設定
    - `SERVICES`で使用するサービスを指定し、`DEBUG`モードを有効化、`DATA_DIR`を指定
 
- **networks** : `backend_app_web`ネットワークに接続

### volumes 


```yaml
volumes:
  db_data:
  static:
  localstack_data:
  localstack_bin:
```
 
- **db_data** : PostgreSQLのデータ永続化用ボリューム
 
- **static** : 静的ファイルの永続化用ボリューム
 
- **localstack_data** : Localstackのデータ永続化用ボリューム
 
- **localstack_bin** : Localstackのバイナリ永続化用ボリューム


## ここで本題！networksセクションの概要 
- Docker Composeでネットワークを定義することで、複数のサービス間で通信を確立し、分離された環境を作成できます
- `docker-compose.yml`ファイルの`networks`セクションについて詳しく説明します
- `networks`セクションでは、Composeファイル内で使用するカスタムネットワークを定義します
    - サービス間の通信が可能となり、各サービスを適切に分離することができます
### サンプルのnetworksセクション 


```yaml
networks:
  backend_app_web:
  backend_app_db:
```
この例では、`backend_app_web`と`backend_app_db`の2つのネットワークが定義されています。
### 各ネットワークの役割 

#### backend_app_webネットワーク 
このネットワークは、Web関連のサービス（`app`, `nginx`, `localstack`）を接続するために使用されます。これにより、これらのサービス間での通信が可能となります
#### backend_app_dbネットワーク 
このネットワークは、データベース関連のサービス（`db`, `app`）を接続するために使用されます。これにより、データベースサービスとアプリケーションサービス間での通信が可能となります
### 各サービスにおけるネットワーク設定 

各サービスでネットワークを設定することで、特定のネットワークに接続するように指定できます

#### dbサービスのネットワーク設定 


```yaml
db:
  networks:
    - backend_app_db
```
 
- `db`サービスは`backend_app_db`ネットワークに接続します
 
- この設定により、`db`サービスは同じネットワークに接続されている他のサービス（この場合、`app`サービス）と通信することができます

#### appサービスのネットワーク設定 


```yaml
app:
  networks:
    - backend_app_web
    - backend_app_db
```
 
- `app`サービスは`backend_app_web`と`backend_app_db`の2つのネットワークに接続します
 
- これにより、`app`サービスはWeb関連のサービスとデータベース関連のサービスの両方と通信することができます

#### nginxサービスのネットワーク設定 


```yaml
nginx:
  networks:
    - backend_app_web
```
 
- `nginx`サービスは`backend_app_web`ネットワークに接続します
 
- この設定により、`nginx`サービスはWeb関連のサービス（この場合、`app`サービス）と通信することができます

#### localstackサービスのネットワーク設定 


```yaml
localstack:
  networks:
    - backend_app_web
```
 
- `localstack`サービスは`backend_app_web`ネットワークに接続します
 
- この設定により、`localstack`サービスはWeb関連のサービス（この場合、`app`サービス）と通信することができます

### ネットワークの詳細設定 

ネットワークの詳細設定を追加することも可能です。以下に、各オプションの例を示します

#### カスタムネットワークの定義例 


```yaml
networks:
  backend_app_web:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: "backend_bridge"
    ipam:
      config:
        - subnet: "172.20.0.0/16"
  backend_app_db:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: "db_bridge"
    ipam:
      config:
        - subnet: "172.21.0.0/16"
```
 
- **driver** : ネットワークのドライバーを指定。デフォルトは`bridge`
 
- **driver_opts** : ドライバーに対するオプションを設定。この例では、カスタムブリッジ名を指定
 
- **ipam** : IPアドレス管理設定
  - **config** : サブネットなどの設定を行う

:::note info
ネットワークを使用することで、サービス間の通信を効率的に管理し、分離された環境を作成することができます。`networks`セクションを適切に設定することで、複雑なアプリケーションの構築・管理が容易になります
:::





## 総論

- Docker Composeを使うことで、複数のコンテナを簡単に管理・起動することができる
 
- サンプルの`docker-compose.yml`では、データベース、アプリケーション、Nginx、Localstackの4つのサービスが定義されている

- 各サービスには、ビルド設定、環境変数、ボリューム、ポートフォワーディング、依存関係などの詳細な設定が含まれている