如何避免在此处使用/root/.cache?不确定我是否了解多阶段构建的工作原理。
# ---- Base python ----
FROM python:2.7-alpine3.7 AS base
# Create app directory
WORKDIR /app
# ---- Dependencies ----
FROM base AS dependencies
COPY requirements.txt ./
RUN apk add --no-cache libgcc git build-base && \
pip install -r requirements.txt && \
apk del git build-base binutils-libs binutils gmp isl libgomp libatomic pkgconf libgcc && \
apk del mpfr3 mpc1 libstdc++ gcc musl-dev libc-dev g++ make fortify-headers ca-certificates libssh2 && \
apk del libcurl expat pcre2 git && \
pip uninstall -y mock PyMySQL coverage pytest pytest-cov pytest-xdist wheel setuptools && \
rm -rf /usr/share/locale/* && \
rm -rf /var/cache/debconf/*-old && \
rm -rf /var/lib/apt/lists/* /var/lib/dpkg && \
rm -rf /usr/share/doc/* && \
rm -rf /usr/share/man/?? && \
rm -rf /usr/share/man/??_*
# ---- Copy Files/Build ----
FROM dependencies AS build
WORKDIR /app
COPY . /app
COPY --from=dependencies /root/.cache /root/.cache
WORKDIR /app
也许我应该使用virtualenv?
答案 0 :(得分:2)
Docker多阶段构建通过创建多个阶段来进行工作,目的是使最终映像具有最少所需的组件
在您的情况下,您将重新使用初始构建阶段作为最终映像
FROM python:2.7-alpine3.7 AS base
..
FROM base AS dependencies
..
FROM dependencies AS build
但是,您还将删除在依赖项阶段安装的不需要的软件包,从而消除了多阶段映像的优势,因此看不到任何可见的大小变化。
为了进行演示,由于您尚未发布requirements.txt
文件,因此我假设它将安装flask
λ cat requirements.txt
flask==1.0.2
考虑您的Dockerfile,但是删除删除软件包的命令
# ---- Base python ----
FROM python:2.7-alpine3.7 AS base
# Create app directory
WORKDIR /app
# ---- Dependencies ----
FROM base AS dependencies
COPY requirements.txt ./
RUN apk add --no-cache libgcc git build-base && \
pip install -r requirements.txt
# ---- Copy Files/Build ----
FROM dependencies AS build
WORKDIR /app
COPY . /app
COPY --from=dependencies /root/.cache /root/.cache
WORKDIR /app
构建图像:
docker build -t so:51678830 .
Sending build context to Docker daemon 3.072kB
Step 1/10 : FROM python:2.7-alpine3.7 AS base
---> b1d3c201a89a
Step 2/10 : WORKDIR /app
---> Using cache
---> 675f27f73cf9
Step 3/10 : FROM base AS dependencies
---> 675f27f73cf9
Step 4/10 : COPY requirements.txt ./
---> Using cache
---> 288a87ba0ecf
Step 5/10 : RUN apk add --no-cache libgcc git build-base && pip install -r requirements.txt
---> Running in 6520cfe93603
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
(1/23) Installing binutils-libs (2.30-r1)
(2/23) Installing binutils (2.30-r1)
(3/23) Installing gmp (6.1.2-r1)
(4/23) Installing isl (0.18-r0)
(5/23) Installing libgomp (6.4.0-r5)
(6/23) Installing libatomic (6.4.0-r5)
(7/23) Installing pkgconf (1.3.10-r0)
(8/23) Installing libgcc (6.4.0-r5)
(9/23) Installing mpfr3 (3.1.5-r1)
(10/23) Installing mpc1 (1.0.3-r1)
(11/23) Installing libstdc++ (6.4.0-r5)
(12/23) Installing gcc (6.4.0-r5)
(13/23) Installing musl-dev (1.1.18-r3)
(14/23) Installing libc-dev (0.7.1-r0)
(15/23) Installing g++ (6.4.0-r5)
(16/23) Installing make (4.2.1-r0)
(17/23) Installing fortify-headers (0.9-r0)
(18/23) Installing build-base (0.5-r0)
(19/23) Installing libssh2 (1.8.0-r2)
(20/23) Installing libcurl (7.61.0-r0)
(21/23) Installing expat (2.2.5-r0)
(22/23) Installing pcre2 (10.30-r0)
(23/23) Installing git (2.15.2-r0)
Executing busybox-1.27.2-r11.trigger
OK: 186 MiB in 53 packages
Collecting flask==1.0.2 (from -r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/7f/e7/08578774ed4536d3242b14dacb4696386634607af824ea997202cd0edb4b/Flask-1.0.2-py2.py3-none-any.whl (91kB)
Collecting Werkzeug>=0.14 (from flask==1.0.2->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/20/c4/12e3e56473e52375aa29c4764e70d1b8f3efa6682bef8d0aae04fe335243/Werkzeug-0.14.1-py2.py3-none-any.whl (322kB)
Collecting click>=5.1 (from flask==1.0.2->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/34/c1/8806f99713ddb993c5366c362b2f908f18269f8d792aff1abfd700775a77/click-6.7-py2.py3-none-any.whl (71kB)
Collecting itsdangerous>=0.24 (from flask==1.0.2->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/dc/b4/a60bcdba945c00f6d608d8975131ab3f25b22f2bcfe1dab221165194b2d4/itsdangerous-0.24.tar.gz (46kB)
Collecting Jinja2>=2.10 (from flask==1.0.2->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/7f/ff/ae64bacdfc95f27a016a7bed8e8686763ba4d277a78ca76f32659220a731/Jinja2-2.10-py2.py3-none-any.whl (126kB)
Collecting MarkupSafe>=0.23 (from Jinja2>=2.10->flask==1.0.2->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/4d/de/32d741db316d8fdb7680822dd37001ef7a448255de9699ab4bfcbdf4172b/MarkupSafe-1.0.tar.gz
Building wheels for collected packages: itsdangerous, MarkupSafe
Running setup.py bdist_wheel for itsdangerous: started
Running setup.py bdist_wheel for itsdangerous: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/2c/4a/61/5599631c1554768c6290b08c02c72d7317910374ca602ff1e5
Running setup.py bdist_wheel for MarkupSafe: started
Running setup.py bdist_wheel for MarkupSafe: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/33/56/20/ebe49a5c612fffe1c5a632146b16596f9e64676768661e4e46
Successfully built itsdangerous MarkupSafe
Installing collected packages: Werkzeug, click, itsdangerous, MarkupSafe, Jinja2, flask
Successfully installed Jinja2-2.10 MarkupSafe-1.0 Werkzeug-0.14.1 click-6.7 flask-1.0.2 itsdangerous-0.24
Removing intermediate container 6520cfe93603
---> 6d73b486a703
Step 6/10 : FROM dependencies AS build
---> 6d73b486a703
Step 7/10 : WORKDIR /app
---> Running in 0ed8fa7f13e7
Removing intermediate container 0ed8fa7f13e7
---> e61cf72b31ae
Step 8/10 : COPY . /app
---> f6c7a4d3d8df
Step 9/10 : COPY --from=dependencies /root/.cache /root/.cache
---> 2c15e7080c91
Step 10/10 : WORKDIR /app
---> Running in 717bd7cf7b1d
Removing intermediate container 717bd7cf7b1d
---> cfe7ee0c5880
Successfully built cfe7ee0c5880
Successfully tagged so:51678830
检查图像的大小:
docker images
| REPOSITORY TAG IMAGE ID CREATED SIZE |
|--------------------------------------------------------------------------------------------------|
| so 51678830 4477dac77289 About a minute ago 234MB |
让我们修改Dockerfile,使其使用“基本”作为最终映像,但从依赖项通过缓存的pip wheel复制
# ---- Base python ----
FROM python:2.7-alpine3.7 AS base
# Create app directory
WORKDIR /app
# ---- Dependencies ----
FROM base AS dependencies
COPY requirements.txt ./
RUN apk add --no-cache libgcc git build-base && \
pip install -r requirements.txt
# ---- Copy Files/Build ----
FROM base
WORKDIR /app
COPY . /app
COPY --from=dependencies /root/.cache /root/.cache
WORKDIR /app
构建图像
docker build -t so:51678830 .
Sending build context to Docker daemon 3.072kB
Step 1/10 : FROM python:2.7-alpine3.7 AS base
---> b1d3c201a89a
Step 2/10 : WORKDIR /app
---> Running in aca871ed01e3
Removing intermediate container aca871ed01e3
---> 89d357832427
Step 3/10 : FROM base AS dependencies
---> 89d357832427
Step 4/10 : COPY requirements.txt ./
---> 6ecbfe862e27
Step 5/10 : RUN apk add --no-cache libgcc git build-base && pip install -r requirements.txt
---> Running in 465256e75563
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
(1/23) Installing binutils-libs (2.30-r1)
(2/23) Installing binutils (2.30-r1)
(3/23) Installing gmp (6.1.2-r1)
(4/23) Installing isl (0.18-r0)
(5/23) Installing libgomp (6.4.0-r5)
(6/23) Installing libatomic (6.4.0-r5)
(7/23) Installing pkgconf (1.3.10-r0)
(8/23) Installing libgcc (6.4.0-r5)
(9/23) Installing mpfr3 (3.1.5-r1)
(10/23) Installing mpc1 (1.0.3-r1)
(11/23) Installing libstdc++ (6.4.0-r5)
(12/23) Installing gcc (6.4.0-r5)
(13/23) Installing musl-dev (1.1.18-r3)
(14/23) Installing libc-dev (0.7.1-r0)
(15/23) Installing g++ (6.4.0-r5)
(16/23) Installing make (4.2.1-r0)
(17/23) Installing fortify-headers (0.9-r0)
(18/23) Installing build-base (0.5-r0)
(19/23) Installing libssh2 (1.8.0-r2)
(20/23) Installing libcurl (7.61.0-r0)
(21/23) Installing expat (2.2.5-r0)
(22/23) Installing pcre2 (10.30-r0)
(23/23) Installing git (2.15.2-r0)
Executing busybox-1.27.2-r11.trigger
OK: 186 MiB in 53 packages
Collecting flask==1.0.2 (from -r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/7f/e7/08578774ed4536d3242b14dacb4696386634607af824ea997202cd0edb4b/Flask-1.0.2-py2.py3-none-any.whl (91kB)
Collecting Werkzeug>=0.14 (from flask==1.0.2->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/20/c4/12e3e56473e52375aa29c4764e70d1b8f3efa6682bef8d0aae04fe335243/Werkzeug-0.14.1-py2.py3-none-any.whl (322kB)
Collecting click>=5.1 (from flask==1.0.2->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/34/c1/8806f99713ddb993c5366c362b2f908f18269f8d792aff1abfd700775a77/click-6.7-py2.py3-none-any.whl (71kB)
Collecting itsdangerous>=0.24 (from flask==1.0.2->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/dc/b4/a60bcdba945c00f6d608d8975131ab3f25b22f2bcfe1dab221165194b2d4/itsdangerous-0.24.tar.gz (46kB)
Collecting Jinja2>=2.10 (from flask==1.0.2->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/7f/ff/ae64bacdfc95f27a016a7bed8e8686763ba4d277a78ca76f32659220a731/Jinja2-2.10-py2.py3-none-any.whl (126kB)
Collecting MarkupSafe>=0.23 (from Jinja2>=2.10->flask==1.0.2->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/4d/de/32d741db316d8fdb7680822dd37001ef7a448255de9699ab4bfcbdf4172b/MarkupSafe-1.0.tar.gz
Building wheels for collected packages: itsdangerous, MarkupSafe
Running setup.py bdist_wheel for itsdangerous: started
Running setup.py bdist_wheel for itsdangerous: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/2c/4a/61/5599631c1554768c6290b08c02c72d7317910374ca602ff1e5
Running setup.py bdist_wheel for MarkupSafe: started
Running setup.py bdist_wheel for MarkupSafe: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/33/56/20/ebe49a5c612fffe1c5a632146b16596f9e64676768661e4e46
Successfully built itsdangerous MarkupSafe
Installing collected packages: Werkzeug, click, itsdangerous, MarkupSafe, Jinja2, flask
Successfully installed Jinja2-2.10 MarkupSafe-1.0 Werkzeug-0.14.1 click-6.7 flask-1.0.2 itsdangerous-0.24
Removing intermediate container 465256e75563
---> d9a23965de75
Step 6/10 : FROM base
---> 89d357832427
Step 7/10 : WORKDIR /app
---> Running in bb975f43890d
Removing intermediate container bb975f43890d
---> ba0d78774039
Step 8/10 : COPY . /app
---> 3510860b3538
Step 9/10 : COPY --from=dependencies /root/.cache /root/.cache
---> 812c65bd156b
Step 10/10 : WORKDIR /app
---> Running in 4191ef84468e
Removing intermediate container 4191ef84468e
---> 236d8ee0bea4
Successfully built 236d8ee0bea4
Successfully tagged so:51678830
有了这个,我们得到的图像大小为60.5MB
码头工人图像
| REPOSITORY TAG IMAGE ID CREATED SIZE |
|---------------------------------------------------------------------------------------------------|
| so 51678830 e53282dc4fc7 2 seconds ago 60.5MB |
但是,我们仅将缓存文件复制到了最终映像上,我们仍然需要安装它,然后才能删除/root/.cache
。 Dockerfile现在将如下所示:
# ---- Base python ----
FROM python:2.7-alpine3.7 AS base
# Create app directory
WORKDIR /app
# ---- Dependencies ----
FROM base AS dependencies
COPY requirements.txt ./
RUN apk add --no-cache libgcc git build-base && \
pip install -r requirements.txt
# ---- Copy Files/Build ----
FROM base
WORKDIR /app
COPY . /app
COPY --from=dependencies /root/.cache /root/.cache
COPY requirements.txt ./
RUN pip install -r requirements.txt && rm -rf /root/.cache
构建图像:
docker build -t so:51678830 .
Sending build context to Docker daemon 3.584kB
Step 1/11 : FROM python:2.7-alpine3.7 AS base
---> b1d3c201a89a
Step 2/11 : WORKDIR /app
---> Running in 8471e5fe8fac
Removing intermediate container 8471e5fe8fac
---> 646de3787bbc
Step 3/11 : FROM base AS dependencies
---> 646de3787bbc
Step 4/11 : COPY requirements.txt ./
---> 4b6c6690ddf7
Step 5/11 : RUN apk add --no-cache libgcc git build-base && pip install -r requirements.txt
---> Running in aaa83a183ead
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
(1/23) Installing binutils-libs (2.30-r1)
(2/23) Installing binutils (2.30-r1)
(3/23) Installing gmp (6.1.2-r1)
(4/23) Installing isl (0.18-r0)
(5/23) Installing libgomp (6.4.0-r5)
(6/23) Installing libatomic (6.4.0-r5)
(7/23) Installing pkgconf (1.3.10-r0)
(8/23) Installing libgcc (6.4.0-r5)
(9/23) Installing mpfr3 (3.1.5-r1)
(10/23) Installing mpc1 (1.0.3-r1)
(11/23) Installing libstdc++ (6.4.0-r5)
(12/23) Installing gcc (6.4.0-r5)
(13/23) Installing musl-dev (1.1.18-r3)
(14/23) Installing libc-dev (0.7.1-r0)
(15/23) Installing g++ (6.4.0-r5)
(16/23) Installing make (4.2.1-r0)
(17/23) Installing fortify-headers (0.9-r0)
(18/23) Installing build-base (0.5-r0)
(19/23) Installing libssh2 (1.8.0-r2)
(20/23) Installing libcurl (7.61.0-r0)
(21/23) Installing expat (2.2.5-r0)
(22/23) Installing pcre2 (10.30-r0)
(23/23) Installing git (2.15.2-r0)
Executing busybox-1.27.2-r11.trigger
OK: 186 MiB in 53 packages
Collecting flask==1.0.2 (from -r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/7f/e7/08578774ed4536d3242b14dacb4696386634607af824ea997202cd0edb4b/Flask-1.0.2-py2.py3-none-any.whl (91kB)
Collecting Werkzeug>=0.14 (from flask==1.0.2->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/20/c4/12e3e56473e52375aa29c4764e70d1b8f3efa6682bef8d0aae04fe335243/Werkzeug-0.14.1-py2.py3-none-any.whl (322kB)
Collecting click>=5.1 (from flask==1.0.2->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/34/c1/8806f99713ddb993c5366c362b2f908f18269f8d792aff1abfd700775a77/click-6.7-py2.py3-none-any.whl (71kB)
Collecting itsdangerous>=0.24 (from flask==1.0.2->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/dc/b4/a60bcdba945c00f6d608d8975131ab3f25b22f2bcfe1dab221165194b2d4/itsdangerous-0.24.tar.gz (46kB)
Collecting Jinja2>=2.10 (from flask==1.0.2->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/7f/ff/ae64bacdfc95f27a016a7bed8e8686763ba4d277a78ca76f32659220a731/Jinja2-2.10-py2.py3-none-any.whl (126kB)
Collecting MarkupSafe>=0.23 (from Jinja2>=2.10->flask==1.0.2->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/4d/de/32d741db316d8fdb7680822dd37001ef7a448255de9699ab4bfcbdf4172b/MarkupSafe-1.0.tar.gz
Building wheels for collected packages: itsdangerous, MarkupSafe
Running setup.py bdist_wheel for itsdangerous: started
Running setup.py bdist_wheel for itsdangerous: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/2c/4a/61/5599631c1554768c6290b08c02c72d7317910374ca602ff1e5
Running setup.py bdist_wheel for MarkupSafe: started
Running setup.py bdist_wheel for MarkupSafe: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/33/56/20/ebe49a5c612fffe1c5a632146b16596f9e64676768661e4e46
Successfully built itsdangerous MarkupSafe
Installing collected packages: Werkzeug, click, itsdangerous, MarkupSafe, Jinja2, flask
Successfully installed Jinja2-2.10 MarkupSafe-1.0 Werkzeug-0.14.1 click-6.7 flask-1.0.2 itsdangerous-0.24
Removing intermediate container aaa83a183ead
---> eca67b911ca4
Step 6/11 : FROM base
---> 646de3787bbc
Step 7/11 : WORKDIR /app
---> Running in 0b81da90cc35
Removing intermediate container 0b81da90cc35
---> 17489d37a114
Step 8/11 : COPY . /app
---> 1f12ed2b9456
Step 9/11 : COPY --from=dependencies /root/.cache /root/.cache
---> 850bd5d693e3
Step 10/11 : COPY requirements.txt ./
---> b508d7762e8e
Step 11/11 : RUN pip install -r requirements.txt && rm -rf /root/.cache
---> Running in 125afe6f16b0
Collecting flask==1.0.2 (from -r requirements.txt (line 1))
Using cached https://files.pythonhosted.org/packages/7f/e7/08578774ed4536d3242b14dacb4696386634607af824ea997202cd0edb4b/Flask-1.0.2-py2.py3-none-any.whl
Collecting Werkzeug>=0.14 (from flask==1.0.2->-r requirements.txt (line 1))
Using cached https://files.pythonhosted.org/packages/20/c4/12e3e56473e52375aa29c4764e70d1b8f3efa6682bef8d0aae04fe335243/Werkzeug-0.14.1-py2.py3-none-any.whl
Collecting click>=5.1 (from flask==1.0.2->-r requirements.txt (line 1))
Using cached https://files.pythonhosted.org/packages/34/c1/8806f99713ddb993c5366c362b2f908f18269f8d792aff1abfd700775a77/click-6.7-py2.py3-none-any.whl
Collecting itsdangerous>=0.24 (from flask==1.0.2->-r requirements.txt (line 1))
Collecting Jinja2>=2.10 (from flask==1.0.2->-r requirements.txt (line 1))
Using cached https://files.pythonhosted.org/packages/7f/ff/ae64bacdfc95f27a016a7bed8e8686763ba4d277a78ca76f32659220a731/Jinja2-2.10-py2.py3-none-any.whl
Collecting MarkupSafe>=0.23 (from Jinja2>=2.10->flask==1.0.2->-r requirements.txt (line 1))
Installing collected packages: Werkzeug, click, itsdangerous, MarkupSafe, Jinja2, flask
Successfully installed Jinja2-2.10 MarkupSafe-1.0 Werkzeug-0.14.1 click-6.7 flask-1.0.2 itsdangerous-0.24
Removing intermediate container 125afe6f16b0
---> d122f42fcb72
Successfully built d122f42fcb72
Successfully tagged so:51678830
最终映像为70MB
| REPOSITORY TAG IMAGE ID CREATED SIZE |
|--------------------------------------------------------------------------------------------------|
| so 51678830 d122f42fcb72 4 seconds ago 69.6MB |
希望让事情变得清晰