Что делать, если ваш файл Dockerfile становится настолько большим, что его невозможно поддерживать
Когда размер Dockerfile превышает разумный предел, возникает несколько проблем:
- Его сложно понять и поддерживать - нам нужно прочитать сотни строк, чтобы понять все зависимости.
- Между столькими строками можно упустить явную проблему безопасности.
- Git вызовет больше конфликтов, поскольку все меняют один и тот же файл
- Если мы не очистим каждую зависимость, это может привести к тяжелому изображению
Лучшее решение - разделить наш Dockerfile на несколько Dockerfiles, чтобы наши Dockerfile были меньше по размеру и их было легче понять и поддерживать.
Вот несколько советов по уменьшению размера вашего Dockerfile.
Рефакторинг 1: извлечение зависимости из официального образа
Избегайте создания артефактов, скопированных с официального изображения.
Пример
Оригинал:
FROM golang:1.12 RUN apt-get update && \ apt-get upgrade -y && \ apt-get install -y git openssh-client zip WORKDIR $GOPATH/src/github.com/hashicorp/terraform RUN git clone https://github.com/hashicorp/terraform.git ./ && \ git checkout v0.12.9 && \ ./scripts/build.sh WORKDIR /my-config COPY . /my-config/ CMD ["terraform init"]
Рефакторинг:
FROM hashicorp/terraform:0.12.9 AS terraform FROM golang:1.12 COPY --from=terraform /go/bin/terraform /usr/bin/terraform WORKDIR /my-config COPY . /my-config/ CMD ["terraform init"]
Рефакторинг 2: извлечение зависимости в другой док-файл
Когда нет официального образа, из которого можно извлечь артефакт, вам следует отделить его сборку в другом Dockefile.
Затем скопируйте артефакты в исходный файл Dockerfile.
Пример
Оригинал:
FROM golang:1.12 RUN apt-get update && \ apt-get upgrade -y && \ apt-get install -y git openssh-client WORKDIR /go/src/gitlab.com/sahilm/ RUN git clone https://github.com/sahilm/yamldiff.git RUN cd yamldiff && \ go get -u github.com/golang/dep/cmd/dep && \ dep ensure && \ GOOS=linux go build -o /usr/local/yamldiff WORKDIR /my-app COPY . /my-app/ CMD ["./run.sh"]
Рефакторинг:
Dockerfile для yamldiff
:
FROM golang:1.12 RUN apt-get update && \ apt-get upgrade -y && \ apt-get install -y git openssh-client WORKDIR /go/src/gitlab.com/sahilm/ RUN git clone https://github.com/sahilm/yamldiff.git RUN cd yamldiff && \ go get -u github.com/golang/dep/cmd/dep && \ dep ensure && \ GOOS=linux go build -o /usr/local/yamldiff CMD ["bash"]
Dockerfile для моего приложения:
FROM Marvalero/yamldiff:latest AS yamldiff FROM golang:1.12 COPY --from=yamldiff /usr/bin/yamldiff /usr/bin/yamldiff WORKDIR /my-app COPY . /my-app/ CMD ["./run.sh"]
Рефакторинг 3: разделите изображение на этапы
Docker имеет многоступенчатую функцию, которая пригодится, когда ваш Dockerfile состоит из разных частей.
Наиболее распространенный вариант использования - выполнить этап сборки и затем скопировать артефакты в основное изображение. Наличие разных этапов делает ваш Dockerfile более понятным и безопасным.
Пример
Оригинал:
FROM golang:1.12 RUN apt-get update && \ apt-get upgrade -y && \ apt-get install -y git openssh-client WORKDIR /go/src/gitlab.com/sahilm/ RUN git clone https://github.com/sahilm/yamldiff.git RUN cd yamldiff && \ go get -u github.com/golang/dep/cmd/dep && \ dep ensure && \ GOOS=linux go build -o /usr/local/yamldiff CMD ["bash"]
Рефакторинг:
FROM golang:1.12 as Builder RUN apt-get update && \ apt-get upgrade -y && \ apt-get install -y git openssh-client WORKDIR /go/src/gitlab.com/sahilm/ RUN git clone https://github.com/sahilm/yamldiff.git RUN cd yamldiff && \ go get -u github.com/golang/dep/cmd/dep && \ dep ensure && \ GOOS=linux go build -o /usr/local/yamldiff FROM ubuntu:18.04 COPY --from=Builder /usr/local/yamldiff /usr/local/yamldiff CMD ["bash"]
Рефакторинг 4: сортировка многострочных аргументов
По возможности отсортируйте многострочные аргументы. Это помогает еще раз проверить, не дублируется ли пакет.
Пример
Оригинал:
FROM ubuntu:18.04 RUN apt-get -yqq install \ ca-certificates \ bash \ jq \ wget \ curl \ openssh-client \ build-essential \ libpng-dev \ python \ zip CDM ["bash"]
Рефакторинг:
FROM ubuntu:18.04 RUN apt-get -yqq install \ bash \ build-essential \ ca-certificates \ curl \ jq \ libpng-dev \ openssh-client \ python \ wget \ zip CDM ["bash"]
Рефакторинг 5: Теги
Поддержание чистоты ваших тегов также важно при работе с образами Docker. Я всегда считаю очень полезным иметь три типа тегов:
- Название ветки: определяет последнюю версию моего изображения для конкретной ветки.
Примечание. Почему бы не использовать latest
? При использовании latest
я никогда не знаю, означает ли это последнюю стабильную версию или последнюю сборку во всем репозитории. Использование имен веток (например, master
, feature/new-class
и т. Д.), Указывающих на последнюю версию ветки, является более интуитивным.
- Версия: требуется, чтобы отличать исправления от критических изменений. Я рекомендую использовать семантическое управление версиями (
major.minor.patch
). - Фиксация: я всегда хочу знать, на какую фиксацию указывает тег. Теперь вы можете сделать это, создав теги версий в своем репозитории. Но когда это невозможно, просто пометьте свои изображения его Commit SHA.
Наслаждайтесь красивыми файлами Docker
Спасибо за прочтение. Надеюсь, вам станет проще поддерживать файлы Dockerfiles.
Если вы хотите узнать больше о Docker и контейнерах, вы можете ознакомиться с двумя моими предыдущими статьями: