Docker 이미지에서는 진입점 스크립트에서 데이터베이스 연결을 핑하기 위해 netcat을 설치하지 않으려고 합니다.
/bin/sh
MOODLE_DB_HOST="xxxx"
MOODLE_DB_PORT=80
function pingdb {
OK=0
for count in {1..100}; do
echo "Pinging database attempt ${count} into ${MOODLE_DB_HOST}:${MOODLE_DB_PORT}"
if $(nc -z ${MOODLE_DB_HOST} ${MOODLE_DB_PORT}) ; then
echo "Can connect into database"
OK=1
break
fi
sleep 5
done
echo "Is ok? "$OK
if [ $OK -eq 1 ]; then
echo "Database type: "${MOODLE_DB_TYPE}
echo "DB Type: "${MOODLE_DB_TYPE}
else
echo >&2 "Can't connect into database"
exit 1
fi
}
nc
하지만 대신에 도커 이미지에서 실행되는 진입점 스크립트 대신 PHP를 사용하고 싶습니다 .
다른 옵션이 있나요?
내가 이 작업을 수행하려는 이유는 Debian 기반과 Alpine 기반의 Dockerfile이 2개 있기 때문입니다.
Debian 기반 PHP 이미지:
ARG PHP_VERSION="7.4"
FROM php:${PHP_VERSION}-fpm as base
RUN --mount=type=bind,from=mlocati/php-extension-installer:latest,source=/usr/bin/install-php-extensions,target=/usr/local/bin/install-php-extensions \
/usr/local/bin/install-php-extensions xmlrpc mbstring zip xml intl soap gd opcache &&\
echo "PHP_EXTENTION_DIR="$(php -i | grep extension_dir | cut -d " " -f 5) >> /etc/environment &&\
cat /etc/environment &&\
apt-get update &&\
apt-get install -y netcat &&\
apt-get autopurge -y &&\
apt-get autoremove -y &&\
apt-get autoclean &&\
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* cache/* /var/lib/log/* &&\
echo "max_input_vars=5000" > ${PHP_INI_DIR}/conf.d/moodle.ini
COPY ./scripts/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chown root:root /usr/local/bin/entrypoint.sh &&\
chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/bin/sh","/usr/local/bin/entrypoint.sh"]
CMD ["php-fpm"]
산 기준:
ARG PHP_VERSION="7.4"
FROM php:${PHP_VERSION}-fpm-alpine as base
RUN --mount=type=bind,from=mlocati/php-extension-installer:latest,source=/usr/bin/install-php-extensions,target=/usr/local/bin/install-php-extensions \
/usr/local/bin/install-php-extensions xmlrpc mbstring zip xml intl soap gd opcache &&\
apk update &&\
apk add netcat-openbsd &&\
rm -rf /var/cache/apk/* /var/tmp/* cache/* /var/lib/log/* &&\
echo "max_input_vars=5000" > ${PHP_INI_DIR}/conf.d/moodle.ini
COPY ./scripts/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chown root:root /usr/local/bin/entrypoint.sh &&\
chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/bin/sh","/usr/local/bin/entrypoint.sh"]
CMD ["php-fpm"]
때로는 매개변수에 따라 PHP_VERSION
netcat 설치용 패키지가 존재하거나 존재하지 않을 수도 있습니다(또는 다른 이름으로 존재할 수도 있습니다). 또한 빌드 시간 apk add
이 apt-get
크게 늘어납니다.
그럼 대안이 있나요?
답변1
바로 여기에:
function pingdb {
OK=0
for i in $(seq 1 100); do
echo "Pinging database attempt ${count} into ${MOODLE_DB_HOST}:${MOODLE_DB_PORT}"
if $(php -r "is_resource(@fsockopen(\"${MOODLE_DB_HOST}\",intval(\"${MOODLE_DB_PORT}\")))?exit(0):exit(1);") ; then
echo "Can connect into database"
OK=1
break
fi
sleep 5
done
if [ $OK -eq 1 ]; then
echo "Database type: "${MOODLE_DB_TYPE}
echo "DB Type: "${MOODLE_DB_TYPE}
else
echo >&2 "Can't connect into database"
exit 1
fi
}
보시다시피 nc
다음이 대체됩니다.
php -r "is_resource(@fsockopen(\"${MOODLE_DB_HOST}\",intval(\"${MOODLE_DB_PORT}\")))?exit(0):exit(1);"
2개의 매개변수가 필요합니다 fsockopen
.
host
port
내가 하는 일은 PHP에서 소켓을 열고 소켓이 열려 있는지 확인하는 것입니다. 그렇다면 0
상태 코드로 종료하고, 그렇지 않으면 로 종료합니다 1
. 각 매개변수는 쉘 스크립트의 문자열을 사용하여 전달되므로 값을 PHP 문자열로 변환하기 위해 "
문자를 사용하여 인코딩합니다 .\
vars를 사용하지 않고도 다음을 수행할 수 있습니다.
php -r "is_resource(@fsockopen(\"google.com",80)))?exit(0):exit(1);"
하지만 안전을 위해 bash 매개변수를 사용하는 버전의 intval을 사용했습니다.