GitHub Action中Docker容器退出,exec命令报错及挂载配置求助
解决GitHub Action中Docker容器退出与挂载配置问题
问题概述
本地通过Docker Desktop的文件共享(路径:docker desktop > settings > resources > file sharing)实现了应用路径挂载,但在GitHub Action中配置相同挂载后,oe-web容器启动后立即退出(状态码Exit 255),导致后续执行docker exec命令时提示容器未运行,工作流失败。
现有配置
docker-compose.yml 配置
web: container_name: oe-web build: context: ./ dockerfile: Dockerfile depends_on: - db ports: - 8000:8000 working_dir: /app volumes: - ./:/app
GitHub Action 工作流配置
name: Docker Image CI on: push: branches: [ master ] pull_request: branches: [ master ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Run docker-compose run: docker-compose up -d - name: Sleep for 20s uses: juliangruber/sleep-action@v1 with: time: 10s - name: database migration with docker run: docker exec oe-web php artisan migrate - name: database seed with docker run: docker exec oe-web php artisan db:seed
错误详情
工作流执行时的核心错误:
Run docker exec oe-web php artisan migrate Error response from daemon: Container 27479cda84fb7f7c393bceeedbb2e2cf5ecd086917390728ac635748ac4411df is not running Error: Process completed with exit code 1.
更新后的容器状态显示oe-web已退出:
Name Command State Ports ------------------------------------------------------------------------------------------------- oe-adminer entrypoint.sh php -S [::]: ... Up 0.0.0.0:8080->8080/tcp,:::8080->8080/tcp oe-db docker-entrypoint.sh --def ... Up 3306/tcp, 33060/tcp oe-web docker-php-entrypoint /bin ... Exit 255
解决方案建议
1. 先排查容器退出的具体原因
在GitHub Action中添加步骤,获取oe-web容器的日志,明确Exit 255的触发原因:
docker-compose logs oe-web
Exit 255通常和权限不足、启动命令执行失败有关,结合挂载目录的场景,大概率是容器内进程无法读写挂载的/app目录。
2. 修复挂载目录的权限问题
GitHub Action运行在Ubuntu环境,仓库文件的权限与容器内运行用户不匹配是常见问题,可通过以下方式解决:
- 在Dockerfile中配置权限:指定容器内运行用户,并确保其拥有
/app目录的读写权限
# 以www-data用户为例,可根据实际镜像调整 RUN mkdir -p /app && chown -R www-data:www-data /app USER www-data
- 在GitHub Action中调整本地目录权限:提前将代码目录的权限切换为容器内用户的UID/GID
# 33是www-data用户的默认UID/GID,需和Dockerfile中的用户对应 sudo chown -R 33:33 ./
- 挂载时显式指定权限:在docker-compose的volumes配置中添加读写权限声明
volumes: - ./:/app:rw
3. 优化容器启动的依赖检查
depends_on仅保证容器启动顺序,无法确保数据库服务就绪。添加健康检查,让web容器等待db服务完全就绪后再启动:
# 在docker-compose的db服务中添加健康检查 db: # 原有配置 healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"] timeout: 20s retries: 10 interval: 5s # 修改web服务的depends_on配置 web: # 原有配置 depends_on: db: condition: service_healthy
4. 替换docker exec为docker-compose exec
使用docker-compose exec更适配compose环境,无需依赖容器名,同时添加-T参数避免终端交互问题:
docker-compose exec -T web php artisan migrate docker-compose exec -T web php artisan db:seed
5. 可选:放弃挂载,直接将代码打包进镜像
如果挂载目录的权限问题难以调试,可以在构建镜像时直接将代码复制到容器内,去掉volumes挂载配置:
# 在Dockerfile中添加代码复制步骤 COPY . /app
这种方式在CI环境中更稳定,避免了宿主机与容器的权限冲突。
内容的提问来源于stack exchange,提问作者dhanyn10
相关产品推荐
相关产品推荐

