[Linux]Docker Compose でコンテナの作成
公開日:2025-11-30
更新日:2025-11-30
更新日:2025-11-30
1. 概要
Docker Compose でコンテナを作成します。
Docker Compose を使うと、コンテナの構築などをファイルで定義することができます。
docker-compose(ハイフンあり)はバージョン1(非推奨)、
docker compose(ハイフンなし)はバージョン2(推奨)です。
Docker Compose を使うと、コンテナの構築などをファイルで定義することができます。
docker-compose(ハイフンあり)はバージョン1(非推奨)、
docker compose(ハイフンなし)はバージョン2(推奨)です。
2. コマンド
コード
docker compose up # 実行
docker compose up -d # バックグラウンドで実行
docker compose down # 停止
docker compose logs # ログ表示3. docker compose で hello-world
docker-compose.yml を作成します。
~/docker_test/docker-compose.yml
インデントはタブではなく半角スペース 2 つです。
services 配下に、各コンテナを定義します。
「hello」は任意のサービス名です。
image で Docker イメージを指定します。
docker compose でコンテナの実行。
停止したコンテナは、「docker ps -a」で確認できます。
docker compose で起動したコンテナの停止と削除
もう一度実行する場合、「docker compose up」を実行します。
コンテナが既にある場合は、コンテナを再起動します。
~/docker_test/docker-compose.yml
コード
services:
hello:
image: hello-world
.yml は、YMAL と言うデータを構造化して定義できる形式です。インデントはタブではなく半角スペース 2 つです。
services 配下に、各コンテナを定義します。
「hello」は任意のサービス名です。
image で Docker イメージを指定します。
docker compose でコンテナの実行。
コマンド
cd ~/docker_test
docker compose up
実行結果
hello-1 |
hello-1 | Hello from Docker!
hello-1 | This message shows that your installation appears to be working correctly.
hello-1 |
(省略)
hello-world は文字を出力してすぐに停止します。停止したコンテナは、「docker ps -a」で確認できます。
docker compose で起動したコンテナの停止と削除
コマンド
docker compose down
docker compose down -v # ネットワークやボリュームも削除
もう一度実行する場合、「docker compose up」を実行します。
コンテナが既にある場合は、コンテナを再起動します。
4. docker compose で Nginx
~/docker_test/docker-compose.yml
内容は次のコマンドと同じです。
html と conf は、「Docker で Nginx のコンテナの使用」で作成したもの使います。
php-fpm と連携していた場合は、conf の location ~ \.php$ のブロックをコメントアウトしてください。
php-fpm のホストがないため、Nginx の起動時にエラーになります。
~/docker_test/nginx/conf/app.conf
~/docker_test/nginx/html/test.html
起動中のコンテナを全て停止して削除
コンテナを起動します。
http://localhost:8080/test.html にアクセスして正常に表示されれば OK です。
コンテナを停止するには次のコマンドを使用します。
コード
services:
nginx:
image: nginx:1.29.3
ports:
- "80:80"
volumes:
- ~/docker_test/nginx/conf:/etc/nginx/conf.d
- ~/docker_test/nginx/html:/usr/share/nginx/html
内容は次のコマンドと同じです。
コマンド
docker run \
-p 80:80 \
-v ~/docker_test/nginx/conf:/etc/nginx/conf.d \
-v ~/docker_test/nginx/html:/usr/share/nginx/html \
nginx:1.29.3
html と conf は、「Docker で Nginx のコンテナの使用」で作成したもの使います。
php-fpm と連携していた場合は、conf の location ~ \.php$ のブロックをコメントアウトしてください。
php-fpm のホストがないため、Nginx の起動時にエラーになります。
~/docker_test/nginx/conf/app.conf
コード
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
}
~/docker_test/nginx/html/test.html
コード
test
起動中のコンテナを全て停止して削除
コマンド
docker ps -a # コンテナ一覧(停止中を含む)の表示
docker stop { コンテナID | コンテナ名 } # コンテナの停止
docker rm { コンテナID | コンテナ名 } # コンテナの削除
コンテナを起動します。
コマンド
cd ~/docker_test
docker compose up -d # -d でバックグラウンドで実行。-d を付けない場合、他のコマンドが実行できなくなる。
http://localhost:8080/test.html にアクセスして正常に表示されれば OK です。
コンテナを停止するには次のコマンドを使用します。
コマンド
docker compose stop # コンテナが残る。
docker compose down # コンテナは削除。ボリュームは残るため、 次回、初期化処理が実行されない
docker compose down -v # コンテナは削除。ボリュームが削除されるため、次回、初期化処理が実行される5. ネットワークの確認
docker run でコンテナを起動する時は、「--network my-app-network」のようにしてネットワークを指定していましたが、
docker compose の場合は、自動的にネットワークが作成されます(ネットワークを指定して作成することも可能)。
起動中のコンテナを確認します。
Nginx のコンテナの詳細情報を表示します。
ネットワークからコンテナを確認することもできます。
ネットワークの詳細情報を表示します。
起動中のコンテナを確認します。
コード
docker ps
実行結果
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
767fd2233286 nginx:1.29.3 "/docker-entrypoint.…" 12 minutes ago Up 12 minutes 0.0.0.0:80->80/tcp, [::]:80->80/tcp docker_test-nginx-1
Nginx のコンテナの詳細情報を表示します。
コード
docker inspect docker_test-nginx-1
実行結果
(省略)
"IPv6Gateway": "",
"MacAddress": "",
"Networks": {
"docker_test_default": {
"IPAMConfig": null,
"Links": null,
(省略)
「docker_test-nginx-1」のネットワークが「docker_test_default」であることがわかります。ネットワークからコンテナを確認することもできます。
ネットワークの詳細情報を表示します。
コード
docker network inspect docker_test_default
実行結果
(省略)
"Containers": {
"767fd2233286a5ed44ea8c4e357c4e07a5dbd4ca001105207917c25c7dcd6805": {
"Name": "docker_test-nginx-1",
"EndpointID": "68665d00428e698f9d02043f92f8588a6ba45778a9e4b1ccd323936cc64a09fb",
"MacAddress": "3a:ca:78:b2:d3:8d",
"IPv4Address": "172.19.0.2/16",
"IPv6Address": ""
}
},
(省略)
ネットワークの「docker_test_default」に、「docker_test-nginx-1」が接続されていることがわかります。6. docker compose で Nginx、php-fpm、MariaDB のコンテナの作成
6.1 Nginx の conf と html
html と conf は、「Docker で Nginx のコンテナの使用」と「Docker で Nginx と PHP の連携」で作成したものを使います。
~/docker_test/nginx/conf/app.conf
~/docker_test/nginx/html/test.php
~/docker_test/nginx/conf/app.conf
コード
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
location ~ \.php$ {
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html/$fastcgi_script_name;
include fastcgi_params;
}
}
~/docker_test/nginx/html/test.php
コード
<?php phpinfo();6.2 .env の作成
.env は、Docker Compose の実行時に読み込まれる環境変数の設定ファイルです。
環境変数は、docker-compose.yml で使用できます。
これにより、MariaDB などのパスワードを docker-compose.yml に書かないようにすることができます。
.env は、GitHub などで公開しないようにしてください。
~/docker_test/.env
環境変数を参照する場合は、${DB_ROOT_PASSWORD}、${DB_APP_PASSWORD} のようにします。
後ほど、root ユーザとアプリ用ユーザのパスワードとして使用します。
今回は「password」と言うパスワードにしていますが、実際には複雑なパスワードにしてください。
環境変数は、docker-compose.yml で使用できます。
これにより、MariaDB などのパスワードを docker-compose.yml に書かないようにすることができます。
.env は、GitHub などで公開しないようにしてください。
~/docker_test/.env
コード
DB_ROOT_PASSWORD=password
DB_APP_PASSWORD=password
環境変数を参照する場合は、${DB_ROOT_PASSWORD}、${DB_APP_PASSWORD} のようにします。
後ほど、root ユーザとアプリ用ユーザのパスワードとして使用します。
今回は「password」と言うパスワードにしていますが、実際には複雑なパスワードにしてください。
6.3 docker-compose.yml の作成
~/docker_test/docker-compose.yml
container_name でコンテナ名も指定していますが、サービス名でもホスト名のように扱えます。
「ping サービス名」が可能。
restart: unless-stopped で、Docker が起動された時にコンテナを自動起動します。
但し、コンテナを手動して停止した場合は、Docker を再起動しても停止したままとなります。
nginx サービスの depends_on で php が指定されているため、php サービスが先に起動します。
php のイメージは、build に指定された「dockerfile」で作成されます。
volumes が 複数ありますが、
サービス内の volumes は、Docker ホストのディレクトリを、コンテナ内のディレクトリにマウントするためのもので、
最後の volumes は、ボリュームの作成を指示するものです。
コード
services:
nginx:
image: nginx:1.29.3
restart: unless-stopped
container_name: nginx-test
ports:
- "80:80"
volumes:
- ~/docker_test/nginx/html:/usr/share/nginx/html
- ~/docker_test/nginx/conf:/etc/nginx/conf.d
depends_on:
- php
networks:
- app-network
php:
build:
context: .
dockerfile: dockerfile
restart: unless-stopped
container_name: php-fpm
volumes:
- ~/docker_test/nginx/html:/var/www/html
environment:
- MYSQL_HOST=mariadb-test
- MYSQL_DATABASE=test
- MYSQL_USER=app
- MYSQL_PASSWORD=${DB_APP_PASSWORD}
networks:
- app-network
mariadb:
image: mariadb:12.0.2
restart: unless-stopped
container_name: mariadb-test
ports:
- "3306:3306"
volumes:
- db-data:/var/lib/mysql
# - ~/docker_test/init:/docker-entrypoint-initdb.d
environment:
- MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
- MYSQL_DATABASE=test
- MYSQL_USER=app
- MYSQL_PASSWORD=${DB_APP_PASSWORD}
networks:
- app-network
volumes:
db-data:
networks:
app-network:
driver: bridge
services 直下の nginx、php、mariadb は、サービス名です。container_name でコンテナ名も指定していますが、サービス名でもホスト名のように扱えます。
「ping サービス名」が可能。
restart: unless-stopped で、Docker が起動された時にコンテナを自動起動します。
但し、コンテナを手動して停止した場合は、Docker を再起動しても停止したままとなります。
nginx サービスの depends_on で php が指定されているため、php サービスが先に起動します。
php のイメージは、build に指定された「dockerfile」で作成されます。
volumes が 複数ありますが、
サービス内の volumes は、Docker ホストのディレクトリを、コンテナ内のディレクトリにマウントするためのもので、
最後の volumes は、ボリュームの作成を指示するものです。
6.4 dockerfile の作成
PHP だけなら docker-compose.yml で image を指定するだけでコンテナを作成できますが、
PHP の拡張モジュールもインストールする必要があるため、dockerfile を使用して、細かく制御します。
~/docker_test/dockerfile
パッケージリストの更新。
dockerfile では、apt ではなく、安定している apt-get を使用することが多い。
「libmariadb-dev」
MariaDB 用の PHP の拡張モジュールをコンパイルするのに使用。
「pkg-config」
コンパイル時に必要なパスを解決するのに使用。
「docker-php-ext-install pdo_mysql」
pdo と pdo_mysql のインストール。
「apt-get clean」
パッケージのキャッシュのクリア。
「rm -rf /var/lib/apt/lists/*」
アップデート時に使用したファイルの削除。
PHP の拡張モジュールもインストールする必要があるため、dockerfile を使用して、細かく制御します。
~/docker_test/dockerfile
コード
FROM php:8.4.14-fpm
RUN apt-get update && apt-get install -y \
libmariadb-dev \
pkg-config \
&& docker-php-ext-install pdo_mysql \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /var/www/html
「apt-get update」パッケージリストの更新。
dockerfile では、apt ではなく、安定している apt-get を使用することが多い。
「libmariadb-dev」
MariaDB 用の PHP の拡張モジュールをコンパイルするのに使用。
「pkg-config」
コンパイル時に必要なパスを解決するのに使用。
「docker-php-ext-install pdo_mysql」
pdo と pdo_mysql のインストール。
「apt-get clean」
パッケージのキャッシュのクリア。
「rm -rf /var/lib/apt/lists/*」
アップデート時に使用したファイルの削除。
6.5 docker compose の実行
確認しやすくするため、他のコンテナが実行中の場合は、停止して削除してください。
コンテナの起動
コンテナが起動しているか確認。
起動しない場合は、ログを確認します。
コンテナの起動
コマンド
docker compose up -d
コンテナが起動しているか確認。
コマンド
docker ps
起動しない場合は、ログを確認します。
コマンド
docker compose logs nginx
docker compose logs php-fpm
docker compose logs mariadb
6.6 DB にテストデータの作成
「Docker で MariaDB のコンテナの使用」のようにして table1 にデータを追加します。
また、test_db.php も作成していない場合は、作成してください。
http://localhost:8080/test_db.php にアクセスして、データが表示されれば OK です。
コマンド
docker exec -it mariadb-test bash
mariadb -u app -p
use test
CREATE TABLE table1 (
id INT NOT NULL AUTO_INCREMENT,
text TEXT NOT NULL,
PRIMARY KEY (id)
) ENGINE = InnoDB;
INSERT INTO table1 (text) values ('test1'), ('test2'), ('test3');
また、test_db.php も作成していない場合は、作成してください。
http://localhost:8080/test_db.php にアクセスして、データが表示されれば OK です。
6.7 ボリュームについて
ボリュームとは、コンテナデータを永続化して保持できるストレージで、実体は Docker のホスト側にあります。
MariaDb のコンテナのデータは、コンテナ内の /var/lib/mysql に作成されますが、
docker-compose.yml でボリュームの db-data でマウントしているため、
MariaDb のコンテナを削除しても、DB のデータが保持されます。
ボリュームは、次のコマンドで確認できます。
ボリューム一覧の表示
ボリュームの確認
MariaDB のコンテナ起動時に、
/var/lib/mysql(/var/lib/docker/volumes/docker_test_db-data/_data でマウント)が空かチェックして、
空の場合は、システムのデータベースの作成、root ユーザの作成、environment で指定されている root ユーザのパスワードの設定、ユーザの追加、データベースの作成が行われます。
ボリュームの実体のファイル一覧の表示
ボリュームはコンテナを削除しても残るため、ボリュームが不要になったり、1 から作り直したい場合は、ボリュームを削除してください。
ボリュームの削除
MariaDb のコンテナのデータは、コンテナ内の /var/lib/mysql に作成されますが、
docker-compose.yml でボリュームの db-data でマウントしているため、
MariaDb のコンテナを削除しても、DB のデータが保持されます。
ボリュームは、次のコマンドで確認できます。
ボリューム一覧の表示
コマンド
docker volume list
実行結果
DRIVER VOLUME NAME
local 13ef3f63182e3756f22f9dc8c4fe29b4471c43d8e20253f28ab89a333c686738
local 7559340f3416feefab02574bf7374f6307436e0556eddc6361c25556755dfc2e
local docker_test_db-data
local d42140bba7d859d2d53b1b9cd0941de375a338e3bc19ef7900af722149b6190d
ボリュームの確認
コマンド
docker volume inspect docker_test_db-data
実行結果
[
{
"CreatedAt": "2025-11-19T23:47:50+09:00",
"Driver": "local",
"Labels": {
"com.docker.compose.config-hash": "b2d9a21578e6b1da8e8bfc71b42b9abca8d777fe1d2b460037bea5dd2fcdce14",
"com.docker.compose.project": "docker_test",
"com.docker.compose.version": "2.40.0",
"com.docker.compose.volume": "db-data"
},
"Mountpoint": "/var/lib/docker/volumes/docker_test_db-data/_data",
"Name": "docker_test_db-data",
"Options": null,
"Scope": "local"
}
]
Mountpoint が、ボリュームの実体のパス(Docker のホスト側)です。MariaDB のコンテナ起動時に、
/var/lib/mysql(/var/lib/docker/volumes/docker_test_db-data/_data でマウント)が空かチェックして、
空の場合は、システムのデータベースの作成、root ユーザの作成、environment で指定されている root ユーザのパスワードの設定、ユーザの追加、データベースの作成が行われます。
ボリュームの実体のファイル一覧の表示
コマンド
sudo ls -al /var/lib/docker/volumes/docker_test_db-data/_data
ボリュームはコンテナを削除しても残るため、ボリュームが不要になったり、1 から作り直したい場合は、ボリュームを削除してください。
ボリュームの削除
コマンド
docker compose down -v # コンテナの停止・削除、ボリュームの削除
または
docker volume rm {ボリューム名}
docker volume rm docker_test_db-data7. docker compose で MariaDB のテーブル作成とテストデータの追加
任意の SQL は docker-compose.yml では定義できないため、
外部の SQL ファイルとシェルスクリプトを使って DB を操作します。
一度コンテナの停止とボリュームの削除を行います。
~/docker_test/docker-compose.yml の修正
ここで指定したディレクトリに、.sql や .sh のファイルを入れると、ボリュームが空の時に1度だけ実行されます。
実行される順番は、ファイル名の昇順です。ファイル名の先頭に、頭を0埋めにした番号を付けるとわかりやすいです。
environment から MYSQL_DATABASE と MYSQL_USER の定義を削除します。
これを指定すると、自動的にデータベースとユーザが作成されるため。
外部の SQL ファイルでデータベースとユーザを作成しない場合は、残したままにします。
init ディレクトリの作成
1番目に実行される初期化処理(シェルスクリプト)
~/docker_test/init/01_init.sh
<<EOF から EOF に囲まれた部分が mariadb に渡されます。
【注意】
${MYSQL_ROOT_PASSWORD} と ${MYSQL_PASSWORD} は、docker-compose.yml の environment で指定した変数です。
.env の変数は直接使えないので注意してください。
また、SQL の中では環境変数が使えないため、シェルスクリプトを使っています。
2番目に実行される初期化処理(SQL)
~/docker_test/init/02_init.sql
SQL のファイルは用途ごとに分けても良いです。
01_create_database.sql
02_create_tables.sql
03_insert_test_data.sql
Docker Compose でコンテナを起動する
http://localhost:8080/test_db.php にアクセスして、テストデータが表示されれば OK です。
外部の SQL ファイルとシェルスクリプトを使って DB を操作します。
一度コンテナの停止とボリュームの削除を行います。
コマンド
docker compose down -v
~/docker_test/docker-compose.yml の修正
コード(抜粋)
(省略)
mariadb:
image: mariadb:latest
container_name: mariadb-test
ports:
- "3306:3306"
volumes:
- db-data:/var/lib/mysql
# コメントアウトを解除する
- ./init:/docker-entrypoint-initdb.d # 初期化(./init 配下の .sql と .sh の実行)
environment:
- MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
# - MYSQL_DATABASE=test # 削除。コメントアウト
# - MYSQL_USER=app # 削除。コメントアウト
- MYSQL_PASSWORD=${DB_APP_PASSWORD}
networks:
- app-network
(省略)
volumes で、init ディレクトリを、初期化用のディレクトリとするように指定します。ここで指定したディレクトリに、.sql や .sh のファイルを入れると、ボリュームが空の時に1度だけ実行されます。
実行される順番は、ファイル名の昇順です。ファイル名の先頭に、頭を0埋めにした番号を付けるとわかりやすいです。
environment から MYSQL_DATABASE と MYSQL_USER の定義を削除します。
これを指定すると、自動的にデータベースとユーザが作成されるため。
外部の SQL ファイルでデータベースとユーザを作成しない場合は、残したままにします。
init ディレクトリの作成
コマンド
mkdir -p ~/docker_test/init
1番目に実行される初期化処理(シェルスクリプト)
~/docker_test/init/01_init.sh
コマンド
#!/bin/bash
set -e # エラーが出たら即停止
mariadb -u root -p"${MYSQL_ROOT_PASSWORD}" <<EOF
CREATE USER 'app'@'%' IDENTIFIED BY "${MYSQL_PASSWORD}"; # appユーザの作成
CREATE DATABASE IF NOT EXISTS test; # データベースの作成
GRANT ALL PRIVILEGES ON test.* TO 'app'@'%'; # appユーザにtestデータベースの全てのテーブルに対する操作権限を付与
FLUSH PRIVILEGES; # 実行した GRANT の反映
EOF
mariadb に接続して、app ユーザ、test データベース、app ユーザの権限設定を行います。<<EOF から EOF に囲まれた部分が mariadb に渡されます。
【注意】
${MYSQL_ROOT_PASSWORD} と ${MYSQL_PASSWORD} は、docker-compose.yml の environment で指定した変数です。
.env の変数は直接使えないので注意してください。
また、SQL の中では環境変数が使えないため、シェルスクリプトを使っています。
2番目に実行される初期化処理(SQL)
~/docker_test/init/02_init.sql
コマンド
-- データベースの選択
use test;
-- テーブル作成
CREATE TABLE table1 (
id INT NOT NULL AUTO_INCREMENT,
text TEXT NOT NULL,
PRIMARY KEY (id)
) ENGINE = InnoDB;
--データ作成
INSERT INTO table1 (text) values ('test1'), ('test2'), ('test3');
テーブル作成とデータ作成を行います。SQL のファイルは用途ごとに分けても良いです。
01_create_database.sql
02_create_tables.sql
03_insert_test_data.sql
Docker Compose でコンテナを起動する
コマンド
docker compose up -d
http://localhost:8080/test_db.php にアクセスして、テストデータが表示されれば OK です。
8. コンテナ削除・再起動後の DB のデータの確認
DB に bash で接続して、SQL でデータを追加します。
http://localhost:8080/test_db.php にアクセスすると、表示されるデータが増えます。
コンテナを停止・削除して、再度コンテナを起動します。
http://localhost:8080/test_db.php にアクセスすると、先ほど追加したデータが残っていることが確認できます。
DB のデータがボリューム(コンテナの外)にあるため、コンテナを削除しても、データが残っています。
コンテナを停止・削除して、再度コンテナを起動します。
http://localhost:8080/test_db.php にアクセスすると、ボリュームを削除したため、先ほど追加したデータが表示されなくなります。
コマンド
docker exec -it mariadb-test bash
mariadb -u app -p
use test
INSERT INTO table1 (text) values ('test4'), ('test5'), ('test6');
http://localhost:8080/test_db.php にアクセスすると、表示されるデータが増えます。
コンテナを停止・削除して、再度コンテナを起動します。
コマンド
docker compose down # コンテナの停止・削除
docker compose up -d # コンテナの起動
http://localhost:8080/test_db.php にアクセスすると、先ほど追加したデータが残っていることが確認できます。
DB のデータがボリューム(コンテナの外)にあるため、コンテナを削除しても、データが残っています。
コンテナを停止・削除して、再度コンテナを起動します。
コマンド
docker compose down -v # コンテナの停止・削除、ボリュームの削除
docker compose up -d # コンテナの起動
http://localhost:8080/test_db.php にアクセスすると、ボリュームを削除したため、先ほど追加したデータが表示されなくなります。

