как объединить слои изображения Docker и уменьшить размер файла изображения - PullRequest
3 голосов
/ 13 мая 2019

docker image inspect <name> дает мне 16 ГБ

и около 20 слоев

Когда я вошел в систему как root, это du -hs / показывает мне только 2 ГБ

FYI, естьуже очень многострочные команды RUN в Dockerfile.

можно ли сжать все слои в один слой без касания Dockerfile, перестройки и т. д.?

или, возможно, добавив дополнительное действие кDockerfile, который очищает / улучшает кэширование

Dockerfile - это

FROM heroku/heroku:18

ENV PYENV_ROOT="/pyenv"
ENV PATH="/pyenv/shims:/pyenv/bin:$PATH"
ENV PYTHON_VERSION 3.5.6
ENV GPG_KEY <value>
ENV PYTHONUNBUFFERED 1
ENV TERM xterm
ENV EDITOR vim

RUN apt-get update && apt-get install -y \
    build-essential \
    gdal-bin \
    binutils \
    iputils-ping \
    libjpeg8 \
    libproj-dev \
    libjpeg8-dev \
    libtiff-dev \
    zlib1g-dev \
    libfreetype6-dev \
    liblcms2-dev \
    libxml2-dev \
    libxslt1-dev \
    libssl-dev \
    libncurses5-dev \
    virtualenv \
    python-pip \
    python3-pip \
    python-dev \
    libmysqlclient-dev \
    mysql-client-5.7 \
    libpq-dev \
    libcurl4-gnutls-dev \
    libgnutls28-dev \
    libbz2-dev \
    tig \
    git \
    vim \
    nano \
    tmux \
    tmuxinator \
    fish \
    sudo \
    libnet-ifconfig-wrapper-perl \
    ruby \
    libssl-dev \
    nodejs \
    strace \
    tcpdump \
    # npm & grunt
    && curl -L https://npmjs.com/install.sh | sh \
    && npm install -g grunt-cli grunt \
    # ruby & foreman
    && gem install foreman \
    # installing pyenv
    && curl https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash

COPY . /app
COPY ./requirements /requirements
COPY ./requirements.txt /requirements.txt
COPY ./docker/docker_compose/django/foreman.sh /foreman.sh
COPY ./docker/docker_compose/django/Procfile /Procfile
COPY ./docker/docker_compose/django/entrypoint.sh /entrypoint.sh

# ADD sudoer user django with password django
RUN groupadd -r django -g 1000 && \
    useradd -ms /usr/bin/fish -p $(openssl passwd -1 django) --uid 1000 --gid 1000 -r -g django django && \
    usermod -a -G sudo django && \
    chown -R django:django /app 

COPY --chown=django:django ./docker/docker_compose/django/fish /home/django/.config/fish
COPY --chown=django:django ./docker/docker_compose/django/tmuxinator /home/django/.tmuxinator
COPY ./docker/docker_compose/django/fish /root/.config/fish

WORKDIR /app

RUN sed -i 's/\r//' /entrypoint.sh \
    && sed -i 's/\r//' /foreman.sh \
    && chmod +x /entrypoint.sh \
    && chown django /entrypoint.sh \
    && chmod +x /foreman.sh \
    && chown django /foreman.sh \
    && chown -R django:django /home/django/ \
    && pyenv install ${PYTHON_VERSION%%} \
    && mkdir -p /app/log \
    && pyenv global ${PYTHON_VERSION%%} \
    && pyenv rehash \
    && ${PYENV_ROOT%%}/versions/${PYTHON_VERSION%%}/bin/pip install -U pip \
    && ${PYENV_ROOT%%}/versions/${PYTHON_VERSION%%}/bin/pip install -r /requirements.txt \
    && chown -R django:django /pyenv/ \
    && ${PYENV_ROOT%%}/versions/${PYTHON_VERSION%%}/bin/pip install -r /requirements/dev_requirements.txt

# this user receives ENVs from the top
USER django

ENTRYPOINT ["/entrypoint.sh"]

Что я пробовал до сих пор:

Опция --squash из экспериментального режимаdocker build скорее не для меня.Этот Dockerfile является одним из нескольких Dockerfile в docker-compose.

Я также проверил это: https://github.com/jwilder/docker-squash

, но, похоже, загрузка Docker не может загрузить сжатое изображение.Кроме того, этот сквош дает мне 8 ГБ (все еще далеко от ожидаемого ~ 2 ГБ)

docker save <image_id> | docker-squash -t latest_tiny | docker load

обновление после ответов:

, когда я добавил это:

&& apt-get autoremove \             # ? to consider
&& apt-get clean \                  # ? to consider
&& rm -rf /var/lib/apt/lists/*

до apt-get и --no-cache-dir для каждого пункта, результат составил 72 ГБ (да, даже намного больше - docker images показывает 36 ГБ перед командой pip и 72 ГБ в качестве окончательного размера).

мой рабочий каталог свободен (относительно COPY).du -hs / (как корень) еще 2 ГБИ все изображения были удалены перед перестройкой.

Следуя подходу @Mihai, я смог уменьшить изображение с 16 ГБ до 9 ГБ.

Ответы [ 2 ]

2 голосов
/ 13 мая 2019

Есть простой трюк, чтобы избавиться от промежуточных слоев.Он также уменьшит размер, но от того, насколько он зависит, зависит от того, как он был построен.

Создайте Dockerfile примерно так:

FROM your_image as initial

FROM your_image_base

COPY --from=initial / /

your_image_base должно быть что-то вроде 'alpine'- поэтому самое маленькое изображение, с которого происходит ваше изображение и его родители.

Теперь создайте изображение и проверьте историю и размер:

docker build -t your-image:2.0 .
docker image history your-image:2.0
docker image ls

Таким образом, вы создаете новый файл Dockerfile (если это приемлемо для вашего процесса), не касаясь исходного файла Docker.

Дайте мне знать, если это решит вашу проблему.

ОБНОВЛЕНИЕ ПОСЛЕ ПРОСМОТРА Dockfile:

возможно, я скучаюно я не вижу, чтобы вы очищали кэш apt-get после выполнения установок.Ваша большая команда RUN должна заканчиваться на «&& rm -rf / var / lib / apt / lists / *» в той же строке, чтобы она не сохраняла весь кэш на слое.

0 голосов
/ 14 мая 2019

Определенно добавьте && rm -rf /var/lib/apt/lists/* в конце команды основного запуска, как сказал Михай.Другая вещь, которая может помочь (в зависимости от того, насколько велики ваши зависимости), это установка с помощью pip с опцией --no-cache-dir.Кроме того, убедитесь, что вы понимаете сборочный контекст и рассмотрите возможность использования .dockerignore или отправки контекста в другой каталог (полностью зависит от того, как настроен ваш каталог)

Я такжеповезло, исследуя изображение, используя погружение .Честно говоря, это выглядит как довольно большое изображение, так что не уверен, сколько вы сможете его снять

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...