如何用Docker部署PHP项目?

wen PHP项目 2

如何用Docker部署PHP项目:从零开始的容器化实战指南

目录导读

  • 为什么选择Docker部署PHP项目?
  • 环境准备与核心概念解析
  • 编写Dockerfile:构建PHP+Apache/Nginx镜像
  • 使用docker-compose编排多容器(PHP+MySQL+Redis)
  • 项目部署与数据持久化配置
  • 常见问题与解决方案(FAQ)
  • 性能优化与安全最佳实践

为什么选择Docker部署PHP项目?

在传统开发中,PHP项目常因环境差异导致“在我机器上能运行”的尴尬,Docker通过容器化技术,将PHP应用及其依赖(如扩展、Web服务器、数据库)打包成独立单元,确保开发、测试、生产环境一致,根据2025年Stack Overflow调查,超过67%的开发者已采用容器化部署,其中PHP项目占比显著增长。

如何用Docker部署PHP项目?

核心优势:

  • 环境隔离:不同项目使用不同PHP版本(如7.4、8.2)互不干扰
  • 快速迭代:修改代码后秒级重启容器,无需重装系统
  • 资源节约:相比虚拟机,容器共享宿主机内核,内存占用降低40%

适用场景: Laravel、Symfony、ThinkPHP等主流框架,以及WordPress、Drupal等内容管理系统。


环境准备与核心概念解析

你需要:

  • 已安装Docker Desktop(Windows/Mac)或Docker Engine(Linux)
  • 对PHP基本语法和命令行熟悉
  • 一个待部署的PHP项目(如简单的index.php输出phpinfo()

关键概念:

  • 镜像(Image):只读模板,如php:8.2-apache(含PHP和Apache)
  • 容器(Container):镜像的运行实例,可读写
  • 数据卷(Volume):持久化保存数据库文件和上传资源
  • Docker Compose:批量管理多个容器(PHP+MySQL+Nginx)

编写Dockerfile:构建PHP+Apache/Nginx镜像

以PHP + Apache为例,创建项目根目录下的Dockerfile

# 使用官方PHP 8.2 Apache镜像
FROM php:8.2-apache
# 安装常用PHP扩展
RUN docker-php-ext-install pdo_mysql mysqli
# 启用Apache重写(支持Laravel等框架)
RUN a2enmod rewrite
# 复制项目代码到容器默认目录
COPY . /var/www/html/
# 设置目录权限(生产环境注意安全)
RUN chown -R www-data:www-data /var/www/html

构建镜像:

docker build -t my-php-app .

运行容器:

docker run -d -p 8080:80 --name php-demo my-php-app

访问http://localhost:8080即可看到项目运行。

若需使用Nginx: 采用Nginx+PHP-FPM组合,需两个Dockerfile或直接使用官方镜像php:8.2-fpm


使用docker-compose编排多容器(PHP+MySQL+Redis)

实际项目通常需要数据库,创建docker-compose.yml

version: '3.8'
services:
  php:
    build: .
    ports:
      - "8080:80"
    volumes:
      - ./src:/var/www/html  # 代码热更新
    depends_on:
      - db
      - redis
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root123
      MYSQL_DATABASE: myapp
    volumes:
      - mysql_data:/var/lib/mysql
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
volumes:
  mysql_data:

启动所有服务:

docker-compose up -d

关键说明:

  • volumes挂载使本地代码修改即时生效(开发模式)
  • depends_on保证数据库先启动
  • 容器间可通过服务名互通(如PHP中连接MySQL用host=db

项目部署与数据持久化配置

生产环境差异:

  • 移除代码热挂载,改为镜像内打包
  • 使用环境变量管理数据库密码(而非硬编码)

优化版生产Dockerfile:

FROM php:8.2-apache
RUN docker-php-ext-install pdo_mysql opcache
COPY --chown=www-data:www-data . /var/www/html/
# 设置生产配置
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"

数据持久化技巧:

  • MySQL数据:使用命名卷(mysql_data),删除容器后数据保留
  • 上传文件:单独挂载volumes:- ./uploads:/var/www/html/uploads
  • 日志文件:使用docker logs或挂载日志目录

常见问题与解决方案(FAQ)

Q1:容器启动后访问报错“404 Not Found”? A:检查DocumentRoot设置,若使用Laravel,需配置Apache虚拟主机指向public目录,或在Dockerfile中添加:

ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf

Q2:PHP连接MySQL失败,提示“Host not allowed”? A:容器内MySQL需允许远程连接,在Compose文件中为MySQL添加:

environment:
  MYSQL_ROOT_HOST: '%'  # 允许所有主机

或指定PHP容器IP(生产更安全)。

Q3:如何修改PHP配置(如上传文件大小)? A:在Dockerfile或Compose中自定义php.ini

php:
  volumes:
    - ./php.ini:/usr/local/etc/php/php.ini

其中php.ini包含upload_max_filesize = 20M

Q4:容器重启后数据丢失? A:确保数据库使用了卷(volume)而非临时存储,检查docker-compose.yml中是否有 volumes: - mysql_data:/var/lib/mysql


性能优化与安全最佳实践

优化建议:

  • 使用PHP 8.2+的OPcache扩展,提升代码执行速度(已在生产Dockerfile中启用)
  • 使用Alpine基础镜像缩小体积(如php:8.2-fpm-alpine
  • 生产环境结合Nginx反向代理+PHP-FPM,比Apache资源占用低30%

安全措施:

  • 不要以root用户运行容器(使用www-data
  • 敏感信息(如DB密码)使用docker secrets或.env文件
  • 定期扫描镜像漏洞:docker scan my-php-app
  • 限制容器网络:仅暴露必要端口

扩展阅读: 若需部署ThinkPHP框架,需开启URL重写;WordPress可配合官方镜像wordpress:php8.2-apache快速搭建。


通过以上步骤,你可以实现从本地开发到生产环境的无缝迁移,Docker不仅解决了环境一致性问题,更让团队协作、自动部署(CI/CD)变得简单,当遇到新问题时,记住核心思路:将PHP应用视为无状态容器,所有持久化数据交给卷,所有配置交给环境变量。

抱歉,评论功能暂时关闭!