Docker部署Laravel多租户应用遭遇502 Bad Gateway错误求助
排查Docker环境下Laravel多租户应用的502 Bad Gateway错误
问题背景
配置了包含PHP、Nginx、MySQL和Redis的Docker环境用于运行Laravel多租户应用,但执行docker-compose up时出现502 Bad Gateway错误,相关配置详情如下:
PHP服务Dockerfile
# Use the official PHP image as the base image with PHP 8.2 FROM php:8.2-fpm # Set the working directory in the container WORKDIR /var/www/html # Copy composer.lock and composer.json to install dependencies COPY composer.lock composer.json /var/www/html/ # Install Composer (PHP dependency manager) RUN apt-get update && apt-get install -y \ git \ zip \ unzip \ libfreetype6-dev \ libjpeg62-turbo-dev \ libpng-dev \ zlib1g-dev \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) gd \ && docker-php-ext-install pdo_mysql \ && pecl install redis \ && docker-php-ext-enable redis \ && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer # Copy the Laravel application files to the working directory in the container COPY . /var/www/html # Install dependencies RUN composer install # Expose port 9000 and start php-fpm server EXPOSE 9001 CMD ["php-fpm"]
Docker Compose文件(docker-compose.yml)
version: '3' services: nginx: container_name: nginx_container image: nginx:latest ports: - "80:80" volumes: - ./nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - php networks: - app-network php: container_name: php_container build: context: . dockerfile: Dockerfile volumes: - .:/var/www/html ports: - "9001:9000" depends_on: - mysql - redis networks: - app-network mysql: container_name: mysql_container image: mysql:5.7 platform: linux/amd64 restart: always environment: MYSQL_DATABASE: zmenu MYSQL_USER: user MYSQL_PASSWORD: password MYSQL_ROOT_PASSWORD: root_password volumes: - mysql_data:/var/lib/mysql networks: - app-network redis: container_name: redis_container image: redis:latest ports: - "6379:6379" networks: - app-network networks: app-network: driver: bridge external: true volumes: mysql_data:
Nginx配置(nginx/default.conf)
server { listen 80 default_server; server_name ~^(?<subdomain>.+)\.zmenu\.test$; location / { proxy_pass http://php:9001; proxy_set_header Host $subdomain.zmenu.test; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
排查与解决建议
1. 修正Nginx与PHP-FPM的通信逻辑
PHP-FPM使用FastCGI协议而非HTTP协议,当前Nginx配置用proxy_pass是错误的,需改为fastcgi_pass,同时容器间通信使用PHP容器内部的9000端口(而非主机映射的9001),还要添加Laravel必要的路由转发规则:
修正后的nginx/default.conf:
server { listen 80 default_server; server_name ~^(?<subdomain>.+)\.zmenu\.test$; # 指定Laravel的public目录为根目录 root /var/www/html/public; index index.php index.html index.htm; # 处理静态文件与Laravel路由 location / { try_files $uri $uri/ /index.php?$query_string; } # 处理PHP请求 location ~ \.php$ { fastcgi_pass php:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; # 传递子域名信息给Laravel fastcgi_param HTTP_HOST $subdomain.zmenu.test; } }
2. 修正PHP容器的端口暴露配置
PHP-FPM默认在容器内部监听9000端口,Dockerfile中EXPOSE 9001是错误的,需改为暴露内部实际运行的端口:
修改Dockerfile末尾:
# Expose port 9000 and start php-fpm server EXPOSE 9000 CMD ["php-fpm"]
3. 检查PHP容器的运行状态与权限
- 查看PHP容器日志,确认PHP-FPM是否正常启动:
docker logs php_container - 确保Laravel的
storage和bootstrap/cache目录权限正确,在Dockerfile中添加权限配置:# 添加到composer install之后 RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache RUN chmod -R 775 /var/www/html/storage /var/www/html/bootstrap/cache
4. 验证Docker网络连通性
- 检查外部网络
app-network是否存在:
如果不存在,先创建网络:docker network lsdocker network create app-network - 进入Nginx容器测试与PHP容器的连通性:
若无法连通,检查compose文件中所有服务的docker exec -it nginx_container ping phpnetworks配置是否统一为app-network。
5. 确认Laravel环境配置
在项目根目录的.env文件中配置正确的数据库和Redis连接信息(使用容器名称作为主机名):
APP_URL=http://your-subdomain.zmenu.test DB_CONNECTION=mysql DB_HOST=mysql DB_PORT=3306 DB_DATABASE=zmenu DB_USERNAME=user DB_PASSWORD=password REDIS_HOST=redis REDIS_PORT=6379
内容的提问来源于stack exchange,提问作者rabih mh
相关产品推荐
相关产品推荐

