首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何合并Docker的图像层并精简图像文件

如何合并Docker的图像层并精简图像文件
EN

Stack Overflow用户
提问于 2019-05-14 01:32:22
回答 2查看 4.5K关注 0票数 4

docker image inspect <name>为我提供了16 me

和大约20层

当我以超级用户身份登录时,此du -hs /仅显示2 2GB

仅供参考,Dockerfile中已经有非常多行的RUN命令。

我可以在不接触Dockerfile文件、重建等的情况下将所有图层压缩到一个图层中吗?

或者可能通过向Dockerfile添加额外的操作来清除/改进缓存

Dockerfile

代码语言:javascript
复制
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"]

到目前为止,我已经尝试了:

docker build的实验模式下的--squash选项不适合我。该Dockerfile是docker-compose中的更多Dockerfile之一。

我还检查过这个:https://github.com/jwilder/docker-squash

但是看起来docker load不能加载一个压缩的图像。另外,那个压缩包给了我8 8GB (仍然离预期的2 8GB还差很远)

代码语言:javascript
复制
docker save <image_id> | docker-squash -t latest_tiny | docker load

回答后的更新:

当我添加以下内容时:

代码语言:javascript
复制
&& apt-get autoremove \             # ? to consider
&& apt-get clean \                  # ? to consider
&& rm -rf /var/lib/apt/lists/*

对每个pip执行apt-get--no-cache-dir命令,结果是72 as (是的,甚至更多- docker imagespip命令之前显示36 as,最终大小为72 as)。

我的工作目录是清晰的(关于COPY)。du -hs / (作为根)仍然有2 2GB。在重建之前所有的图像都被移除了。

遵循@Mihai的方法,我能够将图像从16 9GB精简到9 9GB。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-14 03:12:08

有一个简单的技巧可以摆脱中间层。它也会缩小尺寸,但大小取决于它是如何构建的。

创建Dockerfile,如下所示:

代码语言:javascript
复制
FROM your_image as initial

FROM your_image_base

COPY --from=initial / /

your_image_base应该类似于“高山”--所以你的图像和它的父母从最小的图像派生出来。

现在构建镜像并检查历史和大小:

代码语言:javascript
复制
docker build -t your-image:2.0 .
docker image history your-image:2.0
docker image ls

这样,您就可以在不接触初始Dockerfile的情况下创建一个新的Dockerfile (如果您的进程可以接受的话)。

如果这解决了你的问题,请告诉我。

在看到Dockerfile后更新:

也许我错过了它,但我没有看到您在执行安装后清理apt-get缓存。您的大运行命令应该在同一行上以"&& rm -rf /var/lib/apt/list/*“结束,这样它就不会在层上存储整个缓存。

票数 6
EN

Stack Overflow用户

发布于 2019-05-14 10:18:47

一定要像米海说的那样,在主运行命令的末尾添加&& rm -rf /var/lib/apt/lists/*。另一件可能有用的事情(取决于您的依赖项有多大)是使用--no-cache-dir选项通过pip进行安装。此外,确保您理解build context,并考虑使用.dockerignore或将上下文发送到另一个目录(完全取决于您的目录是如何设置的)

我还有幸使用dive探索过一幅图像。老实说,这看起来像是一张很大的图片,所以不确定你能把它写下来多少

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56117261

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档