Search code examples
phpdockercomposer-phpdocker-multi-stage-build

How to copy from one image to another in a docker multistaged build?


I want to copy the vendor folder from the composer image to another php image during a multistaged build.

My Dockerfile looks like this:

FROM composer
WORKDIR /tmp/composer-vendors/
COPY composer.lock composer.json ./
RUN composer install --ignore-platform-reqs
RUN pwd && ls

FROM php:7.3-fpm-alpine
WORKDIR /var/www/html
RUN pwd && ls
COPY --from=composer /tmp/composer-vendors/vendor ./vendor
CMD ["php-fpm"]

The RUN pwd && ls is only there to show that the files are indeed there.

Yet the copy --from=composer fails stating:

Step 9/10 : COPY --from=composer /tmp/composer-vendors/vendor ./vendor
COPY failed: stat /var/lib/docker/overlay2/c0cece8b4ffcc3ef3f6ed26c3131ae94813acffd5034b359c2ea6aed922f56ee/merged/tmp/composer-vendors/vendor: no such file or directory

What am I doing wrong?


My example composer.json:

{
  "name": "kopernikus/multistage-copy-issue",
  "require": {
    "nesbot/carbon": "^2.36"
  }
}

Solution

  • You have to alias the image as otherwise docker uses the base image as provided by composer and not the image you built.

    This means you need to change your FROM statement:

    FROM composer as BUILDER
    

    and reference your image:

    COPY --from=BUILDER /tmp/composer-vendors/vendor ./vendor
    

    The alias could be anything, I used BUILDER as an example. In fact, you could even reuse the name:

    FROM composer AS composer
    

    though that might lead to unexpected behavior if people are not expecting a modified image.