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

构建PHP Docker基础镜像时vendor目录缺失,容器主机同步失败

问题:PHP镜像构建阶段生成的vendor目录消失的排查与解决

场景描述

尝试搭建PHP基础镜像作为应用基座,计划在镜像构建阶段完成项目初始化及依赖包安装,但执行docker-compose up --build后,主机和容器中均未生成vendor目录,导致应用无法运行。

相关配置文件

Dockerfile

ARG PHP_VERSION=8.1.9

FROM php:${PHP_VERSION}-cli-alpine

# ARG PECL_OPENSWOOLE_VERSION=4.11.1

RUN apk update \
    && apk add --no-cache \
    supervisor \
    tree \
    vim \
    --update linux-headers \
    && rm -rf /tmp/pear

# supervisord setup
RUN mkdir -p /etc/supervisor/ \
    && mkdir -p /var/log/supervisord/
COPY docker/dev/php-cli/config/supervisord.conf /etc/supervisor/conf.d/supervisord.conf

# install composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer


COPY . /srv/www/
WORKDIR /srv/www
RUN mkdir -p vendor
RUN chown -R www-data: /srv/www

USER www-data
RUN composer validate --strict 
RUN composer install

USER root
ENTRYPOINT ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

项目目录结构

├── Makefile
├── bin
│	└── console
├── composer.json
├── config
├── docker
│	└── dev
│	    ├── nginx
│	    │	└── app.conf
│	    └── php-cli
│	        ├── Dockerfile
│	        └── config
│	            └── supervisord.conf
├── docker-compose.yaml
└── src
    └── user.php

docker-compose.yaml

version: '3.9'
services:
  app:
    build:
      context: .
      dockerfile: docker/dev/php-cli/Dockerfile
    volumes:
      - .:/srv/www/

问题根源

核心原因是绑定挂载覆盖了镜像内的目录:
当docker-compose up启动容器时,./:/srv/www的挂载规则会将主机当前目录的内容完全覆盖容器内的/srv/www目录。由于主机目录原本没有vendor文件夹,构建阶段在镜像内生成的vendor就被覆盖掉了,导致容器内和主机都看不到该目录。

解决方案

方案1:保留镜像内的vendor目录,避免挂载覆盖

修改docker-compose.yaml,添加一条挂载规则,让容器内的/srv/www/vendor目录不被主机挂载覆盖:

version: '3.9'
services:
  app:
    build:
      context: .
      dockerfile: docker/dev/php-cli/Dockerfile
    volumes:
      - .:/srv/www/
      - /srv/www/vendor  # 这条规则会保留镜像内的vendor目录,不受主机挂载影响

方案2:优化Dockerfile构建逻辑,提升缓存效率

原Dockerfile先复制整个项目再执行composer install,每次代码变更都会触发重新安装依赖。调整后先复制composer相关文件,利用Docker构建缓存,仅当composer.json或composer.lock变更时才重新安装依赖:

ARG PHP_VERSION=8.1.9

FROM php:${PHP_VERSION}-cli-alpine

# ARG PECL_OPENSWOOLE_VERSION=4.11.1

RUN apk update \
    && apk add --no-cache \
    supervisor \
    tree \
    vim \
    linux-headers \
    && rm -rf /tmp/pear

# supervisord setup
RUN mkdir -p /etc/supervisor/ \
    && mkdir -p /var/log/supervisord/
COPY docker/dev/php-cli/config/supervisord.conf /etc/supervisor/conf.d/supervisord.conf

# install composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# 先复制composer配置文件,利用构建缓存
WORKDIR /srv/www
COPY composer.json composer.lock* ./
RUN mkdir -p vendor \
    && chown -R www-data: /srv/www

USER www-data
RUN composer validate --strict \
    && composer install  # 可根据需求添加--no-dev、--optimize-autoloader等参数

# 最后复制项目代码
USER root
COPY . /srv/www/
RUN chown -R www-data: /srv/www

USER www-data
ENTRYPOINT ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

额外验证步骤

  • 单独运行镜像(不挂载目录),检查vendor是否存在:
    docker run --rm $(docker build -q . -f docker/dev/php-cli/Dockerfile) ls /srv/www/vendor
    
  • 如果需要主机也同步vendor目录,可从容器拷贝:
    docker cp $(docker ps -qf "name=app"):/srv/www/vendor ./
    

内容的提问来源于stack exchange,提问作者mina.nsami

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 17:25:06