Docker + PHP + Nginx で exited with code 0 が発生した時の対応

Docker + PHP + Nginx の環境下にて Docker の設定ファイルを見直していたら、
下記メッセージが出て PHP のコンテナが停止した。

$ docker-compose up
.
.
.
exited with code 0

環境

  • Docker v28
  • Docker Desktop v4
  • Nginx v1
  • PHP v8

exited with code 0 とは

このメッセージはエラーではなく Docker の仕様で、
コンテナの起動を継続するためのプロセスがなかったのでコンテナが停止した。
というものらしい。

これも仕様か分からないけど、
Dockerfile で CMD や、
docker-compose.yaml で command を使うと、
exited with code 0 が出る。

サンプルコード

このままだと PHP は動かない。

docker-compose.yaml

一応 command のところをコメントアウトすると PHP は動く。

services:
    sample-app:
        image: nginx:1
        working_dir: /var/www/html
        depends_on:
            - sample-php
        ports:
            - 8080:80
        tty: true
        volumes:
            - ./app:/var/www/html
            - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    sample-php:
        build:
            context: .
            dockerfile: ./php/Dockerfile
        volumes:
            - ./app:/var/www/html
            - ./app/logs:/var/www/html/logs
        command: "bin/composer install"

/nginx/default.conf

このファイルは今回あまり関係ないので割愛。

/php/Dockerfile

このファイルも今回あまり関係ないので割愛。

/app/bin/composer

このファイルも今回あまり関係ないので割愛。

/app/public/index.php

echo するだけ。

<?php echo 'hello, world'; ?>

対応する

その1 tty: true (これでは解決しない)

  • 有名なやつ
  • docker run -it コンテナ名 の -t にあたるらしい
  • コンテナと仮想端末(キーボード入力)を結びつける?設定らしい
  • 公式日本語化プロジェクト によるとコンテナに TTY を使って実行する設定とのこと
services:
    sample-app:
        image: nginx:1
        working_dir: /var/www/html
        depends_on:
            - sample-php
        ports:
            - 8080:80
        tty: true
        volumes:
            - ./app:/var/www/html
            - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    sample-php:
        build:
            context: .
            dockerfile: ./php/Dockerfile
        volumes:
            - ./app:/var/www/html
            - ./app/logs:/var/www/html/logs
        command: "bin/composer install"
        # 追加
        tty: true

nginx はこれでうまくいけど、
php になるとこれでは解決しなかった。

$ docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED        STATUS        PORTS                  NAMES
dfd138bca583   nginx:1        "/docker-entrypoint.…"   19 hours ago   Up 19 hours   0.0.0.0:8080->80/tcp   sample-app-1

PHP のコンテナが停止している。

その2 stdin_open: true (これでも解決しない)

  • docker run -it コンテナ名 の -i にあたるらしい
  • 公式日本語化プロジェクト によるとコンテナに標準入力を割り当てて実行する設定とのこと
services:
    sample-app:
        image: nginx:1
        working_dir: /var/www/html
        depends_on:
            - sample-php
        ports:
            - 8080:80
        tty: true
        volumes:
            - ./app:/var/www/html
            - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    sample-php:
        build:
            context: .
            dockerfile: ./php/Dockerfile
        volumes:
            - ./app:/var/www/html
            - ./app/logs:/var/www/html/logs
        command: "bin/composer install"
        # 追加
        stdin_open: true

こちらも PHP は動かない。

$ docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED        STATUS        PORTS                  NAMES
dfd138bca583   nginx:1        "/docker-entrypoint.…"   19 hours ago   Up 19 hours   0.0.0.0:8080->80/tcp   sample-app-1

PHP のコンテナが停止している。

その3 何かしらのプログラムを実行する

とりあえず何かしらの常駐プログラムを実行させれば、
コンテナは停止しないらしい。

まずは command でシェルスクリプトを実行するように変更する。

services:
    sample-app:
        image: nginx:1
        working_dir: /var/www/html
        depends_on:
            - sample-php
        ports:
            - 8080:80
        tty: true
        volumes:
            - ./app:/var/www/html
            - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    sample-php:
        build:
            context: .
            dockerfile: ./php/Dockerfile
        volumes:
            - ./app:/var/www/html
            - ./app/logs:/var/www/html/logs
        # 変更
        command: "bin/start_php.sh"

シェルスクリプトファイルを生成して、
権限を変更する。

$ cd /path/to/your/project/app/bin
$ touch start_php.sh
$ chmod 744 start_php.sh

bin/start_php.sh の中身。
色々調べた結果、
php-fpm -F を実行すると、 PHP が動いた。

#!/bin/bash

bin/composer install

# tail -f /dev/null
# php -S 0.0.0.0:8080
php-fpm -F

その他のコメントアウトしてあるものは、
PHP のコンテナ自体は起動し続けるのだけど、
PHP が動かなかった。

$ docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED        STATUS        PORTS                  NAMES
dfd138bca583   nginx:1        "/docker-entrypoint.…"   19 hours ago   Up 19 hours   0.0.0.0:8080->80/tcp   sample-app-1
51dd46553ebe   sample-php     "docker-php-entrypoi…"   19 hours ago   Up 19 hours   9000/tcp               sample-php-1

参考記事。