为什么 composer.json 卷目录中的文件在 dockerfile 中的 composer install 命令 运行 中不可见?

Why composer.json file from volume directory is not visible in composer install command run in dockerfile?

docker-compose.yml:

version: '3.3'
services:
    web:
        image: nginx:latest
        ports:
            - "8080:80"
        volumes:
            - ./api:/var/www/html/api
            - ./site.conf:/etc/nginx/conf.d/default.conf
        links:
            - php
    php:
        build:
            context: ./docker
            dockerfile: php.Dockerfile
        volumes:
        - ./api:/var/www/html/api
        links:
            - db
    db:
       image: mysql:5.7 
       environment:
         MYSQL_ROOT_PASSWORD: password
         MYSQL_DATABASE: symfony
         MYSQL_USER: symfony
         MYSQL_PASSWORD: symfony
       ports:
         - "9906:3306"

php.Dockerfile:

FROM php:7-fpm
WORKDIR /var/www/html/api
COPY --from=composer /usr/bin/composer /usr/bin/composer
RUN apt-get update && apt-get upgrade -y \
    && apt-get install -y git libzip-dev unzip \
    && docker-php-ext-install \
        pdo_mysql zip \
    && docker-php-ext-enable \
        pdo_mysql zip \
    && composer install \
    && bin/console make:migration

命令输出错误:docker-compose build --no-cache:

Composer could not find a composer.json file in /var/www/html/api

但是当我在 PHP 容器内时使用 docker exec -it sf4_php_1 bash

我看到 composer.json 文件在 /var/www/html/api 中,我能够 运行 composer install 正确。

我做错了什么?

该卷是在 运行 时间 安装的,而不是在 构建 时间安装的。

当你构建镜像时,里面没有composer.json,因为你的卷还没有安装。

在 运行 composer install 之前,您需要 复制 构建过程所需的所有文件。

例如更好的 Dockerfile 应该是这样的:

(在这种情况下,我带来了一些 Symfony 文件,因为这是从 Symfony 图像复制的)

COPY --from=composer /usr/bin/composer /usr/bin/composer

RUN apt-get update && apt-get upgrade -y \
    && apt-get install -y git libzip-dev unzip \
    && docker-php-ext-install \
        pdo_mysql zip \
    && docker-php-ext-enable \
        pdo_mysql zip

RUN mkdir -p /var/www/html/api
WORKDIR /var/www/html/api

COPY composer.json composer.lock symfony.lock .env.dist ./

RUN composer install \
    && bin/console make:migration

这不仅会实际工作,而且会为应用程序的构建和平台要求的安装生成不同的层。这样,composer.json 中的更改不会触发重新安装 PHP 扩展和更新 apt。