Docker容器化高可用架构部署方案(八)

07-PHP服务配置详解

本文档详细介绍PHP服务的配置,采用双容器架构(nginx:alpine + php:8.2-fpm-alpine),实现静态文件服务和动态PHP处理分离。

双容器架构说明

PHP服务由两个容器组成:

复制代码
┌─────────────────────────────────────────────────────────┐
│                    PHP服务 (双容器)                      │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  ┌───────────────────┐    ┌───────────────────────────┐ │
│  │   php (nginx:alpine)│    │  php-fpm (php:8.2-fpm)   │ │
│  │   172.20.2.11      │    │  172.20.2.21              │ │
│  │                    │    │                           │ │
│  │   监听: 80         │◄───│  fastcgi_pass             │ │
│  │                    │    │  监听: 9000               │ │
│  │   静态文件         │    │  PHP解析                  │ │
│  └───────────────────┘    └───────────────────────────┘ │
│                                                         │
│              shared volume: web-data                    │
│              (/usr/share/nginx/html = /var/www/html)   │
└─────────────────────────────────────────────────────────┘

容器职责

容器 镜像 IP 职责
php nginx:alpine 172.20.2.11 静态文件服务、接收请求、转发PHP到fastcgi
php-fpm php:8.2-fpm-alpine 172.20.2.21 解析PHP代码、执行逻辑

通信流程

复制代码
客户端请求 → nginx-lb → php(172.20.2.11:80) 
                          │
                          ▼ fastcgi_pass
                    php-fpm(172.20.2.21:9000)
                          │
                          ▼ 读取/写入
                    共享卷 web-data

nginx配置(php-node*.conf)

php-node1.conf

复制代码
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
​
events {
    worker_connections 1024;
    use epoll;
    multi_accept on;
}
​
http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
​
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for" '
                    'request_time: $request_time';
​
    access_log /var/log/nginx/access.log main;
​
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    client_max_body_size 100M;
​
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/xml text/javascript 
               application/json application/javascript application/xml+rss 
               application/rss+xml font/truetype font/opentype 
               application/vnd.ms-fontobject image/svg+xml;
​
    server {
        listen 80;
        server_name localhost;
        root /usr/share/nginx/html;
        index index.php index.html index.htm;
​
        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }
​
        location ~ \.php$ {
            fastcgi_pass 172.20.2.21:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
            include fastcgi_params;
        }
​
        location /health {
            access_log off;
            return 200 "php-healthy\n";
            add_header Content-Type text/plain;
        }
​
        error_page 404 /404.html;
        error_page 500 502 503 504 /50x.html;
    }
}

节点配置差异

节点 配置文件 fastcgi_pass root
Node1 php-node1.conf 172.20.2.21:9000 /usr/share/nginx/html
Node2 php-node2.conf 172.20.2.22:9000 /usr/share/nginx/html
Node3 php-node3.conf 172.20.2.23:9000 /usr/share/nginx/html

关键配置项详解

1. fastcgi_pass

复制代码
location ~ \.php$ {
    fastcgi_pass 172.20.2.21:9000;  # 指向本节点的php-fpm容器
    ...
}

重要

  • 不能使用127.0.0.1:9000localhost:9000

  • 必须使用php-fpm的外部IP(macvlan分配的IP)

  • 每个节点的php.conf中IP不同

2. root路径

复制代码
root /usr/share/nginx/html;  # nginx容器内路径

注意

  • nginx容器使用/usr/share/nginx/html

  • php-fpm容器使用/var/www/html

  • 通过共享卷web-data保持一致

3. SCRIPT_FILENAME

复制代码
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;

说明

  • 必须是nginx容器内的完整路径

  • 与root配置保持一致

php.ini配置

复制代码
[PHP]
upload_max_filesize = 50M
post_max_size = 50M
max_execution_time = 60
memory_limit = 256M
display_errors = Off
log_errors = On
error_log = /var/log/php/error.log
date.timezone = Asia/Shanghai
​
[Session]
session.save_handler = redis
session.save_path = "tcp://172.20.3.11:6379?auth=YourStr0ng!Pass"
​
[opcache]
opcache.enable = 1
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 8
opcache.max_accelerated_files = 4000

配置项说明

配置 说明
upload_max_filesize 上传文件最大大小
post_max_size POST数据最大大小
max_execution_time 脚本最大执行时间
memory_limit 脚本最大内存
session.save_handler Session存储方式
session.save_path Redis服务器地址
opcache.* OPcache加速配置

Docker Compose配置

Node1示例

复制代码
php:
  image: nginx:alpine
  container_name: php
  networks:
    backend-net:
      ipv4_address: 172.20.2.11
  volumes:
    - ./config/php/php-node1.conf:/etc/nginx/nginx.conf:ro
    - web-data:/usr/share/nginx/html
  restart: unless-stopped
  healthcheck:
    test: ["CMD-SHELL", "curl -f http://localhost/index.php > /dev/null 2>&1 || exit 1"]
    interval: 10s
    timeout: 5s
    retries: 3
​
php-fpm:
  build: ./config/php-fpm  # 基于php:8.2-fpm-alpine安装pdo_mysql
  container_name: php-fpm
  networks:
    backend-net:
      ipv4_address: 172.20.2.21
  volumes:
    - ./config/php/php.ini:/usr/local/etc/php/conf.d/custom.ini:ro
    - web-data:/var/www/html
  restart: unless-stopped
  healthcheck:
    test: ["CMD", "php-fpm", "-t"]
    interval: 10s
    timeout: 5s
    retries: 3
​
volumes:
  web-data:

服务IP分配

节点 php php-fpm
Node1 172.20.2.11 172.20.2.21
Node2 172.20.2.12 172.20.2.22
Node3 172.20.2.13 172.20.2.23

部署注意事项

1. 配置文件必须先创建

复制代码
# 确保配置文件存在
touch /opt/cluster-deploy/config/php/php-node1.conf
touch /opt/cluster-deploy/config/php/php-node2.conf
touch /opt/cluster-deploy/config/php/php-node3.conf
touch /opt/cluster-deploy/config/php/php.ini

2. 正确配置fastcgi_pass

  • Node1: fastcgi_pass 172.20.2.21:9000;

  • Node2: fastcgi_pass 172.20.2.22:9000;

  • Node3: fastcgi_pass 172.20.2.23:9000;

3. 共享卷一致性

  • nginx容器挂载:web-data:/usr/share/nginx/html

  • php-fpm容器挂载:web-data:/var/www/html

  • 确保两边路径对应正确

4. 健康检查端点

每个php容器提供/health端点:

复制代码
# 测试健康状态
curl http://172.20.2.11/health
curl http://172.20.2.12/health
curl http://172.20.2.13/health

创建测试页面

复制代码
# 创建测试页面
cat > /opt/cluster-deploy/index.php << 'EOF'
<?php
echo "<h1>PHP Service Test</h1>";
echo "<p>Server: " . gethostname() . "</p>";
echo "<p>PHP Version: " . phpversion() . "</p>";
echo "<p>Time: " . date('Y-m-d H:i:s') . "</p>";
echo "<p>REMOTE_ADDR: " . $_SERVER['REMOTE_ADDR'] . "</p>";

# 测试Redis连接
try {
    $redis = new Redis();
    $redis->connect('172.20.3.11', 6379);
    $redis->auth('YourStr0ng!Pass');
    echo "<p>Redis: Connected</p>";
} catch (Exception $e) {
    echo "<p>Redis: Error - " . $e->getMessage() . "</p>";
}

# 测试Session
session_start();
$_SESSION['test'] = 'Hello from PHP!';
echo "<p>Session ID: " . session_id() . "</p>";
echo "<p>Session Data: " . ($_SESSION['test'] ?? 'Not set') . "</p>";
?>
EOF

# 复制到共享卷
docker run --rm -v web-data:/data -v $(pwd)/index.php:/index.php alpine cp /index.php /data/

常见问题

Q1: 502 Bad Gateway

  • 检查php-fpm是否运行:docker ps | grep php-fpm

  • 检查fastcgi_pass地址是否正确

  • 检查网络连通性:ping 172.20.2.21

Q2: PHP代码不执行

  • 检查SCRIPT_FILENAME路径

  • 确认root路径与挂载路径一致

Q3: Session无法写入Redis

  • 检查Redis连接:telnet 172.20.3.11 6379

  • 验证密码认证

  • 检查php.ini中的session配置

验证命令

复制代码
# 查看PHP容器
docker ps | grep -E "php|php-fpm"

# 测试PHP服务
curl http://172.20.2.11/index.php
curl http://172.20.2.12/index.php
curl http://172.20.2.13/index.php

# 测试健康检查
curl http://172.20.2.11/health
curl http://172.20.2.12/health
curl http://172.20.2.13/health

# 查看PHP-FPM日志
docker logs php-fpm

# 查看PHP版本
docker exec php-fpm php -v

下一步

相关推荐
●VON23 分钟前
AtomGit Flutter鸿蒙客户端:文件树与代码浏览
android·服务器·安全·flutter·harmonyos·鸿蒙
故渊at7 小时前
系列三:组件化与模块化进阶 | 第11篇 组件化项目规范与问题根治:依赖、资源、Manifest 与混淆的全链路管控
android·架构·mvvm·模块化·组件化
审判长烧鸡7 小时前
【AI问答/Docker】Docker全命令对照表:命令+中文+示例+示例说明
docker·ai
故渊at7 小时前
系列二:MVVM 深度实战与项目重构 | 第7篇 LiveData & StateFlow 状态管理实战:从“粘包弹”到“丝滑流式”
android·重构
是阿建吖!7 小时前
【Linux】信号
android·linux·c语言·c++
小肥君7 小时前
docker无法连接GPU资源解决方案
docker·容器·eureka
viva51729 小时前
Docker/历史演进,核心功能,相关工具
docker
goodluckyaa9 小时前
NVIDIAGPU 架构中的不变常量(宏观 → 微观)
架构·gpu算力
alexhilton9 小时前
AppFunctions:让你的Android应用更容易被AI智能体发现
android·kotlin·android jetpack
qq3621967059 小时前
APK文件签名校验教程:验证APK真伪的完整方法
android·智能手机