如何解决Docker Compose容器达到彼此的构建时间
我有一个wordpress docker-compose,其中包含3个服务。
1-PHP,Apache
2-mysql
3-phpmyadmin
我想做的是在构建时安装 wordpress内核和插件, 原因很明显,我不想每次重新启动容器时都会重新进行所有步骤,并安装插件和...。所以我需要连接数据库,但似乎在构建时无法访问我的mysql容器。 我读过某个地方,我需要在构建阶段指定网络,但无法使其正常工作。 这是我的docker-compose文件:
version: '3.8'
volumes:
mhndev_systems_mysql_data:
mhndev_systems_wp_uploads:
networks:
mhndev_network:
services:
## --------------------------------------------
## | 1: Wordpress
## --------------------------------------------
mhndev_systems_wp:
build:
context: .
dockerfile: docker/Dockerfile
args:
WP_VERSION: ${WP_VERSION}
MYSQL_HOST: ${MYSQL_HOST}
MYSQL_PORT: ${MYSQL_PORT}
MYSQL_DATABASE_NAME: ${MYSQL_DATABASE_NAME}
MYSQL_USERNAME: ${MYSQL_USERNAME}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
SITE_URL: ${SITE_URL}
DB_TABLE_PREFIX: ${DB_TABLE_PREFIX}
ENV: ${ENV}
UID: ${UID}
GID: ${GID}
SITE_TITLE: ${SITE_TITLE}
SITE_ADMIN_USERNAME: ${SITE_ADMIN_USERNAME}
SITE_ADMIN_PASSWORD: ${SITE_ADMIN_PASSWORD}
SITE_ADMIN_EMAIL: ${SITE_ADMIN_EMAIL}
network: "mhndev_network"
ports:
- 8191:80
env_file:
- .env
volumes:
- ./themes/dt-the7-child:/var/www/html/wp-content/themes/dt-the7-child
- ./plugins/teamcity:/var/www/html/wp-content/plugins/teamcity
- mhndev_systems_wp_uploads:/var/www/html/wp-content/uploads
depends_on:
- mhndev_systems_mysql
networks:
- mhndev_network
## --------------------------------------------
## | 2: Mysql
## --------------------------------------------
mhndev_systems_mysql:
image: mysql:5.7.21
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE_NAME}
MYSQL_USER: ${MYSQL_USERNAME}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- mhndev_systems_mysql_data:/var/lib/mysql
networks:
- mhndev_network
## --------------------------------------------
## | 3: PhpMyAdmin
## --------------------------------------------
mhndev_systems_phpmyadmin:
image: phpmyadmin/phpmyadmin:5.0.2
depends_on:
- mhndev_systems_mysql
ports:
- "7191:80"
environment:
PMA_HOST: mhndev_systems_mysql
networks:
- mhndev_network
这是我的Dockerfile:
FROM php:7.4-apache
ARG WP_VERSION=5.5.1
RUN apt-get update && apt-get install -y \
sendmail \
libpng-dev \
libjpeg-dev \
libfreetype6-dev \
netcat \
gnupg \
libzip-dev \
zip \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install gd pdo_mysql zip \
&& docker-php-ext-install mysqli && docker-php-ext-enable mysqli
ADD ./docker/apache.conf /etc/apache2/sites-enabled/000-default.conf
RUN \
printf "\nServerName localhost" >> /etc/apache2/apache2.conf &&\
a2enmod rewrite expires
### install wp cli
RUN curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar &&\
chmod +x wp-cli.phar &&\
mv wp-cli.phar /usr/local/bin/wp
WORKDIR /var/www/html
RUN wp core download --allow-root
### copy plugins and themes and php config files to container
COPY ["./plugins/*.zip","/docker/plugins/"]
COPY ["./themes/*.zip","/docker/themes/"]
COPY ./themes/dt-the7-child /var/www/html/wp-content/themes/dt-the7-child
COPY ./plugins/teamcity /var/www/html/wp-content/plugins/teamcity
COPY ./docker/php.ini /usr/local/etc/php/php.ini
COPY ./docker/wp-config.php /var/www/html/wp-config.php
COPY ["./plugins/plugins_*.txt","/docker/plugins/"]
COPY ["./uploads/","/docker/uploads/"]
COPY ["./docker/commands/*.sh","/docker/bin/"]
RUN chmod a+x /docker/bin/*.sh
RUN /bin/bash -c "source /docker/bin/setup-theme-plugins.sh"
RUN chown -R www-data:www-data /var/www/html/
CMD apachectl -D FOREGROUND
这是一个bash文件(setup-theme-plugins.sh),负责安装wordpress核心和插件。
#!/bin/bash
echo '-------------------whoami--------------------'
echo $(whoami)
echo '---------------------------------------------'
printf "\033[0;32m > Waiting for mysql ...\x1b[0m \n"
until nc -z -v -w30 "$MYSQL_HOST" "$MYSQL_PORT"
do
echo "Waiting for database connection..."
# wait for 5 seconds before check again
sleep 1
done
printf "\033[0;32m >Mysql is ready ...\x1b[0m \n"
echo '---------------------------------------------'
printf "\033[0;32m > Copy wordpress uploads if not exists (usually first time ) \x1b[0m \n"
FILE=/var/www/html/wp-content/uploads/2020/01/dell.jpg
if [ -f "$FILE" ]; then
echo "$FILE exists,so no need to copy uploads"
else
echo "$FILE does not exist,copying ..."
cp -r /docker/uploads/* /var/www/html/wp-content/uploads
fi
echo '---------------------------------------------'
sed -i s/__DB_NAME__/"${MYSQL_DATABASE_NAME}"/g /var/www/html/wp-config.php
sed -i s/__DB_USER__/"${MYSQL_USERNAME}"/g /var/www/html/wp-config.php
sed -i s/__DB_PASSWORD__/"${MYSQL_PASSWORD}"/g /var/www/html/wp-config.php
sed -i s/__DB_HOST__/"${MYSQL_HOST}"/g /var/www/html/wp-config.php
sed -i s/__SITE_URL__/"${SITE_URL}"/g /var/www/html/wp-config.php
if [[ -n "${DB_TABLE_PREFIX}" ]]; then
sed -i s/__DB_TABLE_PREFIX__/"${DB_TABLE_PREFIX}"/g /var/www/html/wp-config.php
else
sed -i s/__DB_TABLE_PREFIX__/"${DB_TABLE_PREFIX}"/g /var/www/html/wp-config.php
fi
### set WP_DEBUG,SCRIPT_DEBUG based on DEV environment variable
if [ "${ENV}" = "dev" ]; then
sed -i s/__WP_DEBUG__/true/g /var/www/html/wp-config.php
sed -i s/__SCRIPT_DEBUG__/true/g /var/www/html/wp-config.php
else
sed -i s/__WP_DEBUG__/false/g /var/www/html/wp-config.php
sed -i s/__SCRIPT_DEBUG__/false/g /var/www/html/wp-config.php
fi
wp option update home "${SITE_URL}" --allow-root
wp option update siteurl "${SITE_URL}" --allow-root
### set WP_DEBUG_LOG to php://stdout to always output logs to stdout so be available for docker logs
old_string='__WP_DEBUG_LOG__'
new_string='php://stdout'
sed -i "s%$old_string%$new_string%g" /var/www/html/wp-config.php
if [[ -n "${SITE_ADMIN_USERNAME}" ]]; then
DASHBOARD_USER_NAME="${SITE_ADMIN_USERNAME}"
else
DASHBOARD_USER_NAME="admin"
fi
if [[ -n "${UID}" ]]; then
usermod -u "${UID}" www-data
groupmod -g "${GID}" www-data
fi
chown -R www-data:www-data /var/www/html/
### install wordpress
printf "\033[0;32m > Checking if wordpress core installed,if not Installing it ...\x1b[0m \n"
wp core is-installed --allow-root
retVal=$?
if [ "$retVal" == "1" ];then
printf "\033[0;32m > Trying to Install wordpress ...\x1b[0m \n"
printf "\033[0;32m > Command to execute is : wp core install --url="${SITE_URL}" --title="${SITE_TITLE}" --admin_user="${DASHBOARD_USER_NAME}" --admin_password="${SITE_ADMIN_PASSWORD}" --admin_email="${SITE_ADMIN_EMAIL}" --allow-root ...\x1b[0m \n"
wp core install --url="${SITE_URL}" --title="${SITE_TITLE}" --admin_user="${DASHBOARD_USER_NAME}" --admin_password="${SITE_ADMIN_PASSWORD}" --admin_email="${SITE_ADMIN_EMAIL}" --allow-root
fi
echo '---------------------------------------------'
### install The7 theme from zip file
# shellcheck disable=SC2059
printf "\033[0;32m > Checking if theme: $FILE installed,if not Installing it ...\x1b[0m \n"
wp theme is-installed The7 --allow-root
is_theme_installed=$?
if [[ is_theme_installed -eq 1 || ! -d /var/www/html/wp-content/themes/dt-the7 ]]; then
rm -rf /var/www/html/wp-content/themes/dt-the7
wp theme install /docker/themes/dt-the7.zip --force --allow-root;
fi
echo '---------------------------------------------'
### install plugins from plugins_dev.txt or plugins_prod.txt based on environment
# shellcheck disable=SC2162
while read line; do
IFS='=' read -r -a array <<< "$line"
printf "\033[0;32m > Checking if plugin:%s is installed else Installing %s:%s ...\x1b[0m \n" "${array[0]}" "${array[0]}" "${array[1]}"
# if wp plugin is-installed "${array[0]}" --allow-root; then
wp plugin install "${array[0]}" --version="${array[1]}" --activate --force --allow-root
# fi
echo '---------------------------------------------'
done < /docker/plugins/plugins_"${ENV}".txt
### install plugins from zip file
for FILE in /docker/plugins/*.zip;
do
# shellcheck disable=SC2059
printf "\033[0;32m > Installing plugin $FILE ...\x1b[0m \n"
wp plugin install "$FILE" --force --allow-root;
echo '---------------------------------------------'
done
printf "\033[0;32m > Checking if hello plugin exist and if so uninstall it ...\x1b[0m \n"
#if ! wp plugin is-installed hello --allow-root; then
wp plugin uninstall hello --allow-root
#fi
echo '---------------------------------------------'
printf "\033[0;32m > Checking if akismet plugin exist and if so uninstall it ...\x1b[0m \n"
#if ! wp plugin is-installed akismet --allow-root; then
wp plugin uninstall akismet --allow-root
#fi
echo '---------------------------------------------'
printf "\033[0;32m > activating the7 child theme ...\x1b[0m \n"
wp theme activate dt-the7-child --allow-root
echo '---------------------------------------------'
printf "\033[0;32m > Uninstalling initial themes ...\x1b[0m \n"
#if ! wp theme is-installed twentynineteen --allow-root; then
wp theme delete twentynineteen --allow-root
#fi
echo '---------------------------------------------'
#if ! wp theme is-installed twentyseventeen --allow-root; then
wp theme delete twentyseventeen --allow-root
#fi
echo '---------------------------------------------'
#if ! wp theme is-installed twentytwenty --allow-root; then
wp theme delete twentytwenty --allow-root
#fi
echo '---------------------------------------------'
正如您在我的bash文件中看到的那样,我正在连接到mysql容器。 我该如何实现?
解决方法
您根本无法从Dockerfile连接到数据库。
其中一部分是图像工作方式的基本Docker模型。 Docker映像仅包含一个文件系统和一些元数据,这些元数据描述了如何从中启动容器。您可以将其复制到其他系统并在其中运行。如果您构建了映像并尝试更新数据库的一部分,然后在不同的系统上运行了相同的映像,则它将没有数据库设置。同样,您可以删除并重新创建本地数据库,而无需重建映像,并且您将没有任何数据库内容。
从机械上讲,docker build
步骤(或等效的Compose)在受限环境中运行。最值得注意的是,它未连接到任何Compose网络,因此没有网络设置可用于解析诸如mhndev_systems_mysql
之类的主机名。 (从技术上讲,它位于default bridge network上,与Compose default
网络或您为已构建容器指定的任何networks:
网络不同。)
在典型的应用程序中,您需要将“应用程序代码”与“数据库设置”分开。您必须在应用程序启动时运行数据库设置部分(通常是“迁移”),或者与启动应用程序分开运行;但是您不能在构建时这样做。
,在构建时间和运行时间之间存在一个简单的误解;所有容器将在运行时可用,而不是在构建时可用。因此,无法在构建时访问您的MySQL容器。 我的建议是,从Dockerfile中删除所有需要MySQL的步骤并将它们移至入口点,然后在Dockerfile中设置一个布尔ENV并在入口点的开头检查该值,如果您设置了该命令,它将运行您的命令ENV为true;现在,如果您需要运行入口点(也就是设置WP和MySQL),只需在构建时传递该ENV。
docker build --build-arg var_name=${VARIABLE_NAME}
,
我的猜测是您无法连接,因为数据库服务已启动但尚未准备就绪。在the docker documentation on depends_on中说明了这一点(我也遇到了这个问题):
depends_on 不等待,使db和redis在开始Web之前“就绪” -仅在它们启动之前。如果需要等待服务准备就绪,请参阅控制启动顺序以获取有关此问题的更多信息以及解决方案。
(重点是我的)
就我而言,我以非常难看的方式解决了它(在我的python脚本中有一个sleep()了10秒钟),但是如果这对您来说不是解决方案,那么官方策略文档found here可能会有所帮助
[编辑] 您将什么用作主机变量名称?在docker compose中使用网络时,机器应能够使用其容器名称(即您的 mhndev_systems_mysql )相互通信。你可以试试吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。