python - 带有 psycopg2 的 Light Alpline docker 容器

标签 python docker psycopg2 alpine-linux libpq

我有一些使用 Flask 运行 python 3.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"]

还有我的要求.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。
  • 删除升级 pip 语句。它不是工作必需的,但我想保持最新

我将尝试回答这些问题:

  • 首先如何安装psycopg2而不浪费那么多空间
  • 我应该应用于我的 dockerfile 的任何最佳实践,涉及容器空间的减少和安全性

最佳答案

减少 psycopg2 安装大小

我想做的第一件事是从容器中删除 postgresql-dev 并且仍然能够使用 psycopg2。唯一似乎丢失的文件是 libpq.so.5。该文件可在 alpine 软件包 libpq 中找到,可用 here

这样我们就可以构建 psycopg2 并且仍然节省它之前使用的几乎所有空间。

提高dockerfile的步骤效率

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

我还定义了一个更仔细编写的 .dockerignore 以节省更多空间。使用tree等工具可以帮助您找到容器中不需要的文件。

添加基本安全性

基于 this fine article ,我能够为我的容器指定一个无法修改容器的用户。

最终版本

这是我最终得到的 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 方面还是个新手,所以欢迎您提出任何建议或更改!

关于python - 带有 psycopg2 的 Light Alpline docker 容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65414891/

相关文章:

python - PySpark 以密集向量形式读入文本文件

linux - curl 语法错误 : append couchdb document failed with "conflict"?

python - 有没有一种方法可以使用 pip 安装 psycopg2 而无需在主机系统上安装 postgres

python - 获得锁后检查 multiprocessing.Value 的值

python - 在 Python 中上传文件内容

python - Twitter,错误 : urllib. 错误。HTTPError:HTTP 错误 401:未经授权

python-3.x - 在GeckoDriver中加载Firefox时权限被拒绝

mysql - Spring boot JDBC无法连接docker容器中的mysql

python - 从 DictRow 中删除一个项目

python - Flask-SQLAlchemy 引发 : AttributeError: module 'psycopg2' has no attribute 'paramstyle'