PHP项目容器化与Docker Compose编排完整指南
📖 目录导读
-
为什么PHP项目需要容器化?

-
容器化前的环境准备与项目结构
-
手写Dockerfile:打造PHP+Apache/Nginx镜像
-
数据库与缓存服务的容器化
-
Docker Compose编排:一键启动所有服务
-
数据持久化与网络配置
-
常见问题与性能优化建议
-
FAQ问答专区
为什么PHP项目需要容器化?
传统PHP开发常面临“在我机器上能跑”的窘境,容器化通过将应用与依赖环境封装,实现“构建一次,到处运行”,使用Docker可以让PHP项目在开发、测试、生产环境保持高度一致,并轻松扩展服务集群。
容器化前的环境准备与项目结构
前提条件:
- 安装Docker(20.10+)与Docker Compose (V2)
- PHP项目代码(例如Laravel或WordPress)
- Git初始化(方便版本控制)
推荐项目目录结构:
my-php-app/
├── docker/
│ ├── php/
│ │ └── Dockerfile
│ └── nginx/
│ ├── default.conf
│ └── Dockerfile
├── src/ # PHP代码存放位置
├── docker-compose.yml
└── .env
手写Dockerfile:打造PHP+Apache/Nginx镜像
1 基础PHP镜像选择
官方提供了多种PHP镜像,推荐使用 php:8.2-fpm 或 php:8.2-apache,若需要更多扩展,建议基于官方镜像自定义。
示例:基于PHP-FPM的Dockerfile
FROM php:8.2-fpm
# 安装必要扩展
RUN apt-get update && apt-get install -y \
libpq-dev \
libzip-dev \
unzip \
&& docker-php-ext-install pdo pdo_mysql zip
# 安装Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
COPY src/ /var/www/html/
# 设置权限
RUN chown -R www-data:www-data /var/www/html
USER www-data
2 Nginx反向代理配置
对于高性能场景,推荐使用Nginx+PHP-FPM组合。
nginx/default.conf:
server {
listen 80;
index index.php index.html;
root /var/www/html/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
数据库与缓存服务的容器化
PHP项目通常依赖MySQL/PostgreSQL和Redis,直接在docker-compose中定义服务即可,无需单独编写Dockerfile:
services:
mysql:
image: mysql:8.0
environment:
MYSQL_DATABASE: myapp
MYSQL_USER: user
MYSQL_PASSWORD: secret
MYSQL_ROOT_PASSWORD: rootpass
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:7-alpine
Docker Compose编排:一键启动所有服务
完整的 docker-compose.yml 示例(基于Laravel):
version: '3.8'
services:
app:
build:
context: ./
dockerfile: docker/php/Dockerfile
container_name: php-app
volumes:
- ./src:/var/www/html
networks:
- app-network
environment:
- DB_HOST=mysql
- REDIS_HOST=redis
webserver:
image: nginx:alpine
container_name: nginx-server
ports:
- "8080:80"
volumes:
- ./src:/var/www/html
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
networks:
- app-network
mysql:
image: mysql:8.0
container_name: mysql-db
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
volumes:
- db_data:/var/lib/mysql
networks:
- app-network
redis:
image: redis:alpine
container_name: redis-cache
networks:
- app-network
volumes:
db_data:
networks:
app-network:
driver: bridge
启动命令:docker compose up -d
查看日志:docker compose logs -f app
数据持久化与网络配置
1 数据卷(Volumes)
- 数据库文件通过命名卷
db_data持久化,避免容器删除后数据丢失。 - PHP代码通过绑定挂载
./src:/var/www/html实现热重载(开发环境)。
2 容器间通信
所有服务接入同一网络 app-network,PHP代码中可直接使用服务名称(如 mysql)作为数据库主机地址。
常见问题与性能优化建议
| 问题 | 解决方案 |
|---|---|
| PHP扩展缺失 | 在Dockerfile使用 docker-php-ext-install |
| 权限错误(Permission denied) | 确保 www-data 用户拥有文件读写权限 |
| 容器启动缓慢 | 使用 docker compose build --no-cache 重建 |
| 性能瓶颈 | 增加PHP-FPM的pm.max_children参数,或启用OPcache |
生产环境优化:
- 使用多阶段构建减少镜像体积
- 配置健康检查(
healthcheck) - 结合CI/CD自动推送到私有仓库
FAQ问答专区
问:容器化后如何开发调试?
答:使用docker compose exec app bash进入容器,或IDE中配置远程PHP解释器指向容器内的PHP-FPM,Xdebug也支持容器化调试。
问:如何管理不同的环境配置(开发/测试/生产)?
答:通过.env文件注入变量,并在docker-compose.yml中使用${VARIABLE}引用,例如数据库密码、缓存驱动等。
问:现有PHP项目迁移容器化需要注意什么?
答:检查代码中是否硬编码了绝对路径或IP地址;确认文件上传(如move_uploaded_file)目录已挂载为数据卷;确保php.ini中upload_max_filesize等参数符合需求。
问:容器编排与Kubernetes的关系是什么?
答:Docker Compose适用于单机多容器编排;Kubernetes(K8s)用于大规模生产集群,可将docker-compose.yml作为原型,再转换为K8s资源文件(使用kompose等工具)。
问:如何确保容器化后的PHP应用安全?
答:
- 定期更新基础镜像(
docker compose pull) - 不使用
root用户运行PHP进程 - 设置网络隔离(如内部服务不暴露端口)
- 启用Docker的
--security-opt限制容器能力
通过本文的步骤,你可以将任何一个PHP项目快速容器化,并使用Docker Compose实现服务的编排与统一管理,这种实践不仅提升了开发效率,也简化了部署与运维的复杂度。