![在docker镜像中重复安装某个包](https://linux22.com/image/1548005/%E5%9C%A8docker%E9%95%9C%E5%83%8F%E4%B8%AD%E9%87%8D%E5%A4%8D%E5%AE%89%E8%A3%85%E6%9F%90%E4%B8%AA%E5%8C%85.png)
我创建了一个名为 的 Python 包my-package
。我无意将其公开,因此安装主要通过我们的内部服务器进行。最近,一位高级开发人员使用 docker 构建了一个架构,应用程序托管在其中并且my-package
是依赖项。
问题是为了测试软件包,我需要反复将我的代码复制到 docker 镜像中,然后卸载旧版本的软件包并从本地代码重新安装。
- 重建整个图像需要半个小时。——没有选择。
- 从现有映像创建另一个 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。
- 每次重建图像时,图像尺寸都会变得越来越大。
- Volumes 绝对是我还没有尝试过的选项。我已经使用
script/shell.sh
了它$@
。我将其设置为入口点,并运行我想要在图像中运行的任何命令,而无需太多争论。 - 我使用 docker-compose,因此每次使用新标签重建时,我也需要在 docker-compose 中更新。随着时间的推移,为代码中的一行更改而执行此操作会变得很烦人。
答案1
您需要分享一些 dockerfile,以便我们了解安装 pip 包为何需要这么长时间。如果您希望优化它,这些参考资料可能会有所帮助:
另一种解决方案是,不构建映像进行测试,而是仅通过 的 Docker 参数使用来自主机的包
-v /host/directory:/container/directory
。
这将允许您立即在容器的上下文中测试您的包,因此您仅在测试完成后才创建生产映像。
可以找到更多信息,例如: 了解 Docker 中的卷。
从您发布的dockerfile来看,似乎几乎所有内容都用于安装依赖项。 为了进行测试,您可以创建一个已安装所有这些依赖项的映像,然后每次测试时只需重复安装应用程序的最后一步即可。
为了便于阅读,你最终可以将 dockerfile 编写为 多阶段,用于将依赖项构建与生产分离,也许还可以仅生成最终的最小生产构建。 ONBUILD 指令可能会有用。
只有您自己知道您要实现的目标以及您的限制是什么。上面的链接可以作为起点,还有更多关于此主题的文章。