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

Docker部署PHP应用:构建时如何自动覆盖已有卷内容?

解决方案

一、自动覆盖已有卷内容:用初始化容器同步代码

如果要保留共享卷机制,同时实现启动时自动更新卷内代码,可以添加一个初始化容器,在Caddy和PHP-FPM启动前完成最新代码的同步。这个容器会从你的应用镜像中把最新代码复制到共享卷,覆盖旧内容。

以下是docker-compose.yml的示例配置:

version: '3.8'

services:
  # 初始化容器:同步最新代码到共享卷
  code-sync:
    image: your-app-image:latest  # 包含最新应用代码的镜像
    command: >
      sh -c "cp -r /app/. /shared-code/"
    volumes:
      - app-code:/shared-code  # 挂载共享卷

  caddy:
    image: caddy:latest
    depends_on:
      - code-sync
      - php-fpm
    volumes:
      - app-code:/var/www/html  # 挂载共享卷到Caddy网站目录
      - ./Caddyfile:/etc/caddy/Caddyfile
    ports:
      - "80:80"
      - "443:443"

  php-fpm:
    image: php:8.2-fpm
    depends_on:
      - code-sync
    volumes:
      - app-code:/var/www/html  # 挂载共享卷到PHP-FPM工作目录

volumes:
  app-code:

如果需要保留卷内的持久化文件(比如用户上传的资源),可以修改复制命令跳过指定目录,或者用rsync做增量同步:

# 跳过uploads目录,只同步其他代码
rsync -av --exclude='uploads' /app/ /shared-code/

二、无需共享卷:多阶段构建打包代码到各自容器

不想用共享卷的话,可以通过多阶段构建,分别为Caddy和PHP-FPM制作包含对应代码的镜像,让两个容器各自持有所需文件,完全脱离共享存储依赖。

Caddy镜像的Dockerfile:

# 第一阶段:准备应用代码
FROM php:8.2-fpm AS builder
WORKDIR /app
COPY . .
RUN composer install --no-dev --optimize-autoloader  # 安装PHP依赖

# 第二阶段:制作Caddy镜像,仅复制静态资源和入口文件
FROM caddy:latest
WORKDIR /var/www/html
COPY --from=builder /app/public /var/www/html/public
COPY --from=builder /app/index.php /var/www/html/
COPY ./Caddyfile /etc/caddy/Caddyfile

PHP-FPM镜像的Dockerfile:

# 复用代码准备阶段
FROM php:8.2-fpm AS builder
WORKDIR /app
COPY . .
RUN composer install --no-dev --optimize-autoloader

# 制作PHP-FPM镜像,复制全部PHP代码
FROM php:8.2-fpm
WORKDIR /var/www/html
COPY --from=builder /app /var/www/html
# 可在此添加PHP扩展安装等操作

对应的docker-compose配置:

version: '3.8'

services:
  caddy:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - php-fpm

  php-fpm:
    build:
      context: .
      dockerfile: Dockerfile.php-fpm

更新代码时,只需重新构建两个镜像,容器启动后直接使用镜像内的最新代码,彻底规避卷内容冲突问题。

三、备选方案:绑定挂载主机目录

如果部署环境允许操作主机文件系统,可以用绑定挂载替代Docker卷,直接将主机上的应用代码目录挂载到两个容器中。更新代码时,替换主机目录内的内容即可,容器会自动读取最新版本:

version: '3.8'

services:
  caddy:
    image: caddy:latest
    volumes:
      - ./your-app-code:/var/www/html  # 绑定挂载主机代码目录
      - ./Caddyfile:/etc/caddy/Caddyfile
    ports:
      - "80:80"
      - "443:443"

  php-fpm:
    image: php:8.2-fpm
    volumes:
      - ./your-app-code:/var/www/html  # 挂载同一个主机目录

该方案更适合开发环境,生产环境建议优先使用前两种方案,减少对主机文件系统的依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 08:23:17