在 docker 映像中,我想避免安装 netcat 以便在入口点脚本中 ping 数据库连接:
/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 来替代在 docker 映像上运行的入口点脚本。
还有其他选择吗?
我想要这样做的原因是因为我有 2 个 Dockerfile,一个基于 debian,一个基于 alpine:
基于 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);"
需要fsockopen
2 个参数:
host
port
我所做的是尝试在 php 中打开一个套接字并检查套接字是否已打开。如果是,则我以0
状态代码退出,否则我以1
.每个参数都使用来自 shell 脚本的字符串传递,因此我"
使用字符进行编码\
,以便将值转换为 php 字符串。
不使用 vars 你可以这样做:
php -r "is_resource(@fsockopen(\"google.com",80)))?exit(0):exit(1);"
但是为了安全起见,我使用了使用 bash 参数的版本中的 intval。