如何避免在这里使用/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?
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 |
希望事情说清楚