Conditional COPY in Dockerfile?

Viewed 6288

I have an application with a production Dockerfile that copies our source code into the container, i.e:

COPY . /app

I would like to make this copy conditional, so that passing in a CONTEXT= environment variable prevents/allows this line to execute. Is that possible?

I saw related posts on here but no clear answer. Thanks!

2 Answers

From this post I discovered that Docker-Compose 3.7 supports targeting individual build stages.

So I created a Dockerfile with 2 stages, a base layer that sets up the container, then a deploy that copies in the codebase:

# BUILD STAGE 1 - BASE
FROM webdevops/php-apache:7.2-alpine as base

# Do stuff

# BUILD STAGE 2 - DEPLOY
FROM base as deploy

# Add project
COPY . /app

# Do other stuff

Then I configured my dev docker-compose.yml to target only the base layer, and to mount a volume for the code.

version: "3.7"

services:
  app.base.img:
    build:
      context: .
      target: base
    volumes:
      - ./:/app
    container_name: app.base

My production pipeline builds the image normally (with both layers).

Note the version 3.7 declaration, apparently it's required.

This does what I want, thanks for all the comments and suggestions on this! If you think this is unwise feel free to comment.

No. You should pre-process your project before building the final image.

Multistage builds might help you do that:

FROM debian AS builder
ARG CONTEXT
WORKDIR /final
COPY . /app
RUN bash -c "[ '$CONTEXT' = '1' ] || cp -rfv /app/* /final/"

FROM debian
COPY --from=builder /final /app

In this example, passing --build-arg CONTEXT=1 prevents it from filling the /app folder in the final image, thus removing it from the final image.

Related