Page MenuHomePhabricator

Add support to generate Blubber file requirements from .gitignore
Closed, DeclinedPublic

Description

The Blubber config accepts a requirements array property that is a list of all files needed in the container to perform a task. This works but is challenging to keep in sync with .gitignore, especially since most developers don't run Blubber locally. This ticket is a feature request to support reading the .gitignore file instead which would allow mounting the entire working directory and provide a seamless experience for non-Blubber devs.

Example: WVUI uses .gitignore file to exclude the node_modules/ directory, select dist/ files, and more. Similar, .prettierignore, .stylelintignore, .eslintignore, and forth files are maintained mostly by looking at the .gitignore. However, this list must be mentally inverted and kept in sync for Blubber and is something of trial by error: requirements: [dist/, src/, docs/, .webpack/, tsconfig.json, .postcssrc.json]. A better approach may be to mount all versioned files.

Event Timeline

I think that copies: [local] is really what you are hoping for @Niedzielski. The builder.requirements is really for doing things that only need a few files synced to reduce layer invalidation. If you have things in the repo that should never be added to a Docker container, adding a .dockerignore file to the repo would be the correct way to exclude them from the action that copies: [local] adds to the Blubber generated Dockerfile.

@bd808 I may have misunderstood the purpose of the builder attribute.
In the particular WVUI project @Niedzielski mentioned, the builder attribute in the build blubber variant builds the project with npm run build (maybe i should use the word build one more time hahah) The Dockerfile below is for that build variant, and executes (RUN npm "run" "build") right before it copies over all the project files.

...
RUN mkdir -p ".webpack/" "dist/" "docs/" "src/"
COPY --chown=65533:65533 ["tsconfig.json", ".postcssrc.json", "./"]
COPY --chown=65533:65533 [".webpack", ".webpack/"]
COPY --chown=65533:65533 ["dist", "dist/"]
COPY --chown=65533:65533 ["docs", "docs/"]
COPY --chown=65533:65533 ["src", "src/"]
RUN npm "run" "build"
COPY --chown=65533:65533 [".", "."]
USER "runuser"
ENV HOME="/home/runuser"
ENV NODE_ENV="development"

But if I remove the builder.requirements attribute RUN npm "run" "build" is executed before anything is copied over, so they aren't available. Am I understanding correctly/should we be putting our project build command in the builder attribute like that?

But if I remove the builder.requirements attribute RUN npm "run" "build" is executed before anything is copied over, so they aren't available. Am I understanding correctly/should we be putting our project build command in the builder attribute like that?

I'm learning too! I think I may have found the magic you need in the blubber file for blubber itself:

builder:
  command: [make, blubberoid]
  requirements: [.]

If I change the WVUI blubber.yaml to use this magic, it generates this Dockerfile:

FROM docker-registry.wikimedia.org/nodejs10-devel:0.0.3 AS build
USER "root"
ENV HOME="/root"
ENV DEBIAN_FRONTEND="noninteractive"
RUN apt-get update && apt-get install -y "git" "build-essential" "python-pkgconfig" && rm -rf /var/lib/apt/lists/*
RUN groupadd -o -g "65533" -r "somebody" && useradd -l -o -m -d "/home/somebody" -r -g "somebody" -u "65533" "somebody" && mkdir -p "/srv/service" && chown "65533":"65533" "/srv/service" && mkdir -p "/opt/lib" && chown "65533":"65533" "/opt/lib"
RUN groupadd -o -g "900" -r "runuser" && useradd -l -o -m -d "/home/runuser" -r -g "runuser" -u "900" "runuser"
USER "somebody"
ENV HOME="/home/somebody"
WORKDIR "/srv/service"
COPY --chown=65533:65533 ["package.json", "package-lock.json", "./"]
RUN npm ci
COPY --chown=65533:65533 [".", "./"]
RUN npm "run" "build"
USER "runuser"
ENV HOME="/home/runuser"
ENV NODE_ENV="development"

LABEL blubber.variant="build" blubber.version="0.8.0+5718d4d"

I had seen the [.] as an option for requirements! In the example you provided, node_modules would still be copied over, which I think is what @Niedzielski was hinting at in the ticket description for taking .gitignore into account,

I had seen the [.] as an option for requirements! In the example you provided, node_modules would still be copied over, which I think is what @Niedzielski was hinting at in the ticket description for taking .gitignore into account,

That is really the job of a .dockerignore file. When Blubber emits a Dockerfile instruction of COPY --chown=65533:65533 [".", "./"] that tells Docker to copy all of the files in the context that has been sent to the Docker daemon into the image. The context is sent at the very start of a docker build ... cli command. Any files or directories matching the patterns in a .dockerigore file are excluded from the context sent by the Docker CLI to the Docker daemon. This means that they are not present to be copied, and also that less data was sent in the context from the CLI to the daemon which should make things faster. If the Docker CLI had an option to read a .gitignore file rather than a .dockerignore file, that would be a reasonable option to expose in the Blubber config. Unfortunately, there is currently no such option. That is in part because the two files have different semantics.

That is in part because the two files have different semantics.

Ah! I didn't know the differences between how the two refer to files and dirs. For the purpose of the WVUI project, I'll add .dockerignore like you suggested, that would be cleaner than all of those files be listed out explicitly. Thanks @bd808 !

Change 636750 had a related patch set uploaded (by Nikki Nikkhoui; owner: Nikki Nikkhoui):
[wvui@add-dockerignore] Add .dockerignore

https://gerrit.wikimedia.org/r/636750

Change 636750 merged by jenkins-bot:
[wvui@add-dockerignore] Add .dockerignore

https://gerrit.wikimedia.org/r/636750

Change 643396 had a related patch set uploaded (by Nikki Nikkhoui; owner: Nikki Nikkhoui):
[wvui@master] Add .dockerignore...(again)

https://gerrit.wikimedia.org/r/643396

Change 643396 merged by jenkins-bot:
[wvui@master] Add .dockerignore...(again)

https://gerrit.wikimedia.org/r/643396

Sorry, @nnikkhoui, this task completely fell off my radar. :/ Thanks for helping out, @bd808!

Just to clarify the purpose of the requirements field under builder and in other sections, it is used to specific only a subset of files that are required for the builder.command (or successful completion of npm install in the case of node.requirements). That helps to create image layers that are more cacheable and in many cases will drastically reduce the duration of the overall image build. Doing requirements: [.] is sort of a last resort or when there just isn't much in the directory that isn't needed for the build—which is the case with blubber.

Also, if you do end up having to resort to using requirements: [.], you don't need the copies: [local]. You've already in effect copied the entirety of the project's directory into the image with the former.

Thanks @dduvall! I think ive gotten a nicely working solution, where i did end up using requirements [.] (as there was a pretty lengthy list of files needed for the builder.command so copying everything over seemed to make more sense) combined with a .dockerignore.

Closing this out since the original report asked for Blubber to read in .gitignore. However, Blubber(oid) is merely a stateless transpiler and cannot base its output off of the contents of project files.