PHP シェル CMD を実行した後も実行し続けるように Apache Docker コンテナを設定する

PHP シェル CMD を実行した後も実行し続けるように Apache Docker コンテナを設定する

以下に基づいて Docker コンテナを実行しようとしています:

  • PHP8.1 について
  • アパッチ2.4
  • MariaDB (最新の公式 Docker イメージ)

Dockerファイル:

FROM php:8.1-apache

WORKDIR /var/www/html/

RUN pecl install xdebug \
    && apt update \
    && apt install libzip-dev -y \
    && docker-php-ext-enable xdebug \
    && a2enmod rewrite \
    && docker-php-ext-install zip \
    && rm -rf /var/lib/apt/lists/* \
    && docker-php-ext-install pdo pdo_mysql

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
COPY composer.json .

RUN groupadd -r user && useradd -r -g user user
USER user
RUN composer install --no-dev

COPY . .

EXPOSE 80

CMD [ "sh", "-c", "php src/init.php" ]

docker-compose.yml:

services:

  php:
    build: ./php
    depends_on:
      - db
      - adminer
    container_name: php-apache
    ports:
      - 80:80
    volumes:
      # setup xdebug to be able to use PHP step debugger, if needed
      - ./php/conf.d/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
      - ./php/conf.d/error_reporting.ini:/usr/local/etc/php/conf.d/error_reporting.ini
      # apache config (server name)
      - ./apache/apache2.conf:/etc/apache2/apache2.conf
      # apache config (rewrite rule to reroute all requests to unknown resources through to REST controller)
      - ./apache/000-default.conf:/etc/apache2/sites-enabled/000-default.conf
      # Source code
      - ./php/src:/var/www/html/src
      # unbind local composer components
      - /php/vendor
      - /php/composer.lock
      - /php/composer.phar
    environment:
      MARIADB_HOST: "127.0.0.1"
      MARIADB_USER: root
      MARIADB_PASSWORD: top_very_secret
      MARIADB_DB: apidb

  adminer:
    image: adminer
    depends_on:
      - db
    restart: always
    ports:
      - 8080:8080

  db:
    image: mariadb
    container_name: db
    volumes:
      - maria-db-storage:/var/lib/mysql
    environment:
      MARIADB_ROOT_PASSWORD: top_very_secret
      MARIADB_DATABASE: apidb
    ports:
      - 3306:3306

volumes:
  maria-db-storage:

スクリプト src/init.php は、DB に接続し、アプリケーションに必要なテーブルがまだ存在しない場合はそれを生成します。

/src/init.php私の現在の問題は、Docker コンテナの実行が常に( )の実行の成功で終了することですphp-apache exited with code 0。ドキュメントによると、コンテナは が実行されている間だけ存続するため、これは Docker では正常であることはわかっていますCMD。しかし、コンテナが実行し続け、コンテナの起動時にアプリケーションに必要なものがすべて揃っていることを保証するためにスクリプトが単純に起動されるようにするにはどうすればよいでしょinit.phpうか。

アップデート

init.sh私は以下の内容を使用してこれを設定しようとしました:

#!/bin/sh
php src/init.php
apache2 -D FOREGROUND

次に、以下を置き換えました:

CMD [ "sh", "-c", "php src/init.php" ]

CMD ["sh", "-c", "/var/www/html/start.sh"]

これにより、PHP スクリプトは正常に実行されますが、apache コマンドの実行は失敗し、次のメッセージが表示されます。

[core:warn] [pid 10] AH00111: Config variable ${APACHE_RUN_DIR} is not defined

つまり、Apache の変数はシェル実行ではアクセスできないようです。

答え1

さて、これで実用的な解決策が見つかりました。まず、理由は次のとおりです。

[core:warn] [pid 10] AH00111: Config variable ${APACHE_RUN_DIR} is not defined

問題は、Apache をフォアグラウンドで実行するために間違ったコマンド ツールを使用したことです。apache2ctlの代わりにを使用すると、apache2問題は解決しました ( ではapache2、Apache の環境変数は利用できないようです)。

次に、私の最終的な内容は次のstart.shとおりです。

#!/bin/sh
wait-for-it.sh db:3306 --strict --timeout=30 -- php init.php && apache2ctl -D FOREGROUND

ご覧のとおり、もう1つ追加したものがあります。docker-composeコンテナを同時に起動します(これ、セクション「MariaDBの初期化が完了するまで接続できません」)。このようにして、イメージがまだプルされていないマシンで現在のアプリケーションのコンテナを起動すると、コンテナが完全に初期化されていない状態で に接続しようとする をmariadb実行しようとする可能性が非常に高くなります。これにより、再び愛されているエラーが発生します。Docker自体init.phpdbdbSQLSTATE[HY000] [2002] Connection refused言及それを待つ回避策としてこのソリューションを使用しました。上記のコードで実行されるのは次のことだけです。

  • アドレスがdb:3306使用可能かどうかを最大 30 秒間確認します。
  • その時間内に利用可能になった場合は、その後のすべてを実行します--
  • その時間内に利用できない場合は、実行を中断します (コンテナの初期化が失敗することになります)。

より厳密なアプローチとしては、init.php接続が失敗した場合に 5 秒の間隔を空けてから最大 x 回 DB への接続を再試行するようにコードを記述することもできます。これも目的を果たします。

すべてが正常に動作しています。

関連情報