1. 为什么要在macOS上部署Docker+PHP+Nginx?
作为macOS开发者,我们经常需要搭建本地开发环境。传统方式是在本机直接安装PHP和Nginx,但这种方式存在环境污染、版本冲突等问题。Docker容器化方案完美解决了这些痛点,它允许我们在隔离的环境中运行服务,保持主机系统的纯净。
我最近在MacBook Pro(M1芯片)上完整走通了这套流程,实测M系列芯片和Intel芯片的Mac都能顺利运行。相比虚拟机方案,Docker的资源占用更低,启动速度更快,特别适合需要频繁切换不同PHP版本的开发场景。
2. 环境准备与Docker安装
2.1 系统要求检查
首先确认你的macOS版本:
bash复制sw_vers -productVersion
建议使用macOS Monterey(12.0)或更高版本。对于M1/M2芯片用户,需要特别注意镜像的ARM兼容性。
2.2 Docker Desktop安装
- 访问Docker官网下载对应芯片版本的Docker Desktop
- 双击下载的.dmg文件,将Docker图标拖到Applications文件夹
- 首次启动时会提示需要权限,按指引完成安装
- 在菜单栏可以看到Docker图标,表示服务已运行
注意:安装完成后建议在Preferences → Resources中调整内存分配(建议≥4GB),特别是需要运行多个容器时。
2.3 验证安装
打开终端运行:
bash复制docker --version
docker-compose --version
正常输出版本信息即表示安装成功。
3. Docker基础配置
3.1 镜像加速配置
国内用户建议配置镜像加速器,在Docker Desktop的Preferences → Docker Engine中添加:
json复制{
"registry-mirrors": [
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
]
}
点击Apply & Restart使配置生效。
3.2 常用命令速查
| 命令 | 说明 |
|---|---|
docker ps |
查看运行中的容器 |
docker images |
查看本地镜像 |
docker pull <镜像名> |
拉取镜像 |
docker exec -it <容器ID> bash |
进入容器终端 |
4. 部署Nginx+PHP环境
4.1 方案选型
我们有两种主流方案可选:
-
单个容器方案:使用集成了Nginx和PHP的镜像(如
webdevops/php-nginx)- 优点:部署简单
- 缺点:灵活性差,组件版本绑定
-
多容器方案:Nginx和PHP分别运行在不同容器
- 优点:组件可独立升级,配置灵活
- 缺点:需要配置容器间通信
我推荐使用多容器方案,下面是具体实现。
4.2 目录结构准备
创建项目目录并初始化结构:
code复制my-php-project/
├── docker-compose.yml
├── nginx/
│ ├── conf.d/
│ │ └── default.conf
│ └── nginx.conf
├── php/
│ └── Dockerfile
└── www/
└── index.php
4.3 编写Docker Compose文件
docker-compose.yml内容:
yaml复制version: '3.8'
services:
nginx:
image: nginx:1.23-alpine
ports:
- "8080:80"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./www:/var/www/html
depends_on:
- php
php:
build: ./php
volumes:
- ./www:/var/www/html
4.4 PHP容器配置
php/Dockerfile内容:
dockerfile复制FROM php:8.2-fpm-alpine
RUN docker-php-ext-install pdo pdo_mysql
WORKDIR /var/www/html
4.5 Nginx配置
nginx/conf.d/default.conf内容:
nginx复制server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php index.html;
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;
}
}
4.6 测试文件准备
www/index.php内容:
php复制<?php
phpinfo();
?>
5. 启动与验证
5.1 构建并启动服务
在项目根目录执行:
bash复制docker-compose up -d --build
5.2 验证服务
- 访问
http://localhost:8080应该能看到phpinfo页面 - 检查容器状态:
bash复制docker-compose ps
应该看到nginx和php两个容器都处于运行状态。
5.3 常用管理命令
| 操作 | 命令 |
|---|---|
| 停止服务 | docker-compose down |
| 查看日志 | docker-compose logs -f |
| 重建服务 | docker-compose up -d --force-recreate |
6. 高级配置与优化
6.1 PHP扩展安装
修改php/Dockerfile添加更多扩展:
dockerfile复制RUN apk add --no-cache \
libzip-dev \
libpng-dev \
libjpeg-turbo-dev \
freetype-dev
RUN docker-php-ext-install \
zip \
gd \
mysqli \
pdo_mysql
6.2 Xdebug配置
开发环境建议启用Xdebug:
dockerfile复制RUN apk add --no-cache $PHPIZE_DEPS \
&& pecl install xdebug \
&& docker-php-ext-enable xdebug
然后在www/目录下创建php.ini:
ini复制[xdebug]
xdebug.mode=debug
xdebug.client_host=host.docker.internal
xdebug.start_with_request=yes
6.3 性能优化建议
- 对于M1/M2芯片,使用ARM架构的基础镜像(如
php:8.2-fpm-alpine) - 在
docker-compose.yml中为PHP配置资源限制:
yaml复制php:
build: ./php
deploy:
resources:
limits:
cpus: '2'
memory: 1G
7. 常见问题排查
7.1 端口冲突
如果8080端口被占用,修改docker-compose.yml中的端口映射:
yaml复制ports:
- "8081:80"
7.2 文件权限问题
在容器内执行命令时可能遇到权限问题,解决方案:
bash复制docker-compose exec php chown -R www-data:www-data /var/www/html
7.3 容器间通信失败
确保nginx配置中fastcgi_pass指向正确的服务名:
nginx复制fastcgi_pass php:9000; # 这里的"php"必须与compose中的服务名一致
7.4 性能问题排查
使用以下命令监控容器资源使用:
bash复制docker stats
8. 实际开发建议
- 代码热重载:在
docker-compose.yml中添加:
yaml复制services:
php:
volumes:
- ./www:/var/www/html:cached
-
多项目管理:为每个项目创建独立的compose文件,使用不同端口
-
数据库集成:在compose中添加MySQL服务:
yaml复制services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: example
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
- 环境变量管理:使用
.env文件管理敏感配置:
env复制DB_PASSWORD=secret
在compose中引用:
yaml复制environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
这套环境我已经在多个实际项目中验证过,特别是在团队协作时,通过共享docker-compose配置可以确保所有成员使用完全一致的开发环境。对于需要切换PHP版本的项目,只需修改Dockerfile中的基础镜像版本即可,完全不会影响主机系统。