Docker 图片大小 > 1GB 来自 python:3.8.3-alpine
Docker Image > 1GB in size from python:3.8.3-alpine
我是 docker 的新手,虽然我已经阅读了很多文章、教程并观看了 YouTube 视频,但我仍然发现我的图像大小超过 1 GB 时Python 的高山图像只有大约 25 MB(如果我没看错的话!)。
我正在想办法让它变小(如果确实需要的话)。
[注意:我一直在按照教程创建下面的内容。大部分是有道理的..但有些感觉像巫术]
这是我的 Dockerfile:
FROM python:3.8.3-alpine
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN mkdir -p /home/app
RUN addgroup -S app && adduser -S app -G app
ENV HOME=/home/app
ENV APP_HOME=/home/app/web
RUN mkdir $APP_HOME
RUN mkdir $APP_HOME/staticfiles
RUN mkdir $APP_HOME/mediafiles
WORKDIR $APP_HOME
RUN pip install --upgrade pip
COPY requirements.txt .
RUN apk update \
&& apk add --virtual build-deps gcc python3-dev musl-dev \
&& apk add postgresql-dev \
&& apk add jpeg-dev zlib-dev libjpeg \
&& apk add --update --no-cache postgresql-client
RUN pip install -r requirements.txt
RUN apk del build-deps
COPY entrypoint.prod.sh $APP_HOME
COPY . $APP_HOME
RUN chown -R app:app $APP_HOME
USER app
ENTRYPOINT ["/home/app/web/entrypoint.prod.sh"]
使用 Pillow
和 psycopg2-binary
造成了世界的混乱和伤害。特别是以下内容:
RUN apk update \
&& apk add --virtual build-deps gcc python3-dev musl-dev \
&& apk add postgresql-dev \
&& apk add jpeg-dev zlib-dev libjpeg \
&& apk add --update --no-cache postgresql-client
RUN pip install -r requirements.txt
RUN apk del build-deps
这原本是:
RUN apk update \
&& apk add --virtual build-deps gcc python3-dev musl-dev \
&& apk add postgresql \
&& apk add postgresql-dev \
&& apk add --update --no-cache postgresql-client \
&& pip install psycopg2-binary \
&& apk add jpeg-dev zlib-dev libjpeg \
&& pip install Pillow \
&& apk del build-deps
我真的不知道我需要多少以上才能让它发挥作用。我认为可能有一种减少构建的方法。
我知道有一种方法可以构建原始图像,然后使用它来传输内容,但唯一的教程令人困惑,我正在努力解决这个问题而不增加更多的复杂性。我真希望有人能亲自解释一下。
我也不知道图像的大小是否来自 requirements.txt
文件。我正在使用 django 并且有一些要求:
requirements.txt
asgiref==3.4.1
Babel==2.9.1
boto3==1.18.12
botocore==1.21.12
certifi==2021.5.30
charset-normalizer==2.0.4
crispy-bootstrap5==0.4
defusedxml==0.7.1
diff-match-patch==20200713
Django==3.2.5
django-anymail==8.4
django-compat==1.0.15
django-crispy-forms==1.12.0
django-environ==0.4.5
django-extensions==3.1.3
django-hijack==2.3.0
django-hijack-admin==2.1.10
django-import-export==2.5.0
django-money==2.0.1
django-recaptcha==2.0.6
django-social-share==2.2.1
django-storages==1.11.1
et-xmlfile==1.1.0
fontawesomefree==5.15.3
gunicorn==20.1.0
idna==3.2
jmespath==0.10.0
MarkupPy==1.14
odfpy==1.4.1
openpyxl==3.0.7
Pillow==8.3.1
psycopg2-binary==2.9.1
py-moneyed==1.2
python-dateutil==2.8.2
pytz==2021.1
PyYAML==5.4.1
requests==2.26.0
s3transfer==0.5.0
six==1.16.0
sqlparse==0.4.1
stripe==2.60.0
tablib==3.0.0
urllib3==1.26.6
xlrd==2.0.1
xlwt==1.3.0
我的问题是,如何使图像变小。它需要更小吗?
我只是想找到将 Django 应用程序部署到 Digitalocean 的最佳方法,并且有很多方法和教程等令人困惑。我不知道它是否使它更容易使用 docker。我只使用他们的应用程序平台吗?那会提供SSL吗?使用 docker 等有什么好处?
docker-编写文件(供参考)
version: '3.7'
services:
web:
build:
context: .
dockerfile: Dockerfile.prod
command: gunicorn maffsguru.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
expose:
- 8000
env_file:
- .env.docker
depends_on:
- db
db:
image: postgres:12.0-alpine
env_file:
- .env.docker
volumes:
- postgres_data:/var/lib/postgresql/data/
ports:
- 5432:5432
nginx:
build: ./nginx
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
ports:
- 1337:80
depends_on:
- web
volumes:
postgres_data:
static_volume:
media_volume:
只是说...以上所有似乎都有效...但我不知道图像大小等是否会成为问题?
我也很困惑为什么 Nginx 似乎需要我做 http://0.0.0.0:1337 to view the site. Isn't the whole point to view it by navigating to http://0.0.0.0/
感谢您提供的任何建议或指导,对于我的问题的随机性表示歉意
欢迎来到Docker!全神贯注是一件很重要的事情,尤其是在开始的时候,但你问的是真正有效的问题,而且都是相关的
缩小尺寸
如何
一个很好的起点是 Docker 自己的 Docker 文件最佳实践页面:
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
他们清楚地解释了您的每个指令(COPY
、RUN
、ENV
等)如何创建额外的层,从而增加容器的大小。重要的是,它们展示了如何通过最小化不同的指令来减小图像大小。大量最小化的关键是使用 &&
.
在 RUN
语句中链接命令
我在您的 Docker 文件中注意到的其他内容是一个特定的行:
COPY . $APP_HOME
现在,根据您构建容器的方式(具体来说,您传递给 Docker 的文件夹作为上下文),这将复制 EVERYTHING 因为它有可用。很有可能,这将带入您的 venv
文件夹等,如果您有的话。我觉得这对你来说可能是规模最大的罪魁祸首。您可以通过在文件中添加明确的 COPY
或使用 .dockerignore
文件来缓解这种情况。
我构建了你的图像(没有任何源代码,也没有在 entrypoint.sh
中复制),它以 710MB 作为基础。检查源代码的大小并查看是否有其他内容进入其中可能是个好主意。
在我重新安排一些命令以重用指令后,图像为 484MB,小得多!
如果您遇到困难,我可以将它放入 Github 上的要点中并引导您完成它,但是,Docker 文档应该可以帮助您前进
为什么?
嗯,较大的应用程序/图像本身并不坏,但随着数据的增加,某些操作可能会变慢。
当我说操作时,我倾向于指从注册表中提取图像,或将它们推送到发布。传输 1GB 比传输 50MB 需要更长的时间。
扩展容器时还需要考虑一个因素。虽然图像大小不一定与启动容器时将使用多少磁盘直接相关,但它肯定会增加对你正在使用的机器的要求 运行,并限制其他人使用较小的设备
Docker
使用 Docker 的优点是广泛的,如果不提交我的论文答辩,我不能在这里涵盖所有这些 ;-)
但主要归结为以下几点:
- 许多提供商支持 运行在 docker
中安装您的应用程序
- Docker文件可帮助您在一致的环境中构建您的应用程序,这意味着您不必配置应用程序 运行 所在的每个主机,也不必担心版本冲突
- 容器让您可以在一致(且相同)的环境中开发和 运行 您的应用程序
- 容器通常提供非常好的网络功能。你会遇到的一个例子是 docker compose,你可以简单地通过它们的主机名
访问其他容器
Nginx
据我所知,你在那里设置得很好!我想 nginx 是 'telling you'(通过日志?)导航到 0.0.0.0
,因为那是它将绑定到容器 中的内容 。现在,您已经转发了来自 1337:80
的流量。 Docker 遵循 host:container
的格式,因此这意味着 localhost:1337
上的流量将被定向到容器端口 80
。
您可能需要根据您的 nginx 配置来交换它,但请放心,一旦一切设置完成,您将能够在浏览器中导航到本地主机并查看您的网站
如果您在上述任何方面需要帮助,或者需要更多资源来帮助您,请告诉我。鉴于我们似乎处于同一时区,很高兴随时与您通信并引导您完成任何事情
请注意,您必须安装一个编译器。该编译器需要大量 space.
大多数 Python 包都包含 pre-compiled 二进制包,那你为什么需要编译器?因为你用的是高山。来自 PyPI 的二进制包 (==wheels) 在 Alpine 上不起作用。
所以:
- 从 Alpine 基础映像切换到例如
python:3.8-slim-buster
.
- 摆脱编译器安装,headers,等等,你可能不需要任何东西。
- 享受您新的快速构建,以及很可能更小的图像。
详情:https://pythonspeed.com/articles/alpine-docker-python/
替代方案是 multi-stage 构建,其中您的最终映像不包含不必要的编译器。这当然会增加更多的复杂性。
起点(这是 3 篇文章系列):https://pythonspeed.com/articles/smaller-python-docker-images/
我是 docker 的新手,虽然我已经阅读了很多文章、教程并观看了 YouTube 视频,但我仍然发现我的图像大小超过 1 GB 时Python 的高山图像只有大约 25 MB(如果我没看错的话!)。
我正在想办法让它变小(如果确实需要的话)。
[注意:我一直在按照教程创建下面的内容。大部分是有道理的..但有些感觉像巫术]
这是我的 Dockerfile:
FROM python:3.8.3-alpine
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN mkdir -p /home/app
RUN addgroup -S app && adduser -S app -G app
ENV HOME=/home/app
ENV APP_HOME=/home/app/web
RUN mkdir $APP_HOME
RUN mkdir $APP_HOME/staticfiles
RUN mkdir $APP_HOME/mediafiles
WORKDIR $APP_HOME
RUN pip install --upgrade pip
COPY requirements.txt .
RUN apk update \
&& apk add --virtual build-deps gcc python3-dev musl-dev \
&& apk add postgresql-dev \
&& apk add jpeg-dev zlib-dev libjpeg \
&& apk add --update --no-cache postgresql-client
RUN pip install -r requirements.txt
RUN apk del build-deps
COPY entrypoint.prod.sh $APP_HOME
COPY . $APP_HOME
RUN chown -R app:app $APP_HOME
USER app
ENTRYPOINT ["/home/app/web/entrypoint.prod.sh"]
使用 Pillow
和 psycopg2-binary
造成了世界的混乱和伤害。特别是以下内容:
RUN apk update \
&& apk add --virtual build-deps gcc python3-dev musl-dev \
&& apk add postgresql-dev \
&& apk add jpeg-dev zlib-dev libjpeg \
&& apk add --update --no-cache postgresql-client
RUN pip install -r requirements.txt
RUN apk del build-deps
这原本是:
RUN apk update \
&& apk add --virtual build-deps gcc python3-dev musl-dev \
&& apk add postgresql \
&& apk add postgresql-dev \
&& apk add --update --no-cache postgresql-client \
&& pip install psycopg2-binary \
&& apk add jpeg-dev zlib-dev libjpeg \
&& pip install Pillow \
&& apk del build-deps
我真的不知道我需要多少以上才能让它发挥作用。我认为可能有一种减少构建的方法。
我知道有一种方法可以构建原始图像,然后使用它来传输内容,但唯一的教程令人困惑,我正在努力解决这个问题而不增加更多的复杂性。我真希望有人能亲自解释一下。
我也不知道图像的大小是否来自 requirements.txt
文件。我正在使用 django 并且有一些要求:
requirements.txt
asgiref==3.4.1
Babel==2.9.1
boto3==1.18.12
botocore==1.21.12
certifi==2021.5.30
charset-normalizer==2.0.4
crispy-bootstrap5==0.4
defusedxml==0.7.1
diff-match-patch==20200713
Django==3.2.5
django-anymail==8.4
django-compat==1.0.15
django-crispy-forms==1.12.0
django-environ==0.4.5
django-extensions==3.1.3
django-hijack==2.3.0
django-hijack-admin==2.1.10
django-import-export==2.5.0
django-money==2.0.1
django-recaptcha==2.0.6
django-social-share==2.2.1
django-storages==1.11.1
et-xmlfile==1.1.0
fontawesomefree==5.15.3
gunicorn==20.1.0
idna==3.2
jmespath==0.10.0
MarkupPy==1.14
odfpy==1.4.1
openpyxl==3.0.7
Pillow==8.3.1
psycopg2-binary==2.9.1
py-moneyed==1.2
python-dateutil==2.8.2
pytz==2021.1
PyYAML==5.4.1
requests==2.26.0
s3transfer==0.5.0
six==1.16.0
sqlparse==0.4.1
stripe==2.60.0
tablib==3.0.0
urllib3==1.26.6
xlrd==2.0.1
xlwt==1.3.0
我的问题是,如何使图像变小。它需要更小吗?
我只是想找到将 Django 应用程序部署到 Digitalocean 的最佳方法,并且有很多方法和教程等令人困惑。我不知道它是否使它更容易使用 docker。我只使用他们的应用程序平台吗?那会提供SSL吗?使用 docker 等有什么好处?
docker-编写文件(供参考)
version: '3.7'
services:
web:
build:
context: .
dockerfile: Dockerfile.prod
command: gunicorn maffsguru.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
expose:
- 8000
env_file:
- .env.docker
depends_on:
- db
db:
image: postgres:12.0-alpine
env_file:
- .env.docker
volumes:
- postgres_data:/var/lib/postgresql/data/
ports:
- 5432:5432
nginx:
build: ./nginx
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
ports:
- 1337:80
depends_on:
- web
volumes:
postgres_data:
static_volume:
media_volume:
只是说...以上所有似乎都有效...但我不知道图像大小等是否会成为问题?
我也很困惑为什么 Nginx 似乎需要我做 http://0.0.0.0:1337 to view the site. Isn't the whole point to view it by navigating to http://0.0.0.0/
感谢您提供的任何建议或指导,对于我的问题的随机性表示歉意
欢迎来到Docker!全神贯注是一件很重要的事情,尤其是在开始的时候,但你问的是真正有效的问题,而且都是相关的
缩小尺寸
如何
一个很好的起点是 Docker 自己的 Docker 文件最佳实践页面:
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
他们清楚地解释了您的每个指令(COPY
、RUN
、ENV
等)如何创建额外的层,从而增加容器的大小。重要的是,它们展示了如何通过最小化不同的指令来减小图像大小。大量最小化的关键是使用 &&
.
RUN
语句中链接命令
我在您的 Docker 文件中注意到的其他内容是一个特定的行:
COPY . $APP_HOME
现在,根据您构建容器的方式(具体来说,您传递给 Docker 的文件夹作为上下文),这将复制 EVERYTHING 因为它有可用。很有可能,这将带入您的 venv
文件夹等,如果您有的话。我觉得这对你来说可能是规模最大的罪魁祸首。您可以通过在文件中添加明确的 COPY
或使用 .dockerignore
文件来缓解这种情况。
我构建了你的图像(没有任何源代码,也没有在 entrypoint.sh
中复制),它以 710MB 作为基础。检查源代码的大小并查看是否有其他内容进入其中可能是个好主意。
在我重新安排一些命令以重用指令后,图像为 484MB,小得多!
如果您遇到困难,我可以将它放入 Github 上的要点中并引导您完成它,但是,Docker 文档应该可以帮助您前进
为什么?
嗯,较大的应用程序/图像本身并不坏,但随着数据的增加,某些操作可能会变慢。
当我说操作时,我倾向于指从注册表中提取图像,或将它们推送到发布。传输 1GB 比传输 50MB 需要更长的时间。
扩展容器时还需要考虑一个因素。虽然图像大小不一定与启动容器时将使用多少磁盘直接相关,但它肯定会增加对你正在使用的机器的要求 运行,并限制其他人使用较小的设备
Docker
使用 Docker 的优点是广泛的,如果不提交我的论文答辩,我不能在这里涵盖所有这些 ;-)
但主要归结为以下几点:
- 许多提供商支持 运行在 docker 中安装您的应用程序
- Docker文件可帮助您在一致的环境中构建您的应用程序,这意味着您不必配置应用程序 运行 所在的每个主机,也不必担心版本冲突
- 容器让您可以在一致(且相同)的环境中开发和 运行 您的应用程序
- 容器通常提供非常好的网络功能。你会遇到的一个例子是 docker compose,你可以简单地通过它们的主机名 访问其他容器
Nginx
据我所知,你在那里设置得很好!我想 nginx 是 'telling you'(通过日志?)导航到 0.0.0.0
,因为那是它将绑定到容器 中的内容 。现在,您已经转发了来自 1337:80
的流量。 Docker 遵循 host:container
的格式,因此这意味着 localhost:1337
上的流量将被定向到容器端口 80
。
您可能需要根据您的 nginx 配置来交换它,但请放心,一旦一切设置完成,您将能够在浏览器中导航到本地主机并查看您的网站
如果您在上述任何方面需要帮助,或者需要更多资源来帮助您,请告诉我。鉴于我们似乎处于同一时区,很高兴随时与您通信并引导您完成任何事情
请注意,您必须安装一个编译器。该编译器需要大量 space.
大多数 Python 包都包含 pre-compiled 二进制包,那你为什么需要编译器?因为你用的是高山。来自 PyPI 的二进制包 (==wheels) 在 Alpine 上不起作用。
所以:
- 从 Alpine 基础映像切换到例如
python:3.8-slim-buster
. - 摆脱编译器安装,headers,等等,你可能不需要任何东西。
- 享受您新的快速构建,以及很可能更小的图像。
详情:https://pythonspeed.com/articles/alpine-docker-python/
替代方案是 multi-stage 构建,其中您的最终映像不包含不必要的编译器。这当然会增加更多的复杂性。
起点(这是 3 篇文章系列):https://pythonspeed.com/articles/smaller-python-docker-images/