Search code examples
dockerdockerfile

In Dockerfile, COPY all contents of current directory except one directory


In my Dockerfile, I have the following:

COPY . /var/task

...which copies my app code into the image.

I need to exclude the vendor/ directory when performing this copy.

  • I cannot add vendor/ to .dockerignore, because that directory needs to be part of the image when it gets built within the image with a RUN composer install.
  • I cannot specify every file and directory that should be copied, because they may change and I can't rely on other developers to keep the list updated.

I've tried the following, with the following errors:

COPY [^vendor$]* /var/task

When using COPY with more than one source file, the destination must be a directory and end with a /

COPY [^vendor$]*/ /var/task

COPY failed: no source files were specified


Solution

  • It is actually enough to add the vendor directory to the .dockerignore file.

    You can broadly follow the flow of files through docker build in three phases:

    1. docker build reads files from the directory you name, ignoring things in the .dockerignore file, and sends them to the Docker daemon as the build context.
    2. The COPY instruction copies files from the build context into the container filesystem.
    3. RUN instructions do further transformation or processing.

    If you put vendor in the .dockerignore file, it prevents the directory from being included in the build context. The build will go somewhat faster, and COPY won't have the files to copy into the image. It won't prevent a RUN composer install step later on from creating its own vendor directory in the image.