如何利用基础镜像中的Dockerfile构建完整镜像?
使用基础镜像内的Dockerfile构建镜像的解决办法
我现在遇到这么个问题:基础镜像image1:latest里自带了一个Dockerfile,路径是/usr/local/app/Dockerfile。我想基于这个内置的Dockerfile完成镜像构建,一开始写了这么个Dockerfile但根本没法用:
FROM image1:latest # image1 中包含 Dockerfile 文件 /usr/local/app/Dockerfile docker -f /usr/local/app/Dockerfile
试了两种方法都走不通:
试过的无效方法
方法一:想直接从镜像复制Dockerfile到主机
我本来打算先把镜像里的Dockerfile拷到本地再构建,写了这些命令:
docker copy image1:latest:/usr/local/app/Dockerfile /tmp/Dockerfile docker build -f /tmp/Dockerfile .
结果发现Docker根本没有docker copy命令——正确的docker cp只能从容器复制,不能直接从镜像拿文件,这条路走死了。
方法二:直接引用镜像内的Dockerfile
我还试了直接在构建命令里指定镜像内的文件路径,甚至写了docker-compose配置:
docker build -f image1:latest:/usr/local/app/Dockerfile .
services: web: build: context: . dockerfile: image1:latest:/usr/local/app/Dockerfile
但不管是docker build还是docker-compose,都不支持这种直接引用镜像内文件的写法,完全没用。
能跑通的解决方案
方案1:通过临时容器提取Dockerfile
既然docker cp只能操作容器,那我们先启动一个临时容器,再从容器里拷文件:
- 启动一个挂起的临时容器:
docker run --name temp-container -d image1:latest sleep infinity
- 把容器里的Dockerfile拷到本地:
docker cp temp-container:/usr/local/app/Dockerfile /tmp/Dockerfile
- 用完就删掉这个临时容器:
docker stop temp-container && docker rm temp-container
- 最后用本地的Dockerfile构建:
docker build -f /tmp/Dockerfile .
方案2:用BuildKit直接在构建过程中提取(更高效)
如果你的Docker启用了BuildKit(现在大部分新版本都默认开了),可以不用提前拷文件,直接在构建阶段从镜像里提取内置的Dockerfile:
写个新的Dockerfile,用BuildKit的特性:
# syntax=docker/dockerfile:1.4 # 第一步:从基础镜像里把内置Dockerfile拷出来 FROM scratch AS extract-file COPY --from=image1:latest /usr/local/app/Dockerfile /inner.Dockerfile # 第二步:用官方docker镜像来执行构建 FROM docker:latest AS builder COPY --from=extract-file /inner.Dockerfile ./ # 这里替换成你要构建的镜像名称 RUN docker build -t my-target-image . # 如果需要最终镜像,这里可以继续基于builder阶段的成果或者其他镜像定制 FROM alpine:latest # 比如复制builder阶段构建好的内容,按需调整 COPY --from=builder ...
或者直接用单行命令,不用单独写Dockerfile:
DOCKER_BUILDKIT=1 docker build -f- . <<EOF # syntax=docker/dockerfile:1.4 FROM image1:latest AS source # 把内置Dockerfile输出到临时文件 RUN cat /usr/local/app/Dockerfile > /tmp/inner-dockerfile FROM docker:latest COPY --from=source /tmp/inner-dockerfile ./Dockerfile RUN docker build -t my-target-image . EOF
方案3:配合docker-compose的做法
如果要用docker-compose,先把内置Dockerfile提取到本地,再让docker-compose引用:
- 执行这条命令,一键提取Dockerfile到当前目录(自动创建临时容器、复制、删除容器):
docker create --name temp image1:latest && docker cp temp:/usr/local/app/Dockerfile ./inner.Dockerfile && docker rm temp
- 修改docker-compose.yml,指向本地的
inner.Dockerfile:
services: web: build: context: . dockerfile: inner.Dockerfile
然后正常执行docker-compose build就行。
内容的提问来源于stack exchange,提问作者eastwater
相关产品推荐
相关产品推荐

