我所拥有的是多相似且简单的dockerfile
的
但我想要的是有一个单一的碱基dockerfile
和我的dockerfile
将他们的变量传递给它。
在我的情况下,dockerfile
之间的唯一区别是只是他们的EXPOSE
,所以我认为最好保留一个基本dockerfile
,而其他dockerfile
只像模板引擎一样将这些变量注入到基本dockerfile
中
样品dockerfile
:
FROM golang:1.17 AS builder
WORKDIR /app
COPY . .
RUN go mod download
RUN go build -o /bin/app ./cmd/root.go
FROM alpine:latest
WORKDIR /bin/
COPY --from=builder /bin/app .
EXPOSE 8080
LABEL org.opencontainers.image.source="https://github.com/mohammadne/bookman-auth"
ENTRYPOINT ["/bin/app"]
CMD ["server", "--env=dev"]
IMPORT
指令将永远不会实现
很久以前就提出了Docker
的IMPORT
指令
不幸的是,问题已经解决,而PR仍然开放:
- docker-对多个dockerfile使用共享dockerfile-堆栈溢出
- 提案:Dockerfile添加INCLUDE·Issue#735·moby/mobi
- 为docker构建文件实现INCLUDE谓词/指令·Issue#974·moby/moby
- 添加INCLUDE功能·问题#40165·moby/moby
- docker构建:flavio·Pull Request#2108·moby/moby对include命令的初步工作
- Dockerfile模板自动化图像创建
- 像老板一样为Dockerfile模板化!|Ahmed ElGamil | Dockbit
您案例的解决方案
但对于您的情况,您所需要的只是一点sed
例如:
# Case1: inplace templating
EXPOSED_PORT=8081 sed -i "s/EXPOSE 8080/EXPOSE $EXPOSED_PORT/" Dockerfile
# Case2: generating Dockerfile from template
sed "s/EXPOSE 8080/EXPOSE $EXPOSED_PORT/" Dockerfile.template > Dockerfile
说明:
EXPOSED_PORT=8081
声明本地bash
变量sed
是一个文本操作工具sed -i "s/EXPOSE 8080/EXPOSE $EXPOSED_PORT/" Dockerfile
将EXPOSE 8080
替换为EXPOSE 8081
sed "s/EXPOSE 8080/EXPOSE $EXPOSED_PORT/" Dockerfile.template > Dockerfile
从Dockerfile.template
生成新的Dockerfile
您可以将公开的端口作为映像的构建参数。如果你制作一个像这样的码头文件
FROM alpine:latest
ARG EXPOSED_PORT
EXPOSE ${EXPOSED_PORT}
您可以通过传递类似的端口号来指定构建时暴露的端口
docker build -t myimage --build-arg EXPOSED_PORT=8000 .
值得注意的是,EXPOSE声明主要是文档。如果没有EXPOSE声明,您的图像也会正常工作。
你有一个非常好的主意。我有两个想法:
- 如您所述创建基本的dockerfile,然后像这样构建它:
docker image build tag base
。然后您可以有两个类似FROM base n EXPOSE 8080
的liner Dockerfile - 或者,您可以有一个Dockerfile,只需更改运行容器的方式。有一个
expose
开关。您在Dockerfile中指定的任何内容都可以在run
命令中被覆盖
最后,我所做的如下:github存储库的链接
- 使用
EXPOSE ${{ EXPOSED_PORT }}
创建模板文本文件:
FROM golang:1.17 AS builder
WORKDIR /app
COPY . .
RUN go mod download && make ent-generate
RUN go build -o /bin/app ./cmd/root.go
FROM alpine:latest
WORKDIR /bin/
COPY --from=builder /bin/app .
EXPOSE ${{ EXPOSED_PORT }}
LABEL org.opencontainers.image.source="https://github.com/mohammadne/bookman-library"
ENTRYPOINT ["/bin/app"]
CMD ["server", "--env=dev"]
- ,然后创建一个python脚本
#!/usr/bin/python
from shutil import copyfile
import os
class Config:
def __init__(self, service, port):
self.service = service
self.port = port
configs = [
Config("auth", "8080"),
Config("user", "8081"),
Config("library", "8082"),
]
pathToDir = "../build"
template = f"{pathToDir}/template.txt"
for config in configs:
outputDir = f"{pathToDir}/{config.service}"
os.mkdir(outputDir)
fileName = copyfile(template, f"{outputDir}/Dockerfile")
with open(fileName, "rt") as file:
replacedText = file.read().replace('${{ EXPOSED_PORT }}', config.port)
with open(fileName, "wt") as file:
file.write(replacedText)
然后在python脚本中,您可以替换您的模式!!!