0

Docker Compose部署Laravel完整教程:docker-compose编排Nginx+MySQL+PHP8生产环境实战

2026.05.21 | youres | 9次围观

说到部署Laravel项目,很多人第一反应还是老老实实在服务器上手工装PHP、装Nginx、装MySQL,然后各种配置文件写半天。环境稍有问题,排查起来更是头疼。

其实这套流程可以完全简化——用Docker Compose,一套docker-compose.yml文件,把Nginx、PHP、MySQL、Redis全部定义进去,一个docker-compose up -d就能把整套生产环境跑起来。今天就手把手讲清楚这个流程。

一、为什么推荐用Docker Compose部署Laravel

先说几个实际好处:

  • 环境一致:本地什么环境,生产就什么环境,不存在"本地能跑服务器挂了"的经典问题。
  • 部署快:一个新服务器,Docker装好,文件拷进去,两分钟上线。
  • 迁移方便:整个项目目录拷贝到新机器,docker-compose up就能跑,数据还能通过volumes持久化。
  • 版本隔离:不同项目PHP版本不同?互不干扰,各自独立容器。

我自己维护博客也是用的Docker方案,实战下来确实稳定省心。

二、整体架构规划

Laravel的标准Web架构通常需要这几个组件:

  • nginx:Web服务器,处理HTTP请求,充当反向代理
  • php:PHP-FPM容器,运行Laravel应用代码
  • mysql:数据库
  • redis:缓存和Session存储(可选但推荐)

四者通过Docker内部网络互通,对外只暴露nginx的80和443端口。

三、目录结构

先规划好项目目录,这是很多新手忽略但非常重要的一步:

laravel-docker/
├── docker/
│   ├── nginx/
│   │   └── default.conf
│   └── php/
│       └── Dockerfile
├── src/                  # Laravel项目代码放这里
├── .env                  # 环境变量
├── docker-compose.yml
└── init.sql              # 数据库初始化脚本(可选)

关键点:Laravel代码放在宿主机src目录,通过volumes挂载到PHP容器内,而不是打包进镜像。这样代码更新不需要重新构建镜像。

四、编写docker-compose.yml

version: '3.8'

services:
  nginx:
    image: nginx:alpine
    container_name: laravel_nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./src:/var/www/html
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php
    networks:
      - laravel_net

  php:
    build:
      context: ./docker/php
      dockerfile: Dockerfile
    container_name: laravel_php
    volumes:
      - ./src:/var/www/html
      - ./storage:/var/www/html/storage:delegated
    environment:
      - DB_HOST=mysql
      - DB_PORT=3306
      - DB_DATABASE=laravel
      - DB_USERNAME=laravel_user
      - DB_PASSWORD=your_secure_password
      - REDIS_HOST=redis
      - REDIS_PORT=6379
    depends_on:
      - mysql
      - redis
    networks:
      - laravel_net

  mysql:
    image: mysql:8.0
    container_name: laravel_mysql
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_USER: laravel_user
      MYSQL_PASSWORD: your_secure_password
      MYSQL_ROOT_PASSWORD: root_secure_password
    volumes:
      - mysql_data:/var/lib/mysql
    ports:
      - "3306:3306"
    networks:
      - laravel_net

  redis:
    image: redis:alpine
    container_name: laravel_redis
    networks:
      - laravel_net

networks:
  laravel_net:
    driver: bridge

volumes:
  mysql_data:

几点说明:

  • PHP用自定义Dockerfile构建,方便安装扩展和配置。
  • MySQL数据用volumes持久化,容器删除不会丢数据。
  • Redis使用alpine镜像,体积小资源占用低。
  • 所有容器加入同一网络,彼此通过服务名互相访问。

五、PHP Dockerfile配置

FROM php:8.2-fpm-alpine

# 安装系统依赖和PHP扩展
RUN apk add --no-cache \
    nginx \
    supervisor \
    bash \
    oniguruma-dev \
    libzip-dev \
    && docker-php-ext-install \
        pdo \
        pdo_mysql \
        mbstring \
        zip \
        exif \
        pcntl \
        bcmath \
    && pecl install redis \
    && docker-php-ext-enable redis

# 安装Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# 配置Nginx
COPY nginx.conf /etc/nginx/http.d/default.conf

# 配置Supervisor(守护PHP-FPM)
COPY supervisord.conf /etc/supervisord.conf

# 工作目录
WORKDIR /var/www/html

EXPOSE 9000

CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]

对应的nginx.conf:

server {
    listen 9000;
    root /var/www/html/public;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Supervisor配置文件确保PHP-FPM进程稳定运行:

[supervisord]
nodaemon=true

[program:php-fpm]
command=php-fpm -F
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

六、Nginx配置

server {
    listen 80;
    server_name localhost;
    root /var/www/html/public;
    index index.php index.html;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_buffer_size 32k;
        fastcgi_buffers 4 32k;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }

    access_log /var/log/nginx/laravel_access.log;
    error_log /var/log/nginx/laravel_error.log;
}

七、Laravel .env文件配置

APP_NAME=LaravelApp
APP_ENV=production
APP_KEY=base64:your_generated_app_key_here
APP_DEBUG=false
APP_URL=https://yourdomain.com

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel_user
DB_PASSWORD=your_secure_password

BROADCAST_DRIVER=redis
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis
SESSION_LIFETIME=120

REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379

生成APP_KEY的方法:进入容器执行php artisan key:generate,或者用在线工具生成后填入。

八、部署步骤

整个部署流程如下:

# 1. 准备好Laravel项目代码,放入src目录
# 确保src目录下有完整的Laravel项目(含vendor目录,或稍后容器内composer install)

# 2. 修改文件权限(Laravel storage目录需要写权限)
chmod -R 775 src/storage src/bootstrap/cache

# 3. 构建并启动所有容器
docker-compose up -d --build

# 4. 进入PHP容器,执行初始化
docker exec -it laravel_php bash

# 容器内执行:
composer install --no-dev --optimize-autoloader
php artisan key:generate
php artisan migrate --force
php artisan config:cache
php artisan route:cache

exit

# 5. 验证
curl http://localhost

如果能看到Laravel默认页面,说明部署成功。

九、常用运维命令

# 查看容器状态
docker-compose ps

# 查看日志
docker-compose logs -f

# 重启某个服务
docker-compose restart php

# 进入容器
docker exec -it laravel_php bash

# 重新构建(代码更新后)
docker-compose up -d --build

# 停止所有容器
docker-compose down

十、常见问题排查

502 Bad Gateway
大概率是PHP-FPM没起来或者Nginx连接PHP配置错误。先docker-compose logs nginx看日志,确认php容器状态正常。

数据库连接失败
检查.env里DB_HOST是否写的是mysql(服务名),不是localhost。确认MySQL容器已完全启动(初次启动MySQL需要10-30秒初始化)。

权限错误
storage和bootstrap/cache目录777权限不够,用775并确保属主正确:chown -R 1000:1000 src/storage src/bootstrap/cache

502 on file upload
Nginx默认client_max_body_size是1M,大文件上传需要调整nginx配置。

总结

用Docker Compose部署Laravel,核心就三件事:docker-compose.yml定义服务、Dockerfile构建PHP镜像、Nginx配置文件路由规则。把这三块搞定,后续新项目直接复制改配置就行。

相比传统部署方式,Docker方案的环境一致性、稳定性和迁移便捷性都强很多。刚开始会多花点时间搭框架,但长期维护成本大幅降低。


相关推荐:

版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论
883文章数 0评论数
作者其它文章