SQLSTATE[HY000] 가져오기 [2002] Dockerfile의 CMD를 통해 연결된 경우 mariadb를 사용하는 PHP Apache Docker 컨테이너에서 연결이 거부되었습니다(PHP CLI 작동).

SQLSTATE[HY000] 가져오기 [2002] Dockerfile의 CMD를 통해 연결된 경우 mariadb를 사용하는 PHP Apache Docker 컨테이너에서 연결이 거부되었습니다(PHP CLI 작동).

다음을 기반으로 Docker 컨테이너를 실행하려고 합니다.

  • PHP 8.1
  • 아파치 2.4
  • MariaDB(최신 공식 도커 이미지)

모든 것이 문제 없이 시작됩니다. 하지만 PDO를 통해 Docker 컨테이너의 DB에 연결할 수 없습니다.

도커파일:

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"]

도커-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.1MARIADB_HOSTsrc/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제가 이것을 호스트로 사용해야만 관리자 대시보드에 로그인할 수 있다는 사실을 동시에 알게 되었기 때문에 알게 되었습니다 . 따라서 이것은 추측에 불과하며 이것이 지금 작동하는 이유를 여전히 이해하고 싶습니다..?

그러나 이것은 아직 완전히 작동하지 않습니다. CMDdockerfile에서 줄을 생략하고, 컨테이너를 빌드하고, 를 통해 터미널로 마이그레이션하고 , 거기에서 docker exec -t -i php-apache /bin/bash명령을 실행하는 경우에만 작동합니다 . 위에서 설명한 대로 양식을 php src/init.php통해 그렇게 하려고 하면 언급된 오류가 발생합니다. 내가 아직 무엇을 놓치고 있나요? 물론 저는 Docker 컨테이너의 실행 시작과 함께 이 init 호출을 자동화하는 것을 선호합니다. 더 파고들다...CMDDockerfile

답변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" ]

일을 했어요!

관련 정보