当前位置:首页 > 文章列表 > 文章 > php教程 > Docker部署Laravel项目详细教程

Docker部署Laravel项目详细教程

2025-07-20 16:30:39 0浏览 收藏

使用Docker部署Laravel项目是现代Web开发的流行选择,它通过容器化技术实现环境一致性,简化配置流程。本文将深入探讨如何利用Docker部署Laravel应用,包括创建Dockerfile定义PHP应用容器、配置Nginx转发请求、编写docker-compose.yml编排多服务(如app、web、db、redis),以及执行Docker命令构建和启动服务。此外,文章还将着重介绍生产环境的优化策略,如多阶段构建镜像、资源限制、日志管理、秘密管理和CI/CD集成。通过Docker,开发者可以有效解决“本地能跑”的问题,提升开发效率和部署质量。

部署Laravel项目用Docker的核心在于实现环境一致性并简化配置,具体通过以下步骤:1. 创建Dockerfile,定义PHP应用容器,基于php:8.2-fpm-alpine镜像,安装必要扩展与依赖,设置工作目录并暴露9000端口;2. 配置Nginx文件,转发请求至PHP-FPM容器,确保fastcgi_pass指向正确的服务名;3. 编写docker-compose.yml编排服务,包含app、web、db、redis等容器,设置依赖关系、数据卷、网络和环境变量;4. 执行docker-compose命令构建并启动服务,进入容器运行Laravel相关命令;5. 生产环境优化包括多阶段构建镜像、资源限制、日志策略、秘密管理、CI/CD集成、Laravel优化命令及监控警报配置。Docker解决了“本地能跑”的问题,提供环境一致性、快速上手、依赖隔离、可移植性和扩展基础。最佳实践包括服务分离、合理使用数据卷、清晰网络配置、环境变量管理及健康检查。生产环境部署需特别注意镜像优化、资源限制、日志集中管理、安全敏感信息处理,并集成自动化部署流程,确保应用稳定高效运行。

如何用Docker部署Laravel PHP项目 Laravel框架容器化运行配置

用Docker部署Laravel项目,核心在于将PHP应用、Web服务器(如Nginx)和数据库(如MySQL)各自封装在独立的容器中,并通过Docker Compose协调它们协同工作,实现开发与生产环境的一致性部署,极大简化了环境配置的复杂性。

如何用Docker部署Laravel PHP项目 Laravel框架容器化运行配置

解决方案

要用Docker部署一个Laravel PHP项目,我们通常会用到三个核心文件:Dockerfile(定义应用容器的构建方式)、Nginx配置文件(作为Web服务器),以及docker-compose.yml(编排所有服务)。

我通常会从创建一个Dockerfile开始,它就像是为我的Laravel应用定制的“家”。这个文件会指定基础镜像(比如php:8.2-fpm-alpine,我喜欢Alpine因为它小巧),安装必要的PHP扩展(pdo_mysql, bcmath, gd等),并把我的应用代码复制进去。说实话,最初我总会漏掉几个扩展,导致项目跑不起来,后来才学乖了,把所有依赖都列得清清楚楚。

如何用Docker部署Laravel PHP项目 Laravel框架容器化运行配置
# Dockerfile
FROM php:8.2-fpm-alpine

# 安装系统依赖和PHP扩展
RUN apk add --no-cache \
    nginx \
    mysql-client \
    git \
    supervisor \
    && docker-php-ext-install \
        pdo_mysql \
        bcmath \
        gd \
        exif \
        pcntl \
        sockets \
    && docker-php-ext-enable pdo_mysql bcmath gd exif pcntl sockets

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

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

# 复制应用代码
COPY . .

# 安装Composer依赖
RUN composer install --no-dev --optimize-autoloader --no-interaction

# 配置Laravel权限
RUN chown -R www-data:www-data storage bootstrap/cache \
    && chmod -R 775 storage bootstrap/cache

# 暴露PHP-FPM端口
EXPOSE 9000

# 启动PHP-FPM
CMD ["php-fpm"]

接着是Nginx的配置,它负责将外部请求转发给PHP-FPM容器。我通常会创建一个nginx.conf文件,放在项目的某个地方,比如docker/nginx/default.conf。这里面最关键的就是fastcgi_pass指向PHP-FPM服务。

# docker/nginx/default.conf
server {
    listen 80;
    server_name localhost;
    root /var/www/html/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.php index.html index.htm;

    charset utf-8;

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

    location ~ \.php$ {
        fastcgi_pass app:9000; # 'app' 是docker-compose.yml中PHP服务的名称
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }
}

最后,也是最关键的,是docker-compose.yml文件。它就像一个指挥家,协调所有的服务(应用、Nginx、数据库、Redis等)一起工作。

如何用Docker部署Laravel PHP项目 Laravel框架容器化运行配置
# docker-compose.yml
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: laravel_app
    restart: unless-stopped
    volumes:
      - .:/var/www/html
      - /var/www/html/vendor # 避免宿主机vendor目录权限问题,或者在Dockerfile中安装依赖
    networks:
      - laravel_network

  web:
    image: nginx:alpine
    container_name: laravel_web
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - .:/var/www/html
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app
    networks:
      - laravel_network

  db:
    image: mysql:8.0
    container_name: laravel_db
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_USER: ${DB_USERNAME}
      MYSQL_PASSWORD: ${DB_PASSWORD}
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - laravel_network
    ports:
      - "3306:3306" # 仅在开发环境暴露,生产环境不建议

  redis:
    image: redis:alpine
    container_name: laravel_redis
    restart: unless-stopped
    networks:
      - laravel_network

volumes:
  db_data:

networks:
  laravel_network:
    driver: bridge

有了这些文件,我通常会在项目根目录运行:

  1. docker-compose build (首次构建或有Dockerfile修改时)
  2. docker-compose up -d (启动所有服务,-d表示后台运行)

容器启动后,进入app容器执行Laravel命令: 3. docker-compose exec app composer install (如果Dockerfile中没有安装或需要重新安装) 4. docker-compose exec app php artisan key:generate 5. docker-compose exec app php artisan migrate

然后访问http://localhost,我的Laravel应用就应该跑起来了。这套流程走下来,效率真的提高不少。

为什么选择Docker部署Laravel?

我个人觉得,选择Docker部署Laravel,最直接的原因就是解决了那个经典的“在我机器上能跑”的问题。想想看,以前每次新项目启动,或者有新同事加入,光是配置PHP版本、Nginx、MySQL这些环境,就得耗费半天甚至一天时间,而且还总会遇到各种奇奇怪怪的版本冲突。我记得当初为了一个PHP扩展版本,折腾了整整一个下午,最后发现是系统库版本不对,那种无力感真是记忆犹新。

Docker的出现,就像是给每个项目都配了一个专属的、可复制的“运行环境盒子”。它把Laravel应用所需的一切(PHP、Nginx、数据库、Redis等)都打包在一起,无论在哪台机器上,只要有Docker,这个盒子就能原封不动地运行起来。这带来的好处是显而易见的:

  • 环境一致性: 开发、测试、生产环境高度统一,大大减少了部署时的意外情况。
  • 快速上手: 新成员加入团队,只需要拉取代码,运行几个Docker命令,就能立即投入开发,省去了繁琐的环境配置步骤。
  • 依赖隔离: 不同的项目可以使用不同版本的PHP或数据库,互不干扰。比如,一个老项目还在用PHP 7.4,新项目已经用上PHP 8.2,Docker能轻松应对。
  • 可移植性: 整个应用环境可以轻松地从一台机器迁移到另一台,甚至直接部署到云服务上。
  • 简化扩展: 虽然Docker Compose本身不是生产环境的伸缩方案,但它为后续基于Kubernetes等容器编排工具的扩展打下了坚实的基础。

对我而言,这种“开箱即用”的感觉,以及项目环境的确定性,是任何其他部署方式都难以比拟的。它让我能更专注于代码本身,而不是纠结于环境问题。

Docker Compose配置Laravel项目有哪些最佳实践?

在配置docker-compose.yml时,我积累了一些个人认为非常实用的“最佳实践”,它们能让你的Laravel项目在Docker环境中跑得更稳、更高效。

首先,服务分离是核心。不要试图把Nginx和PHP-FPM塞进同一个容器,那违背了容器“单一职责”的原则。每个服务(appwebdbredisqueue等)都应该有自己的独立容器。这样不仅便于管理和调试,也能让每个服务独立升级或扩展。比如,我的app容器就只负责运行PHP-FPM,web容器只跑Nginx,它们之间通过内部网络通信,互不干涉。

其次,合理使用数据卷(Volumes)。数据卷是实现数据持久化的关键。对于Laravel项目,我通常会挂载以下几个数据卷:

  • 代码卷: .:/var/www/html 将宿主机的项目代码同步到容器内。这在开发时非常方便,改了代码立即生效。
  • vendor目录卷(可选但推荐): - /var/www/html/vendor。这有点反直觉,因为我希望vendor目录在容器内由Composer管理。但实际操作中,如果不挂载它,宿主机上可能会因为权限问题无法删除或修改vendor目录下的文件。我的做法是,在Dockerfile里安装Composer依赖,然后在docker-compose.yml里明确挂载一个匿名卷到vendor目录,这样宿主机上的vendor目录就不会被影响,容器内的数据也独立。
  • 数据库数据卷: db_data:/var/lib/mysql。这是必须的,确保数据库数据在容器重启后不会丢失。
  • Laravel的storagebootstrap/cache 我倾向于直接在Dockerfile中设置这些目录的权限,而不是单独挂载数据卷。因为这些目录的内容是应用运行时生成的,如果挂载数据卷,可能会遇到宿主机和容器之间的权限同步问题。当然,如果需要持久化存储上传文件等,可以考虑为storage/app/public单独挂载数据卷。

再者,网络配置要清晰。Docker Compose默认会为所有服务创建一个桥接网络,让它们可以通过服务名互相通信。比如,我的Nginx容器可以通过app:9000访问PHP-FPM服务。这比用IP地址要方便得多,也更具弹性。

还有,环境变量的管理。Laravel应用依赖.env文件来配置数据库连接、缓存驱动等。在Docker Compose中,可以通过environment字段直接设置环境变量,或者使用env_file指定一个.env文件。我通常会选择后者,因为它与Laravel的习惯保持一致,也方便本地开发。但需要注意的是,敏感信息(如数据库密码)在生产环境中应该使用更安全的秘密管理方案,而不是直接放在.env文件里。

最后,健康检查(Healthchecks)。虽然在开发环境中不常用,但在生产环境中,为关键服务(如数据库)添加健康检查是非常有用的。它能让Docker知道服务是否真正“准备好了”,避免Nginx在数据库还没启动完成时就开始尝试连接,导致错误。

  db:
    # ...其他配置
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

这些实践,都是我在实际项目中摸索出来的,它们让Docker化的Laravel项目部署和维护变得更加顺畅。

Docker部署Laravel在生产环境中应注意哪些细节?

将Docker化的Laravel项目从开发环境推向生产环境,需要考虑的细节远比你想象的要多。在我看来,生产环境的部署不仅仅是让应用跑起来,更要关注其稳定性、性能、安全性和可维护性。

一个很重要的点是镜像优化。开发时我们可能不太在意镜像大小,但生产环境必须重视。我通常会采用多阶段构建(Multi-stage Builds)。这意味着我的Dockerfile会有多个FROM指令。第一个阶段用于构建应用(比如安装Composer依赖、编译前端资源),生成一个“构建产物”,第二个阶段则基于一个更轻量的基础镜像(比如php:8.2-fpm-alpine),只复制最终的构建产物和运行所需的依赖。这样,最终的生产镜像会小很多,启动更快,攻击面也更小。例如,我不会把Composer本身留在生产镜像里。

# Dockerfile (简化版,展示多阶段构建概念)
# Stage 1: Builder
FROM composer:latest as builder
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader

# Stage 2: Production
FROM php:8.2-fpm-alpine
WORKDIR /var/www/html
COPY --from=builder /app/vendor /var/www/html/vendor
COPY . .
# ...其他安装PHP扩展、权限设置等
CMD ["php-fpm"]

资源限制也是生产环境的重点。在docker-compose.yml中,你可以为每个服务设置CPU和内存限制(deploy.resources.limits),这能防止某个服务耗尽宿主机的资源,影响其他应用。虽然Docker Compose在生产环境通常会被Kubernetes等更专业的编排工具取代,但在小规模部署或过渡期,这些限制依然有用。

日志策略必须明确。容器内的日志默认会输出到标准输出(stdout)和标准错误(stderr),Docker会捕获这些日志。这意味着你不需要在容器内配置复杂的日志文件。这很好,因为你可以利用Docker的日志驱动(如json-filesyslogfluentd等)将日志集中收集到外部日志管理系统(如ELK Stack、Grafana Loki)。确保Laravel的日志配置(config/logging.php)是stackstderr驱动,而不是写入文件。

秘密管理(Secrets Management)至关重要。数据库密码、API密钥等敏感信息绝不能直接写在docker-compose.ymlDockerfile中。Docker Swarm和Kubernetes都有自己的秘密管理机制。如果只是用Docker Compose,可以考虑使用环境变量,但更安全的方式是使用外部工具,如HashiCorp Vault,或者在CI/CD流程中注入。

CI/CD集成是自动化部署的关键。每次代码提交后,应该触发CI/CD流水线,自动构建Docker镜像,运行测试,然后部署到生产环境。这大大减少了人工操作的错误,提高了部署效率和可靠性。我个人非常喜欢这种自动化流程,它让我能更专注于开发,而不是部署的繁琐。

别忘了Laravel自身的优化命令。在生产环境中,务必运行这些命令来提升性能:

  • php artisan config:cache:缓存配置信息,减少每次请求时的文件读取。
  • php artisan route:cache:缓存路由信息,加速路由匹配。
  • php artisan view:cache:预编译Blade视图,减少运行时编译开销。
  • composer dump-autoload --optimize:优化Composer的自动加载器。

最后,监控和警报是不可或缺的。你需要实时了解应用和容器的运行状况,包括CPU、内存使用率、网络流量、错误日志等。Prometheus和Grafana是常见的组合,它们能帮助你及时发现问题并进行处理。同时,数据库备份策略也必须到位,这是任何生产应用最基本的保障。

这些细节,虽然看似繁琐,但却是确保Docker化Laravel应用在生产环境中稳定、高效运行的基石。忽视它们,迟早会遇到麻烦。

以上就是《Docker部署Laravel项目详细教程》的详细内容,更多关于docker,Laravel,容器化,Dockerfile,docker-compose.yml的资料请关注golang学习网公众号!

ZIP压缩怎么用?文件打包解压教程ZIP压缩怎么用?文件打包解压教程
上一篇
ZIP压缩怎么用?文件打包解压教程
Java函数式编程实战教程
下一篇
Java函数式编程实战教程
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    511次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    498次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • 扣子空间(Coze Space):字节跳动通用AI Agent平台深度解析与应用
    扣子-Space(扣子空间)
    深入了解字节跳动推出的通用型AI Agent平台——扣子空间(Coze Space)。探索其双模式协作、强大的任务自动化、丰富的插件集成及豆包1.5模型技术支撑,覆盖办公、学习、生活等多元应用场景,提升您的AI协作效率。
    11次使用
  • 蛙蛙写作:AI智能写作助手,提升创作效率与质量
    蛙蛙写作
    蛙蛙写作是一款国内领先的AI写作助手,专为内容创作者设计,提供续写、润色、扩写、改写等服务,覆盖小说创作、学术教育、自媒体营销、办公文档等多种场景。
    12次使用
  • AI代码助手:Amazon CodeWhisperer,高效安全的代码生成工具
    CodeWhisperer
    Amazon CodeWhisperer,一款AI代码生成工具,助您高效编写代码。支持多种语言和IDE,提供智能代码建议、安全扫描,加速开发流程。
    30次使用
  • 畅图AI:AI原生智能图表工具 | 零门槛生成与高效团队协作
    畅图AI
    探索畅图AI:领先的AI原生图表工具,告别绘图门槛。AI智能生成思维导图、流程图等多种图表,支持多模态解析、智能转换与高效团队协作。免费试用,提升效率!
    54次使用
  • TextIn智能文字识别:高效文档处理,助力企业数字化转型
    TextIn智能文字识别平台
    TextIn智能文字识别平台,提供OCR、文档解析及NLP技术,实现文档采集、分类、信息抽取及智能审核全流程自动化。降低90%人工审核成本,提升企业效率。
    65次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码