![SQLSTATE[HY000] [2002] を取得すると、Dockerfile の CMD 経由で接続した場合、mariadb を使用した PHP Apache Docker コンテナで接続が拒否されます (PHP CLI は動作します)](https://rvso.com/image/781990/SQLSTATE%5BHY000%5D%20%5B2002%5D%20%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B%E3%81%A8%E3%80%81Dockerfile%20%E3%81%AE%20CMD%20%E7%B5%8C%E7%94%B1%E3%81%A7%E6%8E%A5%E7%B6%9A%E3%81%97%E3%81%9F%E5%A0%B4%E5%90%88%E3%80%81mariadb%20%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9F%20PHP%20Apache%20Docker%20%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%A7%E6%8E%A5%E7%B6%9A%E3%81%8C%E6%8B%92%E5%90%A6%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%20(PHP%20CLI%20%E3%81%AF%E5%8B%95%E4%BD%9C%E3%81%97%E3%81%BE%E3%81%99).png)
以下に基づいて Docker コンテナを実行しようとしています:
- PHP8.1 について
- アパッチ2.4
- MariaDB (最新の公式 Docker イメージ)
すべて問題なく起動しますが、PDO 経由で Docker コンテナの DB に接続できません。
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 ["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:
さまざまなフォーラムからの投稿や回答の大部分によると、私は と を環境変数の値としてlocalhost
使用しようとしました (また、なぜそれが機能するはずなのかを知りたいです)。とにかく、次の PHP コード ( の内容) では問題は解決されません。127.0.0.1
MARIADB_HOST
src/init.php
new PDO(
"mysql:host={$_ENV['MARIADB_HOST']};dbname={$_ENV['MARIADB_DB']}",
$_ENV['MARIADB_USER'],
$_ENV['MARIADB_PASSWORD'],
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]
);
常に次の結果になります:
SQLSTATE[HY000] [2002] Connection refused
。
アップデート
私はさらに一歩進んで、この行を次のように置き換えました。
MARIADB_HOST: "127.0.0.1"
データベース サービスの名前は次のようになります。
MARIADB_HOST: db
私がこれを知ったのは、ホストとして使用する場合にのみ管理者ダッシュボードにログインできることが同時にわかったからですdb
。したがって、これはむしろ推測であり、なぜこれが現在機能するのかをまだ理解したいと思っています。
ただし、これはまだ完全には機能しません。dockerfileCMD
の行を省略し、コンテナーをビルドし、 を介してそのターミナルに移行しdocker exec -t -i php-apache /bin/bash
、そこからコマンドを実行する場合にのみ機能します。から(上記のように)php src/init.php
実行しようとすると、前述のエラーが発生します。まだ何が足りないのでしょうか? もちろん、この init 呼び出しを Docker コンテナーの実行開始で自動化したいです。さらに掘り下げます...CMD
Dockerfile
答え1
今では本当に理解できました。環境変数はスクリプトがシェル経由で実行される場合にのみ使用され、Docker経由では(私が使用したように)シェル処理は行われなかったため、接続CMD
が拒否されました。ドキュメントから、私はまたこれ:
シェル形式とは異なり、exec 形式はコマンド シェルを呼び出しません。つまり、通常のシェル処理は行われません。たとえば、CMD [ "echo", "$HOME" ] は $HOME で変数置換を行いません。シェル処理が必要な場合は、シェル形式を使用するか、シェルを直接実行します (例: CMD [ "sh", "-c", "echo $HOME" ])。exec 形式を使用してシェルを直接実行する場合、シェル形式の場合と同様に、環境変数の展開を行うのはシェルであり、docker ではありません。
シェルまたは exec 形式で使用する場合、CMD 命令はイメージの実行時に実行されるコマンドを設定します。
CMDのシェル形式を使用する場合は、/bin/sh -cで実行されます。
使用方法:
CMD [ "sh", "-c", "php src/init.php" ]
の代わりに:
CMD [ "php", "src/init.php" ]
仕事完了!