Docker Compose容器达到彼此的构建时间

如何解决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 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-