
다음을 기반으로 Docker 컨테이너를 실행하려고 합니다.
- PHP 8.1
- 아파치 2.4
- MariaDB(최신 공식 도커 이미지)
도커파일:
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" ]
도커-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
. CMD
문서에 따르면 컨테이너는 실행 중인 동안에만 지속되므로 Docker에서는 이것이 정상이라는 것을 알고 있습니다 . 하지만 컨테이너가 계속 실행되는지 어떻게 확인할 수 있나요? 그리고 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
그러면 쉘 실행으로 아파치의 변수에 접근할 수 없는 것 같나요??
답변1
좋아, 이제 작동하는 솔루션을 얻었습니다. 우선 그 이유는 다음과 같습니다.
[core:warn] [pid 10] AH00111: Config variable ${APACHE_RUN_DIR} is not defined
내가 포그라운드에서 아파치를 실행하기 위해 잘못된 명령 도구를 사용했다는 것입니다. apache2ctl
대신 사용하여 apache2
작업을 수행했습니다( apache2
Apache의 환경 변수를 사용할 수 없는 것 같았습니다).
다음으로 my의 최종 내용은 다음 start.sh
과 같습니다.
#!/bin/sh
wait-for-it.sh db:3306 --strict --timeout=30 -- php init.php && apache2ctl -D FOREGROUND
이제 보시다시피 추가한 것이 있습니다. docker-compose
컨테이너를 동시에 시작합니다(참조:이것, "MariaDB 초기화가 완료될 때까지 연결이 없습니다" 섹션). 따라서 아직 이미지를 가져오지 않은 시스템에서 현재 애플리케이션의 컨테이너를 시작하면 컨테이너가 실제로 완전히 초기화되지 않은 채 에 연결을 시도하는 mariadb
실행을 시도할 가능성이 매우 높습니다 . 이로 인해 다시 사랑받는 오류가 발생합니다. 도커 자체init.php
db
db
SQLSTATE[HY000] [2002] Connection refused
언급하다그만큼좀 기다려해결 방법으로 솔루션을 사용했기 때문에 사용했습니다. 위에 표시된 코드에서 수행되는 작업은 다음과 같습니다.
- 주소가
db:3306
사용 가능한지 최대 30초 동안 확인하세요. - 해당 시간 내에 사용할 수 있게 되면 이후의 모든 항목을 실행합니다
--
. - 해당 시간 내에 사용할 수 없게 되면 실행을 중단합니다(컨테이너 초기화가 실패하는 경우).
이에 대한 보다 엄격한 접근 방식을 위해 init.php
연결이 실패할 경우 5초 간격을 기다린 후 최대 x회 동안 DB에 연결을 다시 시도하도록 코딩할 수도 있습니다. 그러면 그것도 효과가 있을 것입니다.
이제 모든 것이 완벽하게 작동하고 있습니다!