この記事は、「docker-compose.ymlってどうやって書くの?」という方に向けて、docker-compose.ymlの書き方をわかりやすく解説する入門記事です。
ポイントを一つずつ確認しながら、docker-compose.ymlの作り方を一緒に見ていきましょう!
単語の意味
本記事で使用する単語のざっくりとした意味を紹介します。
記事の内容をスムーズに理解するための参考にしてください。
- イメージ:コンテナを作成するための「設計図」のようなものです。
- コンテナ:イメージをもとに作られる、独立した「アプリケーションの実行環境」のことです。
docker-compose.yml(compose.yml)ってなに?
docker-compose.ymlは、「複数の Docker コンテナをどのように起動・連携させるか」を定義したファイルです。
どのコンテナを起動するか、どのイメージを使うか、どんなコマンド・環境変数・ポート・ボリュームを使うか、といった 「実行時の設定」 をまとめて記述できます。
docker-compose.yml(+ Dockerfile)を用意しておけば、docker compose up するだけで複数コンテナ(Web・DB など)を一括起動できます。

Docker Composeについてや、Dockerによる環境構築手順が知りたい方は、本記事の最後に載せている参考記事をご活用ください。
今回説明するサンプルコード
以下「【初心者向け】DockerでRails APIとPostgreSQLの環境構築をする(M1 Mac)」で使用したdocker-compose.ymlを例に解説していきます。
【docker-compose.yml】
services:
db:
image: postgres:17
restart: unless-stopped
environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_HOST}
volumes:
- postgres-data:/var/lib/postgresql/data
ports:
- "5432:${DB_PORT}"
app:
build: .
environment:
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
DB_HOST: ${DB_HOST}
FRONTEND_ORIGIN: ${FRONTEND_ORIGIN}
RAILS_ENV: ${RAILS_ENV}
volumes:
- .:/rails-api-docker
- log-data:/rails-api-docker/log
ports:
- "3000:3000"
depends_on:
- db
volumes:
log-data:
postgres-data:
docker-compose.ymlの書き方
それではさっそく、記事冒頭でご紹介した、docker-compose.ymlのサンプルコードで定義されている各種項目について解説していきます。
services
servicesは、何のコンテナを、どんな設定で、いくつ動かすか をまとめて宣言できる項目です。
以下では、db と app という2つのサービス(コンテナの設定)を定義しています。
services:
db:
・・・dbサービス用のコンテナ設定を記述・・・
app:
・・・appサービス用のコンテナ設定を記述・・・
image
image はコンテナを起動するイメージを指定します。
以下では、Docker公式が提供している「PostgreSQL のバージョン 17」のイメージを使用し、コンテナを起動するように設定されています。
services:
db:
image: postgres:17
・・・省略・・・
build
build は、アプリケーションのソースコードなどを元に Docker イメージをビルドし、そのイメージからコンテナを起動するための設定です。
以下では、
docker-compose.ymlがあるディレクトリを基準として- その中にある
Dockerfileを使って - イメージをビルドし、コンテナを起動する
という動作になります。
services:
app:
build: .
・・・省略・・・
※ build を文字列(パス)で指定する場合、そのパスはディレクトリである必要があり、Dockerfile を含んでいる必要があります。
※ 相対パスを指定した場合は、docker-compose.yml ファイルが置かれているディレクトリを基準にパスが解決されます。
参考:https://docs.docker.com/reference/compose-file/build
volumes
volumes にはいくつか種類がありますが、今回はよく使用する2種類を説明します。
1つ目が「名前付きボリューム」で、コンテナを停止・削除してもデータを保持しておきたいときに使用します。
- 例:
postgres-data:/var/lib/postgresql/data→「postgres-data」という名前をつけたボリュームを使用している - 使い所:コンテナを停止・削除してもデータを保持しておきたいとき (例:DB のデータを永続化したいとき)
2つ目が「バインドマウント」で、ローカルPCとコンテナでファイルを共有・同期したいときに使用します。
- 例:
.:/rails-api-docker→ホスト(自分のPC)のカレントディレクトリを、そのままコンテナにマウント(同期・共有)している - 使い所:ローカルPCとコンテナでファイルを共有・同期したいとき (例:ローカルで変更したコードを即座にコンテナに反映したいとき)
以下の設定では、db サービスで「postgres-data」という名前付きボリュームを、コンテナ内の「/var/lib/postgresql/data」というディレクトリにマウントし、DBのデータをコンテナの外に保存することで永続化しています。
また、app サービスでホスト(ローカルPC)の「.(カレントディレクトリ)」を、コンテナ内の「/rails-api-docker」というディレクトリ(Dockerfile内で指定したパス)にマウントしています。
services:
db:
・・・省略・・・
volumes:
- postgres-data:/var/lib/postgresql/data
app:
・・・省略・・・
volumes:
- .:/rails-api-docker
volumes:
postgres-data:
※ PostgreSQLのデータマウント用のフォルダ(/var/lib/postgresql/data)については、Docker公式サイトで提供されているPostgreSQL用イメージのページ(https://hub.docker.com/_/postgres)に指定があります。
ボリューム名とパスの指定方法は以下のとおりです。
名前付きボリュームの場合
名前付きボリュームの場合、左側が「ボリューム名」、右側が「コンテナ側のパス」です。
services:
db:
・・・省略・・・
volumes:
- [ボリューム名] : [コンテナ側のパス]
volumes:
[ボリューム名]:
バインドマウントの場合
バインドマウントの場合、左側が「ホスト(ローカルPC)側のパス」、右側が「コンテナ側のパス」です。
services:
app:
・・・省略・・・
volumes:
- [ホスト側のパス] : [コンテナ側のパス]
ports
ports は、ホストマシン(ローカルPC)とコンテナ間のポートマッピングを定義するために使用されます。
つまり、コンテナ内で実行されているサービスへの外部アクセスを許可するために必要な設定です。
以下では、ホストマシンとコンテナのポート番号を 3000 に設定しています。
この設定により、ブラウザから http://localhost:3000/ にアクセスすると、コンテナ内のアプリケーションを確認することができます。
services:
・・・省略・・・
app:
・・・省略・・・
ports:
- "3000:3000"
・・・省略・・・
※左側が「ホストマシン(ローカルPC)のポート番号」、右側が「コンテナのポート番号」です。
以下のように、ホストマシンのポート番号を 3001 に設定すると、ブラウザから http://localhost:3001/ にアクセスすることでコンテナ内のアプリケーションを確認することができます。
services:
・・・省略・・・
app:
・・・省略・・・
ports:
- "3001:3000"
・・・省略・・・
depends_on
depends_on は、サービス間の依存関係を指定するための設定です。
docker compose up などのコマンドを実行すると、依存関係に従った順番でサービスが起動されます。
以下では、app を起動する前に db が起動されます。
services:
db:
・・・省略・・・
app:
・・・省略・・・
depends_on:
- db
※ 上記のコードの場合、docker compose up db -d を実行すると db のみが起動します( db 単体を起動する場合、依存関係がないため db のみが起動されます)。
restart
restart は、コンテナが停止したときに Docker が自動で再起動するかどうかを指定する設定です。
今回はrestart: unless-stoppedのみ説明します。
DB コンテナは、メモリ不足や一時的なエラーなどで落ちることがあります。
そのたびに手動で docker compose up を実行するのは手間なので、DB コンテナに関しては基本的には常に自動で再起動するようにしておきたいです。
一方で、
docker compose stopなどで 手動でコンテナを停止したいとき- 意図的にサービスを止めたいとき
には、勝手に再起動してほしくありません。
この挙動を実現するのが restart: unless-stopped です。
以下では、dbサービス用のコンテナ設定で「restart: unless-stopped」を設定しています。
services:
db:
・・・省略・・・
restart: unless-stopped
・・・省略・・・
environment
environment は、環境変数を追加する設定です。
以下の場合、DB_USER、DB_PASSWORD、DB_HOST、FRONTEND_ORIGIN、RAILS_ENV という環境変数をコンテナに追加しています。
services:
・・・省略・・・
app:
・・・省略・・・
environment:
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
DB_HOST: ${DB_HOST}
FRONTEND_ORIGIN: ${FRONTEND_ORIGIN}
RAILS_ENV: ${RAILS_ENV}
・・・省略・・・
環境変数をコンテナに追加することで、Rails などのアプリケーション内からこれらの値を参照できるようになります。
以上で各種項目の説明は終わりです!
おわりに
この記事では、docker-compose.yml の基本構造と、よく使う各項目の役割を解説しました。
docker-compose.ymlでは、
servicesで「どんなコンテナを動かすか」を定義しimageやbuildで「どのイメージから起動するか」を決めenvironmentでアプリが使う設定値を渡しvolumesでデータの永続化やファイル共有を行いportsでコンテナの中のアプリにアクセス
できるようにします。
これらを理解することで、Webアプリ + DB のような複数コンテナ構成でも、docker compose up 一発で起動できるようになります。
最初は設定項目が多く感じるかもしれませんが、 それぞれの役割が分かれば、docker-compose.ymlは「意外とシンプルな設定ファイル」だと感じられるはずです。
本記事を参考に、ぜひ自分の環境に合わせた docker-compose.yml を書いてみてください。
本記事が、docker-compose.ymlを「自分で読める・書ける」ようになるための第一歩になれば幸いです!
