You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kubernetes Pod中实现Caddy与PHP-FPM的代码分离部署

解决方案:实现Caddy仅存配置、代码在PHP-FPM容器的架构

你的问题核心在于:Caddy的file_server指令需要读取本地静态文件,而PHP-FPM仅能处理PHP脚本的FastCGI请求,无法直接响应静态文件HTTP请求。要实现Caddy仅存放配置、代码完全在PHP-FPM侧的架构,有两种可行方案:


方案1:PHP-FPM容器内置HTTP服务器(严格满足代码仅在PHP-FPM容器)

让PHP-FPM容器同时运行一个HTTP服务器(比如Nginx),由它负责处理静态文件,并将PHP请求转发给本地的PHP-FPM进程。Caddy仅作为反向代理,将所有请求转发到PHP-FPM容器内的HTTP服务器,完全不接触代码。

步骤1:修改Caddy配置

移除原配置中涉及本地文件读取的root、file_server和静态文件规则,改为反向代理:

my.caddy.website:80 {
    reverse_proxy localhost:8080  # 指向PHP-FPM容器内的HTTP服务器端口
    encode gzip
    log {
        output file /var/log/caddy/my.caddy.website.access.log
    }
    # 静态文件缓存规则可以保留,由后端HTTP服务器处理后,Caddy添加响应头
    @static {
        path *.ico *.css *.js *.gif *.jpg *.jpeg *.png *.svg *.woff *.pdf *.webp
    }
    header @static Cache-Control max-age=5184000
}

步骤2:构建包含HTTP服务器的PHP-FPM镜像

需要自定义PHP-FPM镜像,内置Nginx、应用代码,并配置Nginx处理静态文件和PHP请求:

  1. 镜像中安装PHP-FPM、Nginx和进程管理工具(如supervisord)
  2. 添加Nginx配置示例:
server {
    listen 8080;
    root /app;

    # 处理静态文件
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # 转发PHP请求到本地PHP-FPM
    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
  1. 编写启动脚本,用supervisord同时启动Nginx和PHP-FPM

步骤3:Kubernetes Deployment配置

将Caddy和自定义PHP-FPM容器放在同一个Pod中(共享网络,可通过localhost通信):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: php-caddy-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: php-caddy
  template:
    metadata:
      labels:
        app: php-caddy
    spec:
      containers:
        - name: php-fpm-nginx
          image: your-custom-php-nginx-image  # 替换为你的自定义镜像
          ports:
            - containerPort: 8080
        - name: caddy
          image: caddy:2-alpine
          volumeMounts:
            - name: caddy-config
              mountPath: /etc/caddy/Caddyfile
          ports:
            - containerPort: 80
      volumes:
        - name: caddy-config
          configMap:
            name: caddy-config  # 提前创建包含Caddy配置的ConfigMap

方案2:共享卷挂载(K8s最佳实践,性能更优)

用Kubernetes共享卷存储应用代码,Caddy和PHP-FPM容器同时挂载该卷。此方案中,代码存储在卷而非容器镜像内,Caddy镜像仅包含Caddy程序和配置,符合“仅存配置”的要求,同时静态文件由Caddy直接处理,性能更好。

步骤1:调整Kubernetes Deployment配置

定义共享卷(生产环境建议用PersistentVolumeClaim,示例用EmptyDir),并挂载到两个容器的/app目录:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: php-caddy-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: php-caddy
  template:
    metadata:
      labels:
        app: php-caddy
    spec:
      volumes:
        - name: app-code
          emptyDir: {}  # 临时存储,重启Pod会丢失,生产环境替换为PersistentVolumeClaim
        - name: caddy-config
          configMap:
            name: caddy-config
      # 可选:用initContainer拉取代码到共享卷
      initContainers:
        - name: fetch-app-code
          image: alpine/git
          command: ["git", "clone", "https://your-repo-url.git", "/app"]
          volumeMounts:
            - name: app-code
              mountPath: /app
      containers:
        - name: php-fpm
          image: php:8.2-fpm
          volumeMounts:
            - name: app-code
              mountPath: /app
        - name: caddy
          image: caddy:2-alpine
          volumeMounts:
            - name: app-code
              mountPath: /app
            - name: caddy-config
              mountPath: /etc/caddy/Caddyfile
          ports:
            - containerPort: 80

步骤2:保留原Caddy配置

原配置可直接使用,因为Caddy现在能通过共享卷访问到/app目录的静态文件,PHP请求转发到localhost:9000(同一Pod内的PHP-FPM容器)。


方案对比

方案优点缺点
PHP-FPM内置HTTP服务器代码完全在PHP-FPM容器内,Caddy完全不接触代码容器需运行多进程,复杂度高;静态文件性能略低
共享卷挂载架构清晰,各容器职责单一;静态文件由Caddy处理,性能更优代码存储在卷而非PHP-FPM镜像内;需管理卷的代码同步

内容的提问来源于stack exchange,提问作者Nagri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 15:34:57