Docker: не игногируйте .dockerignore!

Sep 28, 2017 17:28 · 1104 words · 6 minute read docker

Мы уже знаем, как самостоятельно собирать docker-образы из Dockerfil’ов и даже использовали некоторые советы по оптимизации сборки и сжатию образов для уменьшения из размера.

Давайте разберемся как можно ускорить процесс сборки образа (docker build) используя возможности .dockerignore!

Как известно, команда docker build используется для сборки образа. При этом, демон докера (он же докер сервер) должен получить доступ к файлам, из которых вы хотите собрать docker-образ — эти файлы называются build context. Каждый раз, когда вы собираете docker-образ, докер клиент создает новый build context — выбирает файлы, упаковывает их в архив и отправляет докер серверу — иногда это может существенно замедлить процесс сборки.

Здесь нам на помощь приходит файл .dockerignore в нем следует перечислить те файлы и каталоги, которые докер клиент НЕ должен включать в build context. Рассмотрим простой пример на реальных данных — на одном из этапов CI (release) собирается docker-образ с исходниками проекта, подробности выглядят примерно так:

Running with gitlab-ci-multi-runner 9.4.1 (d24b11c)
  on docker-build-runner (9e68759f)
Using Docker executor with image registry.gitlab.lc:5000/develop/ed/tmaier-dc-ssh:latest ...
Starting service registry.gitlab.lc/develop/ed/my-docker-dind:latest ...
Using locally found image version due to if-not-present pull policy
Using docker image registry.gitlab.lc:5000/develop/ed/my-docker-dind:latest ID=sha256:4fc2ecb5eee45df2bbc62bf85a9b9b219e00000b567ceca088a52fe284d4af5a for registry.gitlab.lc/develop/ed/my-docker-dind service...
Waiting for services to be up and running...
Using docker image sha256:3c8a89cc10a14aacd93a1116894a757ff5eb4703dec960585e8c918d9ff37842 for predefined container...
Using locally found image version due to if-not-present pull policy
Using docker image registry.gitlab.lc:5000/develop/ed/tmaier-dc-ssh:latest ID=sha256:0e55c7b385f6ef8ac17c037757e12e5633939e2cc692cd277f4bd26109329dec for build container...
Running on runner-9e68759f-project-8-concurrent-0 via 8fff181d4a66...
Fetching changes...
Removing .env
Removing .happypack/
Removing bin/
Removing build/api.html
Removing node_modules/
Removing public/default_img/user/en/
Removing public/default_img/user/ru/
Removing public/dsd/css/style.css
Removing public/dsd/css/style.css.map
Removing public/dsd/js/bundles/
Removing public/dsd/js/templates.hbs.js
Removing public/dsd/js/templates.html.js
Removing public/dsd/js/utils/routes.js
Removing public/dsd/mix/tmp-pages-bundle/
Removing public/dsl/css/
Removing public/dsl/js/bundles/
Removing public/vendor/
Removing vendor/
HEAD is now at 97796d7 Merge branch 'feature/LK-9208' into 'develop'
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
Checking out 97796d7f as develop...
Skipping Git submodules setup
Downloading artifacts for compile (12377)...
Downloading artifacts from coordinator... ok        id=12377 responseStatus=200 OK token=8X6P3ZvN
$ docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
Login Succeeded
$ docker build --squash -t $CONTAINER_RELEASE_IMAGE -f Dockerfile . --build-arg BRANCH_NAME=$CI_COMMIT_REF_SLUG
Sending build context to Docker daemon 1.218 GB

Step 1/17 : FROM registry.gitlab.lc:5000/develop/ed/image_for_sources:latest
 ---> 474edb21752b
Step 2/17 : ARG BRANCH_NAME=
 ---> Using cache
 ---> 809c20ae2d32
Step 3/17 : COPY ./bin /var/www/${BRANCH_NAME}/bin
 ---> Using cache
 ---> a0fdc22aca28
Step 4/17 : COPY ./build /var/www/${BRANCH_NAME}/build
 ---> Using cache
 ---> e50ff2e943b6
Step 5/17 : COPY ./config /var/www/${BRANCH_NAME}/config
 ---> Using cache
 ---> 560d40a8c60f
Step 6/17 : COPY ./data /var/www/${BRANCH_NAME}/data
 ---> Using cache
 ---> 270f1b9414e9
Step 7/17 : COPY ./.env /var/www/${BRANCH_NAME}/
 ---> e6b0ab6f00dd
Removing intermediate container cfedaa7ecb32
Step 8/17 : COPY ./grunt /var/www/${BRANCH_NAME}/grunt
 ---> 3bdc90697c28
Removing intermediate container e2904e54ca89
Step 9/17 : COPY ./init_autoloader.php /var/www/${BRANCH_NAME}/
 ---> 12a1613946b1
Removing intermediate container cd75cf009923
Step 10/17 : COPY ./library /var/www/${BRANCH_NAME}/library
 ---> 03da42f301fb
Removing intermediate container c3bd9710a333
Step 11/17 : COPY ./module /var/www/${BRANCH_NAME}/module
 ---> 0d2a998bd7f7
Removing intermediate container 41b2daaa6867
Step 12/17 : COPY ./postcss.config.js /var/www/${BRANCH_NAME}/
 ---> 41d3655d27fc
Removing intermediate container 42d97659ae38
Step 13/17 : COPY ./public /var/www/${BRANCH_NAME}/public
 ---> 00e22429fa67
Removing intermediate container 99e5fc47584a
Step 14/17 : COPY ./vendor /var/www/${BRANCH_NAME}/vendor
 ---> b53abe6e7c00
Removing intermediate container fa43fea9d40c
Step 15/17 : COPY ./zf /var/www/${BRANCH_NAME}/
 ---> 5243ffcfe3e3
Removing intermediate container a90f952fa4f5
Step 16/17 : RUN ln -s /var/www/static /var/www/${BRANCH_NAME}/public/static
 ---> Running in 85b51a24b9bd
 ---> 9cfc2dee0789
Removing intermediate container 85b51a24b9bd
Step 17/17 : VOLUME /var/www/${BRANCH_NAME}
 ---> Running in 3051356d5cee
 ---> 167d4a415024
Removing intermediate container 3051356d5cee
Successfully built 42a801ee7c78
Successfully tagged registry.gitlab.lc:5000/develop/ed/develop.sources:latest
Running after script...
$ docker push $CONTAINER_RELEASE_IMAGE
The push refers to a repository [registry.gitlab.lc:5000/develop/ed/develop.sources]
d8efc7f9a927: Preparing
a80d3c8f9104: Preparing
c0de73ac9968: Preparing
c0de73ac9968: Layer already exists
a80d3c8f9104: Layer already exists
d8efc7f9a927: Pushed
latest: digest: sha256:4335cb03335cabbc20daa926db504bfba4427b6143af75a9a2a59a021cf8c3d2 size: 951
Job succeeded

Выполнение данной задачи занимает аж 2 минуты 47 секунд! Обратите внимание на размер build context:

...
Sending build context to Docker daemon 1.218 GB
...

Добавим рядом с нашим Dockerfil’ом новый файл .dockerignore следующего содержания:

.git/
node_modules/  
docker/

После добавления файла в репозиторий запустится процесс CI и на этот раз этап сборки образа (release) будет выглядеть так:

Running with gitlab-ci-multi-runner 9.4.1 (d24b11c)
  on docker-build-runner (9e68759f)
Using Docker executor with image registry.gitlab.lc:5000/develop/ed/tmaier-dc-ssh:latest ...
Starting service registry.gitlab.lc/develop/ed/my-docker-dind:latest ...
Using locally found image version due to if-not-present pull policy
Using docker image registry.gitlab.lc:5000/develop/ed/my-docker-dind:latest ID=sha256:4fc2ecb5eee45df2bbc62bf85a9b9b219e00000b567ceca088a52fe284d4af5a for registry.gitlab.lc/develop/ed/my-docker-dind service...
Waiting for services to be up and running...
Using docker image sha256:06e589298a2549f792a818c7178bd0a47cb2a52459898120ca24a9cb684db6be for predefined container...
Using locally found image version due to if-not-present pull policy
Using docker image registry.gitlab.lc:5000/develop/ed/tmaier-dc-ssh:latest ID=sha256:0e55c7b385f6ef8ac17c037757e12e5633939e2cc692cd277f4bd26109329dec for build container...
Running on runner-9e68759f-project-8-concurrent-0 via 8fff181d4a66...
Fetching changes...
Removing .env
Removing .happypack/
Removing bin/
Removing build/api.html
Removing node_modules/
Removing public/default_img/user/en/
Removing public/default_img/user/ru/
Removing public/dsd/css/style.css
Removing public/dsd/css/style.css.map
Removing public/dsd/js/bundles/
Removing public/dsd/js/templates.hbs.js
Removing public/dsd/js/templates.html.js
Removing public/dsd/js/utils/routes.js
Removing public/dsd/mix/tmp-pages-bundle/
Removing public/dsl/css/
Removing public/dsl/js/bundles/
Removing public/vendor/
Removing vendor/
HEAD is now at d605b86 Merge branch 'feature/LK-8867' into 'develop'
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
Checking out d605b860 as develop...
Skipping Git submodules setup
Downloading artifacts for compile (12613)...
Downloading artifacts from coordinator... ok        id=12613 responseStatus=200 OK token=pGzEsufR
$ docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
Login Succeeded
$ docker build --squash -t $CONTAINER_RELEASE_IMAGE -f Dockerfile . --build-arg BRANCH_NAME=$CI_COMMIT_REF_SLUG
Sending build context to Docker daemon 375.3 MB

Step 1/17 : FROM registry.gitlab.lc:5000/develop/ed/image_for_sources:latest
 ---> 474edb21752b
Step 2/17 : ARG BRANCH_NAME=
 ---> Using cache
 ---> 380966929365
Step 3/17 : COPY ./bin /var/www/${BRANCH_NAME}/bin
 ---> Using cache
 ---> 24b6698a0b8d
Step 4/17 : COPY ./build /var/www/${BRANCH_NAME}/build
 ---> Using cache
 ---> 14a4e8b360d0
Step 5/17 : COPY ./config /var/www/${BRANCH_NAME}/config
 ---> Using cache
 ---> 85095cd38a1a
Step 6/17 : COPY ./data /var/www/${BRANCH_NAME}/data
 ---> Using cache
 ---> ca0fbb56936b
Step 7/17 : COPY ./.env /var/www/${BRANCH_NAME}/
 ---> Using cache
 ---> cd496f338083
Step 8/17 : COPY ./grunt /var/www/${BRANCH_NAME}/grunt
 ---> Using cache
 ---> 6d31dd0eb62f
Step 9/17 : COPY ./init_autoloader.php /var/www/${BRANCH_NAME}/
 ---> Using cache
 ---> 8b6783bcee1a
Step 10/17 : COPY ./library /var/www/${BRANCH_NAME}/library
 ---> Using cache
 ---> 2168495f0846
Step 11/17 : COPY ./module /var/www/${BRANCH_NAME}/module
 ---> Using cache
 ---> 908cdf409686
Step 12/17 : COPY ./postcss.config.js /var/www/${BRANCH_NAME}/
 ---> Using cache
 ---> 3588286a22f8
Step 13/17 : COPY ./public /var/www/${BRANCH_NAME}/public
 ---> 89c9a9c6e4ce
Removing intermediate container 2b73385e0951
Step 14/17 : COPY ./vendor /var/www/${BRANCH_NAME}/vendor
 ---> 65f6757f330b
Removing intermediate container 4940c8409b28
Step 15/17 : COPY ./zf /var/www/${BRANCH_NAME}/
 ---> 0cfec4b9fa60
Removing intermediate container c73b48216a17
Step 16/17 : RUN ln -s /var/www/static /var/www/${BRANCH_NAME}/public/static
 ---> Running in c6e1aca6cab6
 ---> bc882a207a46
Removing intermediate container c6e1aca6cab6
Step 17/17 : VOLUME /var/www/${BRANCH_NAME}
 ---> Running in b4fc8d85a8df
 ---> 26de58f3e64d
Removing intermediate container b4fc8d85a8df
Successfully built e7a44d07ae3e
Successfully tagged registry.gitlab.lc:5000/develop/ed/develop.sources:latest
Running after script...
$ docker push $CONTAINER_RELEASE_IMAGE
The push refers to a repository [registry.gitlab.lc:5000/develop/ed/develop.sources]
f0a24a86880d: Preparing
a80d3c8f9104: Preparing
c0de73ac9968: Preparing
a80d3c8f9104: Layer already exists
c0de73ac9968: Layer already exists
f0a24a86880d: Pushed
latest: digest: sha256:f8f17362721885672fd0fc903505d2c2e71ac44a382533e1ab26684091447f63 size: 951
Job succeeded

Как видим, у нас изменился размер build context:

...
Sending build context to Docker daemon 375.3 MB
...

но самое главное, что docker-образ теперь собирается за 1 минуту 24 секунды — достойная оптимизация!

tweet Share