配置GitHub Actions构建Laravel镜像至Docker Hub的问题排查
我正在开发一个基于以下技术栈的项目:
- Laravel 10
- Tailwind
- MySQL
希望实现自动化流程:每次向GitHub推送代码时,GitHub Actions自动运行测试、构建项目并将Docker镜像推送至Docker Hub,之后可以从Docker Hub拉取镜像运行项目。但在配置.yml文件和Dockerfile时遇到了问题。
当前配置文件
GitHub Actions配置(laravel.yml)
name: Laravel CI on: push: branches: - main pull_request: branches: - main jobs: laravel-tests: runs-on: ubuntu-latest services: mysql: image: mysql:5.7 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 env: MYSQL_DATABASE: laravel MYSQL_ROOT_PASSWORD: password ports: - 3306:3306 steps: - name: Checkout repository uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: '8.1' extensions: mbstring, pdo_mysql, bcmath ini-values: post_max_size=256M, max_execution_time=300 - name: Cache Composer dependencies uses: actions/cache@v2 with: path: vendor key: composer-${{ hashFiles('**/composer.lock') }} restore-keys: composer- - name: Install Composer dependencies run: composer install --prefer-dist --no-progress --no-suggest - name: Setup .env file run: | cp .env.example .env php artisan key:generate - name: Run database migrations run: php artisan migrate --force - name: Install Node.js dependencies run: | npm install npm run build - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push Docker image uses: docker/build-push-action@v6 with: context: . push: true tags: mydockerhubusername/myproject:latest
Dockerfile
FROM php:8.2-fpm RUN apt-get update && apt-get install -y \ build-essential \ libpng-dev \ libjpeg62-turbo-dev \ libfreetype6-dev \ locales \ zip \ jpegoptim optipng pngquant gifsicle \ vim \ unzip \ git \ curl \ libonig-dev \ libxml2-dev \ libzip-dev \ nodejs \ npm \ && docker-php-ext-install pdo pdo_mysql mbstring exif pcntl bcmath gd zip COPY --from=composer:2.6 /usr/bin/composer /usr/bin/composer WORKDIR /var/www/html COPY composer.json composer.lock ./ RUN composer install --no-dev --optimize-autoloader --no-scripts --prefer-dist COPY . . RUN mkdir -p storage bootstrap/cache RUN chmod -R 777 storage bootstrap/cache RUN npm install && npm run build EXPOSE 9000 CMD ["php-fpm"]
遇到的问题
- 有时构建成功,但部署后Laravel应用显示空白页面
- 有时会出现连接重置错误
- 不确定
Dockerfile或.yml的配置是否适用于Docker Hub的推送与拉取
一、Dockerfile 核心问题与修复
1. PHP版本不匹配
GitHub Actions使用PHP 8.1,但Dockerfile用PHP 8.2-fpm,版本不一致可能引发依赖或运行时异常。建议统一版本,比如都用PHP 8.1-fpm。
2. 缺少Laravel必需环境变量
镜像中未设置APP_KEY、DB_CONNECTION等关键环境变量,部署时如果没传入正确的.env,会导致应用启动失败,出现空白页面。
- 修复:在Dockerfile中添加默认环境变量(敏感变量如
APP_KEY建议启动容器时传入):
启动容器时通过ENV APP_ENV=production ENV DB_CONNECTION=mysqldocker run -e APP_KEY=your-key-here或挂载.env文件提供敏感配置。
3. 文件权限过于宽松
chmod -R 777 storage bootstrap/cache权限风险高,应改用PHP-FPM默认用户www-data设置权限:
RUN chown -R www-data:www-data storage bootstrap/cache RUN chmod -R 755 storage bootstrap/cache RUN chmod -R 775 storage/app/public # 若有文件上传需求
4. 未执行生产环境缓存命令
生产环境需要缓存配置、路由和视图来提升性能,避免加载异常,在Dockerfile中添加:
RUN php artisan config:cache RUN php artisan route:cache RUN php artisan view:cache
注意:执行前需确保APP_ENV=production。
5. PHP-FPM监听配置错误
默认PHP-FPM仅监听127.0.0.1:9000,容器外部无法访问,需修改为监听所有地址:
RUN sed -i 's/listen = 127.0.0.1:9000/listen = 0.0.0.0:9000/' /usr/local/etc/php-fpm.d/www.conf
6. 前端构建重复执行
GitHub Actions和Dockerfile中都执行了npm install && npm run build,浪费资源。改用多阶段构建优化:
# 第一阶段:构建前端资源 FROM node:20 as frontend WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build # 第二阶段:构建PHP镜像 FROM php:8.1-fpm # 安装依赖和扩展(省略重复部分) RUN apt-get update && apt-get install -y ... && docker-php-ext-install ... COPY --from=composer:2.6 /usr/bin/composer /usr/bin/composer WORKDIR /var/www/html COPY composer.json composer.lock ./ RUN composer install --no-dev --optimize-autoloader --no-scripts --prefer-dist # 复制代码和前端构建产物 COPY . . COPY --from=frontend /app/public/build ./public/build COPY --from=frontend /app/public/mix-manifest.json ./public/ # 设置权限、缓存命令等(省略重复部分)
二、GitHub Actions 配置优化
1. 缺失测试环节
当前仅执行了数据库迁移,未运行测试,无法保障代码质量,添加测试步骤:
- name: Run tests run: php artisan test
2. Docker镜像标签优化
仅打latest标签不利于版本追溯,添加基于提交哈希的标签:
tags: | mydockerhubusername/myproject:latest mydockerhubusername/myproject:${{ github.sha }}
3. 启用Docker构建缓存
添加缓存配置加速构建:
- name: Build and push Docker image uses: docker/build-push-action@v6 with: context: . push: true tags: | mydockerhubusername/myproject:latest mydockerhubusername/myproject:${{ github.sha }} cache-from: type=gha cache-to: type=gha,mode=max
三、部署与运行问题解决
1. 缺少反向代理
PHP-FPM不处理HTTP请求,需搭配Nginx反向代理。示例Docker Compose配置(docker-compose.yml):
version: '3.8' services: app: image: mydockerhubusername/myproject:latest environment: - APP_KEY=your-app-key-here - DB_HOST=db networks: - laravel-network webserver: image: nginx:alpine ports: - "80:80" volumes: - ./nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - app networks: - laravel-network db: image: mysql:5.7 environment: - MYSQL_DATABASE=laravel - MYSQL_ROOT_PASSWORD=password volumes: - db-data:/var/lib/mysql networks: - laravel-network volumes: db-data: networks: laravel-network: driver: bridge
对应的Nginx配置(nginx/default.conf)需正确转发PHP请求到app:9000。
2. 连接重置错误排查
- 检查PHP-FPM监听地址是否为
0.0.0.0:9000; - 确认Nginx配置中
fastcgi_pass指向正确的容器地址; - 确保容器在同一个Docker网络中;
- 查看容器日志:
docker logs <app-container-id>。
3. 空白页面排查
- 查看Laravel日志:
docker exec <app-container-id> cat storage/logs/laravel.log,日志会显示具体错误(如缺少APP_KEY、数据库连接失败); - 确认
APP_ENV=production时调试模式已关闭,错误详情不会直接显示在页面上; - 检查
public目录是否可访问,静态资源是否存在。
内容的提问来源于stack exchange,提问作者Papazy

