You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker构建PHP容器阶段无法连接MySQL,如何实现构建时数据库连接?

解决Docker构建阶段无法连接MySQL的问题

你遇到的核心问题是Docker镜像构建阶段与Compose服务网络完全隔离——当Docker构建PHP镜像时,Compose中定义的MySQL服务还没启动,而且构建环境根本无法访问Compose创建的内部网络,所以PHP容器在构建时找不到mysql主机名,才会抛出getaddrinfo failed错误。

要在容器启动时自动完成Magento安装(而不是构建阶段),可以按以下步骤调整配置:

1. 修改Dockerfile,将安装逻辑移到启动脚本

把构建阶段的setup:install步骤移除,换成自定义启动脚本,让安装在容器启动时执行:

FROM php:7.2-fpm
RUN apt-get update && apt-get install -y \
  curl \
  wget \
  git \
  vim \
  libfreetype6-dev \
  libjpeg62-turbo-dev \
  libxslt-dev \
  libicu-dev \
  libmcrypt-dev \
  libpng-dev \
  libxml2-dev \
  netcat-traditional  # 新增:用于检测MySQL服务是否就绪

RUN docker-php-ext-install bcmath \
  gd \
  intl \
  soap \
  xsl \
  zip \
  pdo_mysql

WORKDIR /var/www/html
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer config -g http-basic.repo.magento.com -a 5310458a34d580de1700dfe826ff19a1 255059b03eb9d30604d5ef52fca7465d
RUN composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition .

# 复制自定义启动脚本并赋予执行权限
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh

ENTRYPOINT ["entrypoint.sh"]
CMD ["php-fpm"]

2. 创建启动脚本entrypoint.sh

这个脚本会先等待MySQL服务就绪,再检查Magento是否已安装,未安装则自动执行安装:

#!/bin/bash

# 等待MySQL服务完全就绪(避免连接时数据库还没初始化完成)
until nc -z mysql 3306; do
  echo "Waiting for MySQL to be ready..."
  sleep 2
done

# 检查Magento是否已安装(通过env.php文件判断)
if [ ! -f app/etc/env.php ]; then
  echo "Starting Magento installation..."
  php bin/magento setup:install \
    --base-url="http://localhost:8080/" \
    --db-host="mysql" \
    --db-name="magento" \
    --db-user="manager" \
    --db-password="1111" \
    --backend-frontname="admin" \
    --admin-firstname="admin" \
    --admin-lastname="admin" \
    --admin-email="admin@admin.com" \
    --admin-user="admin" \
    --admin-password="admin123" \
    --language="en_US" \
    --currency="USD" \
    --timezone="America/New_York" \
    --use-rewrites="1"

  # 可选:生成静态文件(第一次安装后需要执行)
  php bin/magento setup:static-content:deploy -f en_US
fi

# 执行容器原本的启动命令(保持php-fpm正常运行)
exec "$@"

3. 调整docker-compose.yml,添加依赖关系

确保PHP容器依赖MySQL服务,让Compose先启动MySQL再启动PHP:

version: '3.0'
services:
  nginx:
    image: nginx:1.15
    container_name: nginx
    ports:
      - 8080:80
    volumes:
      - ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php
  php:
    build: ./
    container_name: php
    depends_on:
      - mysql
    # 可选:挂载本地目录,方便开发时修改代码
    # volumes:
    #   - ./magento:/var/www/html
  mysql:
    image: mysql:5.7
    container_name: mysql
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: 1111
      MYSQL_DATABASE: magento
      MYSQL_USER: manager
      MYSQL_PASSWORD: 1111
    volumes:
      - ./mysql:/var/lib/mysql
  adminer:
    image: adminer
    restart: always
    ports:
      - 8000:8080
    depends_on:
      - mysql

为什么这个方案可行?

  • 构建与运行分离:构建阶段只准备PHP环境和Magento代码,运行阶段才执行数据库相关的初始化,此时Compose的服务网络已经创建,MySQL服务也已启动。
  • 避免重复执行:通过检查app/etc/env.php文件,确保只有第一次启动时才会执行安装,后续启动直接跳过。
  • 服务就绪检测:用nc等待MySQL端口开放,避免在数据库还没初始化完成时就执行安装命令。

内容的提问来源于stack exchange,提问作者Petro Chaikivskyi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:28:37