0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Docker理解への道② 〜docker-compose.ymlの徹底的な理解〜

Posted at

はじめに

Dockerを根本的・体系的に理解するために、このシリーズを書き始めました。
第1回リンク

いきなりDockerそのものを理解するのではなく、イメージしやすいものから学習していくつもりです。
今回は「docker-compose.ymlについて完璧に理解しよう」の回です。前回でも概要は触れて、そのときはこう表現しました。

アプリ全体の「構成」と「連携方法」を定義する設計図。以下のような情報を記載しています。

  • どのサービス(コンテナ)を扱うか
  • 各サービスの設定

イメージも設計図という表現がされますが、イメージが一つの部屋(コンテナ)の設計図だとしたら、docker-compose.ymlはマンションの設計図です。


docker compose upの際に、このymlファイルを参考に関連サービス(コンテナ)が起動します。

docker-compose.yml

では具体的なymlファイルの書き方を深堀します。私は実物あった方が、理解が進むタイプなので、Claude Code先生に頼りつつ、一般的な書き方をコメント付きコードで記載してみました。あくまで一例ですが、大枠はどれも似たり寄ったりなので、一つ書くだけでymlファイルの役割がイメージしやすくなりました。

感想としては、自分で変数渡してビルドしたり、他の設定ファイルを利用したりもできるので、拡張性って表現するんですかね?柔軟性もある印象です。
一気に見ると情報量に圧倒されますが、コメント付けながら一つ一つかみ砕いていくと案外理解できました

docker-compose.yml
# ファイルのバージョン
version: "3.8"

networks:
    myapp-network: # 任意のネットワーク名
        driver: bridge # 同じPC内でコンテナ間をつなぐ(その他にもPC間を繋ぐoverlayなど)

# ボリューム:コンテナを消してもデータが残る保存場所
volumes:
    mysql-data: # 任意のボリューム名(例:データベースのデータ用)
    app-logs: # 任意のボリューム名(例:アプリのログファイル用)

# config:機密情報といった別で保管したいものの利用に向いている
configs:
    db-password: # 任意のconfig名
        file: ./secrets/db_password.txt # 対象ファイル

services: # ここが本題!
    nginx: # 任意のコンテナ名(他のコンテナから「http://nginx:80」のようにこの名前で呼び出せる)
        image: nginx:alpine # ← 実際に使う技術
        container_name: myapp-nginx # docker psで表示される名前(省略するとそのままサービス名が使われる)
        ports:  # ポート設定(2パターン)
            - "80:80" # パターン1: "ホスト側:コンテナ側"
            # パターン2: コンテナ側のポート、ホスト側のポート、プロトコル
            - target: 443
            published: 443
            protocol: tcp
        networks:  # どのネットワークにつなぐか
            - myapp-network
        depends_on:   #他のコンテナへの依存(2パターン)
            - sample-api # パターン1: 対象コンテナ(api)が起動したら起動する
            - sample-api  # パターン2: 対象コンテナが正常になったら起動する
                condition: service_healthy
        volumes:  # ボリューム設定:ホストとコンテナのフォルダ共有設定
            - ./html:/usr/share/nginx/html # 指定したコンテナのファイルとローカルのファイルが同期できる。(ホスト側:コンテナ側で記述) 
        restart: unless-stopped # 手動で停止以外、コンテナが落ちたら自動で再起動する
    
    sample-api: # コンテナ名
        build: #imageが既製品を使うのに対して、buildは自分でDockerfile用意してコンテナを作る
            context: ./sample-api # Dockerfileがあるフォルダ
            dockerfile: Dockerfile # ファイル名(省略可能、デフォルトはDockerfile)
            args: # ビルド時に渡す変数
                NODE_VERSION: 18
        ports:
            - "3000:3000"
        networks:
            - myapp-network
        environment:  # 環境変数の書き方(2パターン)
            # パターン1: リスト形式
            - DATABASE_URL=mysql://user:pass@mysql:3306/mydb # ← @mysql の部分!サービス名で他のコンテナを指定できる
            - NODE_ENV=production
            # パターン2: ファイルから読み込む          
            env_file:         
                - .env # .envファイルに書いた環境変数を全部読む
        configs:
            - source: db-password # データベースのパスワードファイル
            target: /run/secrets/db_password.txt # コンテナ内でこのパスで読める
        healthcheck:  # ヘルスチェック
            test: ["CMD", "curl", "-f", "http://localhost:3000/health"] # このコマンドで確認
                interval: 30s # チェック頻度
                timeout: 10s # 10秒以内に応答がなければ失敗
                retries: 3 # 3回連続で失敗したら異常
                start_period: 40s # 起動後40秒は失敗してもOK
            volumes:
                - ./sample-api:/app
            depends_on:
                - mysql
            # リソース制限(使いすぎを防ぐ)
            deploy:
                resources:
                    limits:
                        cpus: '1.0' # CPU 1コア分まで
                        memory: 512M # メモリ512MBまで
                    reservations: # 最低限これだけは確保
                        cpus: '0.5'
                        memory: 256M
   
    mysql: # コンテナ名
        image: mysql:8 # MySQLの公式イメージ
        ports:
            - "3306:3306"
        networks:
            - myapp-network
        environment:
            MYSQL_ROOT_PASSWORD: rootpass
            MYSQL_DATABASE: mydb
            MYSQL_USER: dbuser
            MYSQL_PASSWORD: dbpass
        # データを永続化(コンテナ消してもデータ残る)
        volumes:
            - mysql-data:/var/lib/mysql # MySQLのデータ本体
            - ./init.sql:/docker-entrypoint-initdb.d/init.sql # 初回起動時に実行されるSQL
        restart: always # 常に再起動
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?