Python 带psycopg2的轻型Alpline docker集装箱

Python 带psycopg2的轻型Alpline docker集装箱,python,docker,psycopg2,alpine,libpq,Python,Docker,Psycopg2,Alpine,Libpq,我有一些使用flask运行Python3.7的服务,只需要几个额外的库。其中之一是psycopg2,它能够连接到postgres 就其本身而言,在alpine中安装psycopg2并不是一项非常困难的任务,但我在查找有关该问题的文档时遇到了一些问题。我设法得到了这个运行正常的dockerfile。最大的缺点是它大约有355MB,而且太重了 这是我在进行任何优化之前的初始dockerfile: FROM python:3.7-alpine ENV PATH /usr/local/bin:$PAT

我有一些使用flask运行Python3.7的服务,只需要几个额外的库。其中之一是psycopg2,它能够连接到postgres

就其本身而言,在alpine中安装psycopg2并不是一项非常困难的任务,但我在查找有关该问题的文档时遇到了一些问题。我设法得到了这个运行正常的dockerfile。最大的缺点是它大约有355MB,而且太重了

这是我在进行任何优化之前的初始dockerfile:

FROM python:3.7-alpine

ENV PATH /usr/local/bin:$PATH

ENV LANG C.UTF-8

RUN mkdir -p /usr/src/app

COPY requirements.txt /usr/src/app/

RUN apk update \
    && apk add postgresql-dev \
    && apk add --virtual temp1 gcc python3-dev musl-dev \
    && pip install --upgrade pip \
    && pip install psycopg2==2.8.4

RUN pip install -r /usr/src/app/requirements.txt

RUN apk del temp1

COPY . /usr/src/app

WORKDIR /usr/src/app

EXPOSE 6000

ENTRYPOINT ["python3"]

CMD ["-m", "server"]

和my requirements.txt

psycopg2 == 2.8.4
connexion == 1.1.15
python_dateutil == 2.6.0
loguru~=0.4.1
flask~=1.1.2
six~=1.14.0
Werkzeug==0.16.1
pymongo
PyYAML == 5.3
setuptools == 45.1.0
flask_testing == 0.7.1
mo-future>=3
pyparsing==2.3.1
mo_files
pycryptodomex
ldap3
通过一些测试,我发现最大程度地增加图像大小的步骤是:

  • 安装psycopg2和postgresql dev:220MB仅由这两个版本使用
  • 安装要求:高达60MB
  • 升级pip:向最终映像添加15MB
我试着缩小它的尺寸:

  • 作为构建依赖项安装postgresql dev,并在构建psycopg2后将其从映像中删除。删除postgresql dev会引发一个错误,其中找不到文件libpq.so.5
  • 正在删除upgrade pip语句。它不需要工作,但我想让它保持最新
我将尝试回答以下问题:

  • 首先,如何在不浪费太多空间的情况下安装psycopg2
  • 关于减少空间和容器安全性,我应该将任何最佳实践应用于dockerfile
减小psycopg2安装尺寸 我想做的第一件事是从容器中删除postgresql dev,并且仍然能够使用psycopg2。唯一似乎丢失的文件是libpq.so.5。此文件在alpine软件包libpq中提供

通过这种方式,我们可以构建psycopg2,并且仍然可以节省以前使用的几乎所有空间

提高dockerfile的步骤效率 我尝试最小化dockerfile中的步骤数,以便最终图像更轻。向pip和apk添加适当的标志可以减少用于缓存的空间量。另外,声明一个用于对所有构建依赖项进行分组的变量可以使事情变得更清晰

此外,我还定义了一个更仔细编写的.dockrignore,以节省更多空间。使用tree之类的工具可以帮助您在容器中查找不必要的文件

增加基本安全性 基于,我能够为我的容器指定一个无法修改容器的用户

最终版本 这就是我最后得到的dockerfile文件。它从355MB下降到135MB,这并不完全完美,但要好得多

FROM python:3.7-alpine

ENV PATH /usr/local/bin:$PATH
ENV LANG C.UTF-8
ENV USER=prodUser UID=12345 GID=23456

RUN mkdir -p /usr/src/app

COPY requirements.txt /usr/src/app/

RUN buildDeps='gcc python3-dev musl-dev postgresql-dev' \
    && apk update \
    && apk add --no-cache libpq \
    && apk add --virtual temp1 --no-cache $buildDeps \
    && pip install --no-cache-dir -r /usr/src/app/requirements.txt \
    && apk del temp1

COPY . /usr/src/app

WORKDIR /usr/src/app

RUN addgroup --gid "$GID" "$USER" \
  && adduser \
  --disabled-password \
  --gecos "" \
  --ingroup "$USER" \
  --uid "$UID" \
  "$USER"
USER $USER

EXPOSE 6000

ENTRYPOINT ["python3"]

CMD ["-m", "server"]
下一步
  • 正如前面提到的文章所建议的,我将为生产目的对gunicorn和gnix进行一些研究
  • 我将对requirements.txt文件安装的推荐软件包进行一些测试,并尝试删除我不需要的软件包
  • 我可以尝试进一步减少dockerfile中定义的步骤数
最后说明
我对docker的工作还是新手,所以欢迎您提出任何建议或更改

不应该特别需要修复用户和组ID;只需让
adduser
选择默认值即可。
ENTRYPOINT
CMD
的这种分割没有真正意义,我可能会把所有东西都放进
CMD
,而没有
ENTRYPOINT