こんにちは
昨日に引き続き DooD(Docker outside of Docker) 関連の記事になります
今回は DooD(Docker outside of Docker) で Dockerコンテナ内で docker-compose を利用できるようにしてみたので、ここに残しておきます
なお、DooD(Docker outside of Docker) については、前回の記事で割としっかりめに記載しているので、この記事では説明しません
■概要
APPコンテナからWebコンテナへ対して docker compose コマンドを利用したコンテナ操作を実現してみます
なお、docker-compose.yml の構成や基本的なDockerファイルの中身は 前回の記事 と変わりません
そのうえで、前回とは異なり docker-compose.yml をホストOSとAPPコンテナ間でバインドマウントし、コンテナ内でも docker-compose.yml を認識できるようにします
■流れ
流れとしては、まず docker-compose.yml をホストOSとAPPコンテナ間でバインドマウントしない場合は、どうなるのか確認します
その後、docker-compose.yml をバインドマウントして、正常に実行できることを最後に確認します
1. docker-compose.yml をバインドマウントせずに、APPコンテナからWebコンテナへ操作
2. docker-compose.yml をバインドマウント
3. docker-compose.yml をバインドマウントした状態で、APPコンテナからWebコンテナへ操作
■手順
1. docker-compose.yml をバインドマウントせずに、APPコンテナからWebコンテナへ操作
まずは、ホストOS上の docker-compose.yml の中身を確認し、バインドマウントしていないことを確認します
version: "3.9"
services:
web01:
build:
context: ./
dockerfile: web/Dockerfile
container_name: web01-container
volumes:
- ./app/src:/var/www/vhosts/www.example.com/public_html
depends_on:
- app01
ports:
- "80:80"
app01:
build:
context: ./
dockerfile: app/Dockerfile
container_name: app01-container
volumes:
- ./app/src:/var/www/vhosts/www.example.com/public_html
- /var/run/docker.sock:/var/run/docker.sock
restart: always
ports:
- "9000:9000"
次に、APPコンテナ へ入ります
docker container ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7405f96f6c4d nginx_php-fpm_docker-web01 "/docker-entrypoint.…" 22 hours ago Up 29 seconds 0.0.0.0:80->80/tcp, [::]:80->80/tcp web01-container f491c7cd0510 nginx_php-fpm_docker-app01 "docker-php-entrypoi…" 22 hours ago Up 19 minutes 0.0.0.0:9000->9000/tcp, [::]:9000->9000/tcp app01-container
docker exec -it f491c7cd0510 bash
docker composeコマンドが入っていることを確認し、Webコンテナへ対して docker compose コマンドを実行します
www-data@f491c7cd0510:~/vhosts/www.example.com/public_html$ docker compose version Docker Compose version v2.27.1
→ APPコンテナ内であれば、docker compose コマンドが通ることを確認
docker compose exec web01 nginx -v
www-data@f491c7cd0510:~/vhosts/www.example.com/public_html$ docker compose exec web01 nginx -v no configuration file provided: not found
→ docker-compose.yml がないので、configuration file のエラーが出ました
2. docker-compose.yml をバインドマウント
それでは、docker-compose.yml をバインドマウントするので、まずは APPコンテナ内で docker-compose.ymlを配置する用のディレクトリを作成します
なお、docker-compose.yml のみ /home/docker ディレクトリ直下へ配置した理由としては、WebとAPPコンテナでドキュメントルート配下を共有しており、
もしドキュメントルート直下に配置すると、最悪インターネット上から確認可能になる可能性があるためです
FROM php:8.0.30-fpm
#php.ini用confファイルコピー
COPY ./app/conf/disable_display_error.ini /usr/local/etc/php/conf.d/
#php-fpm用confファイルコピー
COPY ./app/conf/zz-docker.conf /usr/local/etc/php-fpm.d/
#ドキュメントルート作成
RUN apt-get update -y && \
apt-get install -y vim less && \
docker-php-ext-install pdo_mysql && \
mkdir -p /var/www/vhosts/www.example.com/public_html && \
mkdir -p /home/docker ★
COPY ./app/src /var/www/vhosts/www.example.com/public_html
# Docker CLI(静的バイナリ)
RUN curl -fsSL https://download.docker.com/linux/static/stable/x86_64/docker-27.0.3.tgz \
| tar xz --strip-components=1 -C /usr/local/bin docker/docker
# Docker Compose v2 プラグイン
RUN mkdir -p /usr/local/lib/docker/cli-plugins && \
curl -fsSL "https://github.com/docker/compose/releases/download/v2.27.1/docker-compose-linux-x86_64" \
-o /usr/local/lib/docker/cli-plugins/docker-compose && \
chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
RUN groupmod -g 1000 www-data
RUN usermod -u 1000 www-data
RUN groupadd -g 991 docker && usermod -aG docker www-data
# ユーザー切り替え
USER www-data
#作業ディレクトリ設定
WORKDIR /var/www/vhosts/www.example.com/public_html
#ポート開放
EXPOSE 9000
→ ★の個所を追記しました
次に docker-compose.yml でバインドマウントします
version: "3.9"
services:
web01:
build:
context: ./
dockerfile: web/Dockerfile
container_name: web01-container
volumes:
- ./app/src:/var/www/vhosts/www.example.com/public_html
depends_on:
- app01
ports:
- "80:80"
app01:
build:
context: ./
dockerfile: app/Dockerfile
container_name: app01-container
volumes:
- ./app/src:/var/www/vhosts/www.example.com/public_html
- /var/run/docker.sock:/var/run/docker.sock
- ./docker-compose.yml:/home/docker/docker-compose.yml ★
restart: always
ports:
- "9000:9000"
→ カレントディレクトリ直下の docker-compose.yml をコンテナ内のパスにバインドマウントしています
3. docker-compose.yml をバインドマウントした状態で、APPコンテナからWebコンテナへ操作
それでは、設定反映のため docker-compose を利用してコンテナ削除と起動を実施します
docker-compose down && docker-compose up -d
docker container ps -a
最後に、APPコンテナへ入り、Webコンテナへ操作してみます
docker exec -it f45dbc30d49a bash
/home/dockerまで移動し、docker compose コマンドを実行します
docker compose exec web01 nginx -v
WARN[0000] /home/docker/docker-compose.yml: `version` is obsolete service "web01" is not running
→ service “web01” is not running のエラーになりました
■なぜエラーになった?
それでは、なぜ カレントディレクトリ直下に docker-compose.yml が存在するにもかかわらず、エラーになったのでしょうか?
原因としては、docker-compose のプロジェクトが関係してきます(参考:単一ホスト上で、複数の環境を分離)
まず docker-compose におけるプロジェクトとは、1つの設定ファイル(compose.yaml)で管理される複数のコンテナやネットワークなどの集まりを指し、
プロジェクト名はデフォルトでは設定ファイルが置いてあるフォルダ名が自動的に付けられます
(例:/myapp/compose.yaml の場合は、myapp がプロジェクト名になる)
そのため、上述の通り、compose.yml ファイルごとにプロジェクトが作成されるため、もし2つのディレクトリ内に2つの別々の compose.yml を配置してしまうと、
プロジェクト名が重複してしまい、本当は b-compose.yml の操作を実施したかったのに、誤って b-compose.yml の操作を実施してしまうなどは発生します
したがって、複数の compose.yml を利用する場合は、compose.yml 上で name を利用し、compose.yml 毎にプロジェクトを分離する方法がよいかと思います
▼例
version: "3.9"
name: dood01 ★
services:
web01:
build:
context: ./
dockerfile: web/Dockerfile
container_name: web01-container
volumes:
- ./app/src:/var/www/vhosts/www.example.com/public_html
depends_on:
- app01
ports:
- "80:80"
→ 上記だと dood01 がプロジェクト名になります
そのうえで、今回の構成を確認してみると、ホストOS上の nginx_php-fpm_docker ディレクトリ内に docker-compose.yml が配置されており、それを利用して WebコンテナとAPPコンテナを起動しました
そのため、ホストOS上ではプロジェクト名が nginx_php-fpm_docker になっています
docker-compose ls
[root@dood01 nginx_php-fpm_docker]# docker-compose ls NAME STATUS CONFIG FILES nginx_php-fpm_docker running(2) /root/nginx_php-fpm_docker/docker-compose.yml
次に、APPコンテナの /home/docker 上でプロジェクト名を確認してみます
docker compose ls
www-data@f45dbc30d49a:/home/docker$ docker compose ls NAME STATUS CONFIG FILES nginx_php-fpm_docker running(2) /root/nginx_php-fpm_docker/docker-compose.yml
→ あれ? docker プロジェクトではない??
理由としては、今回 APPコンテナ内で docker-compose.yml を実行しておらず、
どうやら docker compose ls コマンドは docker.sock 経由で共有しているホストのデーモンを見にいくみたいなので、ホスト側の nginx_php-fpm_docker が表示されています
それでは、一度 プロジェクトを指定し、Webコンテナへ対してコマンドを実行してみます
docker compose -p nginx_php-fpm_docker exec web01 nginx -v
www-data@f45dbc30d49a:/home/docker$ docker compose -p nginx_php-fpm_docker exec web01 nginx -v nginx version: nginx/1.25.0
→ Nginx のバージョンが表示されたので、問題なく動作してそうです
次に、Webコンテナを停止してみます
docker compose -p nginx_php-fpm_docker stop web01
www-data@f45dbc30d49a:/home/docker$ docker compose -p nginx_php-fpm_docker stop web01 [+] Stopping 1/1 ✔ Container web01-container Stopped
www-data@f45dbc30d49a:/home/docker$ docker compose -p nginx_php-fpm_docker ps NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS app01-container nginx_php-fpm_docker-app01 "docker-php-entrypoi…" app01 55 minutes ago Up 55 minutes 0.0.0.0:9000->9000/tcp, :::9000->9000/tcp
→ APPコンテナのみ起動しています
■最後に
いかがでしたでしょうか
正直これまでにdocker-composeのプロジェクトの概念を知らなかったので、最初はかなりはまりました、、、
ただ、一度理解すれば、そこまで複雑ではない + docker-compose の設計に幅を持たせることができると思ったので、今後は積極的に利用していきたいです