Docker-Compose启动时Entrypoint.sh中数据库迁移未执行问题
问题描述
我是Docker新手,正在将基于Symfony API和MySQL数据库的项目容器化。希望容器启动时自动执行数据库迁移命令php bin/console doctrine:migrations:migrate,于是添加了Entrypoint脚本:
entrypoint.sh
#create or update db php bin/console doctrine:migrations:migrate --no-interaction # start apache apache2-foreground
执行docker-compose up -d后,容器看似正常启动,但数据库未完成迁移。进入容器手动执行doc:mig:mig命令却能成功,请问如何实现自动执行?是不是我对Entrypoint的用法理解有误?
以下是我的配置文件:
docker-compose.yaml(敏感信息已替换)
version: '3.7' services: api: build: . ports: - 8000:80 links: - db volumes: - C:/Repos/myProjectName/src:/var/www/myProjectName_api/src db: image: 'mysql:8.0' container_name: mysql environment: MYSQL_USER: myUserName MYSQL_PASSWORD: myPwd MYSQL_ROOT_PASSWORD: myRootPwd MYSQL_DATABASE: dev_myProjectName volumes: - ./mysql:/var/lib/mysql command: ["--default-authentication-plugin=mysql_native_password"] ports: - "3307:3306"
Dockerfile
FROM php:8.1-apache RUN a2enmod rewrite RUN apt-get update \ && apt-get install -y libzip-dev git wget nano --no-install-recommends \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* RUN docker-php-ext-install pdo RUN docker-php-ext-install pdo_mysql RUN docker-php-ext-install zip RUN wget https://getcomposer.org/download/2.4.2/composer.phar \ && mv composer.phar /usr/bin/composer && chmod +x /usr/bin/composer COPY docker/apache.conf /etc/apache2/sites-enabled/000-default.conf COPY . /var/www/myProjectName_api RUN chown -R www-data:www-data /var/www/myProjectName_api/var # Allow Authorization header RUN echo 'SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1' >> /etc/apache2/apache2.conf COPY environments/.env.dev /var/www/myProjectName_api/.env.local WORKDIR /var/www/myProjectName_api COPY docker/entrypoint.sh /tmp RUN chmod +x /tmp/entrypoint.sh ENTRYPOINT /tmp/entrypoint.sh
解决方案
你的问题核心是API容器启动时,MySQL容器还没完全就绪,导致迁移命令执行失败;另外Entrypoint的写法也有可优化的地方。
1. 添加数据库就绪等待逻辑
Docker的links或depends_on仅保证容器启动顺序,不会等待数据库服务完全可用。需要在entrypoint脚本里添加等待数据库就绪的判断:
修改entrypoint.sh:
#!/bin/bash # 等待MySQL数据库就绪 wait_for_db() { until php bin/console doctrine:query:sql "SELECT 1" > /dev/null 2>&1; do echo "等待MySQL数据库就绪..." sleep 2 done echo "数据库已就绪,开始执行迁移..." } wait_for_db # 执行数据库迁移 php bin/console doctrine:migrations:migrate --no-interaction # 用exec启动apache,让它成为容器PID 1进程(保证信号正确传递) exec apache2-foreground
2. 优化Entrypoint脚本规范
- 脚本开头添加
#!/bin/bash,明确指定shell解释器,避免环境兼容问题 - 最后启动apache时使用
exec,让apache取代entrypoint脚本成为容器主进程,确保容器能正确响应docker stop等停止信号
3. 完善docker-compose配置
将links: - db替换为depends_on: - db,这是Docker Compose推荐的服务依赖写法:
services: api: build: . ports: - 8000:80 depends_on: - db volumes: - C:/Repos/myProjectName/src:/var/www/myProjectName_api/src
4. 验证修改效果
- 重新构建镜像:
docker-compose build - 启动容器:
docker-compose up -d - 查看API容器日志:
docker-compose logs api,确认能看到"数据库已就绪,开始执行迁移..."的日志,以及迁移成功的输出
额外注意事项
- 当前Dockerfile未执行
composer install,如果项目依赖Composer包,需要添加RUN composer install --no-dev --optimize-autoloader命令 - 挂载的
src卷可能覆盖容器内文件,确保迁移文件已存在于容器内或挂载的卷中
内容的提问来源于stack exchange,提问作者Diplodoco
相关产品推荐
相关产品推荐

