期待
Here is my packer file:
{
"builders" : [
{
"type": "docker",
"image": "nginx",
"commit": "true"
}
],
"provisioners" : [
{
"type": "file",
"source": "./index.html",
"destination": "/usr/share/nginx/html/index.html"
}
],
"post-processors" : [
{
"type": "docker-tag",
"repository": "repo",
"tag": "latest"
}
]
}
在 packer build 之后,当从上述输出的工件中运行 docker 容器时,使用命令 docker run -it -d -p 8080:80 自定义 nginx docker 镜像时,上述文件 -命名 web repo,观察到 docker 容器出现,端口被占用但 nginx 进程没有在 docker 容器内运行,因为在指定的端口上无法访问 html 内容。 网址:http://localhost:8080
然而,上面创建自定义 nginx docker 镜像并运行 docker 容器的场景是使用下面的 Dockerfile 和 docker 命令执行的,它工作正常,即 docker 容器出现,端口被占用,并且 HTML 内容也可以访问:>
这是 Dockerfile:
FROM nginx:latest
COPY ./index.html /usr/share/nginx/html/index.html
我需要使用packer docker builder,可能有什么问题? docker builder 与 packer 或 nginx 一起使用有什么限制吗?
答案 0 :(得分:0)
问题在于,packer 的所有荣耀都覆盖了入口点。 Packer 通过“执行”到正在运行的容器并提交它来工作。所以它实际上不使用 docker 构建系统。
当您提交容器时,图像将获取容器启动的入口点和 cmd,在打包程序的情况下,它默认将入口点设置为/bin/sh
。
一种选择是不让它改变入口点。我已从默认命令中删除 --entrypoint
。
source "docker" "nginx" {
image = "nginx"
commit = true
run_command = ["-d", "-i", "-t", "--", "{{.Image}}"]
}
但是,我不确定这是否总是有效。我认为 nginx 入口点很特别,因为它只会在最后执行参数,如果 nginx 不是第一个参数,它不会执行其他任何操作。
exec "$@"
也许有时你需要给它一个 shell 入口点,以便让打包程序在镜像中正常工作。之后,恢复更改数组中的 cmd 和入口点。奇怪的是,当我这样做时,我需要恢复 CMD
否则它将是 null
。
source "docker" "nginx" {
image = "nginx"
commit = true
changes = [
"ENTRYPOINT [\"/docker-entrypoint.sh\"]",
"CMD [\"nginx\", \"-g\", \"daemon off;\"]"
]
}
这是一个完整的工作示例
packer {
required_plugins {
docker = {
version = ">= 1"
source = "github.com/hashicorp/docker"
}
}
}
source "docker" "nginx" {
image = "nginx"
commit = true
# either don't overwrite the entrypoint
run_command = ["-d", "-i", "-t", "--", "{{.Image}}"]
# or restore it
changes = [
"ENTRYPOINT [\"/docker-entrypoint.sh\"]",
"CMD [\"nginx\", \"-g\", \"daemon off;\"]"
]
}
build {
sources = [
"source.docker.nginx",
]
provisioner "file" {
source = "./index.html"
destination = "/usr/share/nginx/html/index.html"
}
post-processor "docker-tag" {
repository = "web"
}
}