1. 为什么选择在macOS上使用Docker部署Nginx+PHP

作为一名长期在macOS环境下工作的全栈开发者,我深刻理解本地开发环境配置的痛点。传统方式直接在macOS上安装Nginx和PHP会遇到版本冲突、依赖管理复杂等问题,而Docker提供了一种优雅的解决方案。

Docker的核心价值在于环境隔离和可移植性。通过容器化技术,我们可以:

  • 避免污染主机环境,保持系统纯净
  • 快速切换不同版本的PHP/Nginx组合进行测试
  • 团队共享相同的开发环境配置
  • 开发环境与生产环境高度一致

对于macOS用户来说,Docker Desktop提供了原生支持M1/M2芯片的版本,性能接近原生应用。实测在2021款M1 Pro MacBook Pro上,运行Nginx+PHP容器的性能损耗不到5%,完全满足日常开发需求。

重要提示:如果你的Mac是M系列芯片,务必下载Apple Silicon版本的Docker Desktop,否则会遇到兼容性问题导致性能大幅下降。

2. macOS环境下的Docker安装与配置

2.1 系统要求检查

在开始安装前,请确认你的macOS满足以下要求:

  • macOS 10.15 Catalina或更高版本
  • 至少4GB内存(建议8GB以上)
  • 20GB可用磁盘空间
  • 对于Intel芯片:支持硬件虚拟化(VT-x)
  • 对于Apple Silicon:无需特别配置

可以通过以下命令检查硬件虚拟化支持(仅Intel芯片):

sysctl -a | grep machdep.cpu.features

输出中应包含"VMX"字样。

2.2 Docker Desktop安装步骤

  1. 访问Docker官网下载对应版本:

    • Intel芯片:https://docs.docker.com/desktop/install/mac-install/
    • Apple Silicon:https://docs.docker.com/desktop/install/mac-apple-silicon/
  2. 双击下载的.dmg文件,将Docker图标拖到Applications文件夹

  3. 首次启动时会要求权限授权:

    • 允许网络连接
    • 允许访问Downloads和Documents目录
  4. 等待初始化完成(首次启动较慢)

  5. 在顶部菜单栏看到Docker图标表示运行成功

2.3 常见安装问题解决

问题1:Docker Desktop启动失败,提示"Virtualization support not detected"

解决方案:

  1. 重启Mac,开机时按住Command+R进入恢复模式
  2. 打开终端,执行:
    spctl kext-consent add VB5E2TV963
    
  3. 重启后再次尝试启动Docker

问题2:M1芯片上镜像兼容性问题

解决方案:

  1. 确保使用ARM架构的基础镜像
  2. 或在docker-compose.yml中指定平台:
    platform: linux/amd64
    

3. Nginx+PHP容器化部署实战

3.1 项目目录结构规划

建议采用以下目录结构:

~/projects/nginx-php-demo/
├── docker-compose.yml
├── nginx/
│   ├── conf.d/
│   │   └── default.conf
│   └── nginx.conf
├── php/
│   └── php.ini
└── www/
    └── index.php

3.2 docker-compose.yml配置

创建docker-compose.yml文件:

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
    networks:
      - app-network

  php:
    image: php:8.2-fpm-alpine
    volumes:
      - ./www:/var/www/html
      - ./php/php.ini:/usr/local/etc/php/conf.d/custom.ini
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

关键配置说明:

  • 使用alpine版本镜像减小体积
  • 将本地www目录映射到容器/var/www/html
  • 自定义nginx配置和php.ini
  • 创建专用网络确保容器间通信

3.3 Nginx配置文件

创建nginx/conf.d/default.conf:

server {
    listen 80;
    index index.php index.html;
    server_name localhost;
    root /var/www/html;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

3.4 PHP测试文件

创建www/index.php:

<?php
phpinfo();
?>

4. 容器启动与调试

4.1 启动容器服务

在项目根目录执行:

docker-compose up -d

首次运行会下载镜像并创建容器,完成后访问: http://localhost:8080

应该能看到PHP信息页面。

4.2 常用操作命令

  • 查看运行中的容器:

    docker-compose ps
    
  • 查看Nginx日志:

    docker-compose logs nginx
    
  • 进入PHP容器:

    docker-compose exec php sh
    
  • 重启服务:

    docker-compose restart
    
  • 停止并删除容器:

    docker-compose down
    

4.3 性能优化配置

Nginx优化: 在nginx/nginx.conf中添加:

worker_processes auto;
events {
    worker_connections 1024;
    multi_accept on;
    use epoll;
}

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    server_tokens off;
    
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}

PHP优化: 在php/php.ini中添加:

memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 120
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1

5. 高级配置与扩展

5.1 多PHP版本管理

如果需要切换PHP版本,只需修改docker-compose.yml中的镜像标签:

php:
  image: php:7.4-fpm-alpine

然后重新构建:

docker-compose up -d --build

5.2 数据库集成

添加MySQL服务到docker-compose.yml:

services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: app_db
      MYSQL_USER: app_user
      MYSQL_PASSWORD: password
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - app-network

volumes:
  mysql_data:

然后在PHP容器中安装MySQL扩展:

docker-compose exec php sh
apk add --no-cache mysql-client
docker-php-ext-install pdo_mysql
exit
docker-compose restart php

5.3 Xdebug配置

开发环境下可以启用Xdebug进行调试:

  1. 创建php/xdebug.ini:
zend_extension=xdebug.so
xdebug.mode=develop,debug
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.start_with_request=yes
xdebug.discover_client_host=1
  1. 修改docker-compose.yml中PHP服务的volumes:
volumes:
  - ./php/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini
  1. 在IDE中配置PHP远程调试,端口9003

6. 生产环境注意事项

虽然本文主要面向开发环境,但如果你计划将这种配置用于生产环境,需要注意:

  1. 安全性强化

    • 禁用PHP危险函数:
      disable_functions = exec,passthru,shell_exec,system,proc_open,popen
      
    • Nginx隐藏版本信息:
      server_tokens off;
      
  2. 性能监控

    • 使用cAdvisor监控容器资源使用
    • 设置资源限制:
      php:
        deploy:
          resources:
            limits:
              cpus: '2'
              memory: 1G
      
  3. 日志管理

    • 配置日志轮转
    • 将日志输出到stdout/stderr以便Docker收集
  4. 高可用性

    • 使用多个Nginx worker
    • 配置PHP-FPM进程池

我在实际项目中使用这套配置已经稳定运行了3年多,最大的体会是Docker带来的环境一致性让团队协作变得非常顺畅。新成员加入时,只需git clone代码库后执行docker-compose up,就能获得完全一致的开发环境,彻底告别"在我机器上是好的"这类问题。

更多推荐