在docker镜像中重复安装某个包

在docker镜像中重复安装某个包

我创建了一个名为 的 Python 包my-package。我无意将其公开,因此安装主要通过我们的内部服务器进行。最近,一位高级开发人员使用 docker 构建了一个架构,应用程序托管在其中并且my-package是依赖项。

问题是为了测试软件包,我需要反复将我的代码复制到 docker 镜像中,然后卸载旧版本的软件包并从本地代码重新安装。

  1. 重建整个图像需要半个小时。——没有选择。
  2. 从现有映像创建另一个 Dockerfile,并仅运行特定命令来复制和安装 pip 包。——我当前的解决方案还不是很有效。

我非常确定 docker 用户会遇到这个问题,因此需要专家意见来找到最有效的处理方法。

更新:Dockerfile

# VERSION 1.8.2
# AUTHOR: Matthieu "Puckel_" Roisil
# DESCRIPTION: Basic Airflow container
# BUILD: docker build --rm -t puckel/docker-airflow .
# SOURCE: https://github.com/puckel/docker-airflow

FROM ubuntu:17.10
MAINTAINER Puckel_

# Never prompts the user for choices on installation/configuration of packages
ENV DEBIAN_FRONTEND noninteractive
ENV TERM linux

# Airflow
ARG AIRFLOW_VERSION=1.8.9
ARG AIRFLOW_HOME=/usr/local/airflow

# Define en_US.
ENV LANGUAGE en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LC_ALL en_US.UTF-8
ENV LC_CTYPE en_US.UTF-8
ENV LC_MESSAGES en_US.UTF-8
ENV LC_ALL en_US.UTF-8

ENV MATPLOTLIBRC /etc

RUN set -ex \
    && buildDeps=' \
        python3.6-dev \
        libkrb5-dev \
        libsasl2-dev \
        libssl-dev \
        libffi-dev \
        build-essential \
        libblas-dev \
        liblapack-dev \
        libpq-dev \
        git \
        wget \
    ' \
    && apt-get update -yqq \
    && apt-get dist-upgrade -yqq \
    && apt-get install -yqq --no-install-recommends \
        $buildDeps \
        python3.6 \
        python3.6-tk \
        apt-utils \
        curl \
        netcat \
        locales \
        ca-certificates \
        sudo \
        libmysqlclient-dev \
    && ln -s /usr/bin/python3.6 /usr/bin/python \
    && sed -i 's/^# en_US.UTF-8 UTF-8$/en_US.UTF-8 UTF-8/g' /etc/locale.gen \
    && locale-gen \
    && update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 \
    && useradd -ms /bin/bash -d ${AIRFLOW_HOME} -u 1500 airflow \
    && mkdir ${AIRFLOW_HOME}/logs \
    && wget https://bootstrap.pypa.io/get-pip.py \
    && python get-pip.py \
    && rm -rf get-pip.py \
    && python -m pip install Cython \
    && python -m pip install requests \
    && python -m pip install pytz \
    && python -m pip install pyOpenSSL \
    && python -m pip install ndg-httpsclient \
    && python -m pip install pyasn1 \
    && python -m pip install Flask-OAuthlib \
    && python -m pip install apache-airflow[crypto,celery,postgres,ldap,jdbc,mysql,s3,samba]==$AIRFLOW_VERSION \
    && python -m pip install celery[redis]==4.1.0 \
    && python -m pip install boto3 \
    && python -m pip install pymongo \
    && python -m pip install statsd \   
    && apt-get remove --purge -yqq $buildDeps \
    && apt-get clean \
    && rm -rf \
        /var/lib/apt/lists/* \
        /tmp/* \
        /var/tmp/* \
        /usr/share/man \
        /usr/share/doc \
        /usr/share/doc-base \
    && apt-get autoremove -yqq

最重要的部分在最后。

ARG CACHEBUST=1

COPY config/matplotlibrc /etc/matplotlibrc
COPY script/entrypoint.sh /entrypoint.sh
COPY script/shell.sh /shell.sh
COPY config/airflow.cfg ${AIRFLOW_HOME}/airflow.cfg

RUN chown -R airflow: ${AIRFLOW_HOME}

RUN pip install matplotlib seaborn xlsxwriter pandas Jinja2
#Add custom PIP repo - THIS IS OF INTEREST
COPY config/pip.conf /etc/pip.conf 
RUN python -m pip install my-package

COPY my-package2 /usr/local/my-package2
# RUN pip uninstall my-package2
RUN python -m pip install /usr/local/my-package2

EXPOSE 8080 5555 8793

USER airflow
WORKDIR ${AIRFLOW_HOME}
ENTRYPOINT ["/entrypoint.sh"]

如您所见,我将 my-package2 从本地机器复制到映像并运行 pip install。

  1. 每次重建图像时,图像尺寸都会变得越来越大。
  2. Volumes 绝对是我还没有尝试过的选项。我已经使用script/shell.sh 了它$@。我将其设置为入口点,并运行我想要在图像中运行的任何命令,而无需太多争论。
  3. 我使用 docker-compose,因此每次使用新标签重建时,我也需要在 docker-compose 中更新。随着时间的推移,为代码中的一行更改而执行此操作会变得很烦人。

答案1

您需要分享一些 dockerfile,以便我们了解安装 pip 包为何需要这么长时间。如果您希望优化它,这些参考资料可能会有所帮助:

另一种解决方案是,不构建映像进行测试,而是仅通过 的 Docker 参数使用来自主机的包 -v /host/directory:/container/directory

这将允许您立即在容器的上下文中测试您的包,因此您仅在测试完成后才创建生产映像。

可以找到更多信息,例如: 了解 Docker 中的卷


从您发布的dockerfile来看,似乎几乎所有内容都用于安装依赖项。 为了进行测试,您可以创建一个已安装所有这些依赖项的映像,然后每次测试时只需重复安装应用程序的最后一步即可。

为了便于阅读,你最终可以将 dockerfile 编写为 多阶段,用于将依赖项构建与生产分离,也许还可以仅生成最终的最小生产构建。 ONBUILD 指令可能会有用。

只有您自己知道您要实现的目标以及您的限制是什么。上面的链接可以作为起点,还有更多关于此主题的文章。

相关内容