![Obteniendo un SQLSTATE[HY000] [2002] Conexión rechazada en el contenedor PHP Apache Docker usando mariadb, si está conectado a través del CMD de Dockerfile (PHP CLI funciona)](https://rvso.com/image/781990/Obteniendo%20un%20SQLSTATE%5BHY000%5D%20%5B2002%5D%20Conexi%C3%B3n%20rechazada%20en%20el%20contenedor%20PHP%20Apache%20Docker%20usando%20mariadb%2C%20si%20est%C3%A1%20conectado%20a%20trav%C3%A9s%20del%20CMD%20de%20Dockerfile%20(PHP%20CLI%20funciona).png)
Estoy intentando ejecutar un contenedor Docker basado en:
- PHP 8.1
- Apache 2.4
- MariaDB (última imagen oficial de Docker)
Todo arranca sin ningún problema; pero no puedo conectarme con la base de datos del contenedor Docker a través de PDO.
Archivo 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:
Según la mayoría de las publicaciones y respuestas de diferentes foros, he intentado usar tanto localhost
como 127.0.0.1
el valor de la variable de entorno MARIADB_HOST
(y además, me interesa saber por qué debería funcionar). De todos modos no soluciona el problema, el siguiente código php (contenido de 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
]
);
Siempre resulta en:
SQLSTATE[HY000] [2002] Connection refused
.
ACTUALIZAR
Llegué un paso más allá reemplazando esta línea aquí:
MARIADB_HOST: "127.0.0.1"
con el nombre de mi servicio de base de datos; ser:
MARIADB_HOST: db
Descubrí esto porque descubrí al mismo tiempo que solo puedo iniciar sesión en el panel de administración si lo uso db
como anfitrión. Por lo tanto, esto fue más bien una suposición, y todavía me encantaría entender por qué funciona ahora.
Sin embargo, esto todavía no funciona del todo. Solo funciona si omito la CMD
línea en el dockerfile, construyo el contenedor, migro a su terminal a través de docker exec -t -i php-apache /bin/bash
y ejecuto el comando php src/init.php
desde allí. Si intento hacerlo a través CMD
del formulario Dockerfile
(como se detalla anteriormente), aparece el error mencionado. ¿Qué me falta todavía? Por supuesto, preferiría automatizar esta llamada de inicio con el inicio del contenedor Docker. Profundizando más...
Respuesta1
Lo tengo de verdad ahora. La conexión fue rechazada porque las variables de entorno solo se usaban si el script se ejecuta a través del shell, y a través de Docker, CMD
como lo usé, no se produjo ningún procesamiento del shell. De los documentos, también encontréeste:
A diferencia del formulario de shell, el formulario exec no invoca un shell de comandos. Esto significa que no se produce el procesamiento normal del shell. Por ejemplo, CMD [ "echo", "$HOME" ] no sustituirá variables en $HOME. Si desea procesar el shell, utilice el formulario del shell o ejecute un shell directamente, por ejemplo: CMD [ "sh", "-c", "echo $HOME" ]. Cuando se utiliza el formulario exec y se ejecuta un shell directamente, como en el caso del formulario shell, es el shell el que realiza la expansión de la variable de entorno, no la ventana acoplable.
Cuando se usa en los formatos shell o exec, la instrucción CMD establece el comando que se ejecutará al ejecutar la imagen.
Si usa la forma shell del CMD, entonces se ejecutará en /bin/sh -c
Usando:
CMD [ "sh", "-c", "php src/init.php" ]
en lugar de:
CMD [ "php", "src/init.php" ]
¡Hizo el trabajo!