Linux 在sed正则表达式中使用docker--build arg
作为Dockerfile构建的一部分,我尝试使用sed替换package.json文件的部分内容。以下命令从常规linux命令行(在我的主机上)运行: 这很好用,而且很管用。然后,我尝试在dockerfile中执行相同的操作:Linux 在sed正则表达式中使用docker--build arg,linux,bash,docker,sed,Linux,Bash,Docker,Sed,作为Dockerfile构建的一部分,我尝试使用sed替换package.json文件的部分内容。以下命令从常规linux命令行(在我的主机上)运行: 这很好用,而且很管用。然后,我尝试在dockerfile中执行相同的操作: ARG TOKEN RUN export GITHUB_TOKEN=$TOKEN && sed -i -E "s/git\+ssh:\/\/git/git\+https:\/\/${GITHUB_TOKEN}:/g" package.json 然后,当我
ARG TOKEN
RUN export GITHUB_TOKEN=$TOKEN && sed -i -E "s/git\+ssh:\/\/git/git\+https:\/\/${GITHUB_TOKEN}:/g" package.json
然后,当我构建它时:
$docker build--build arg TOKEN=MySecretToken
它失败,并显示以下错误消息:
sed:-e表达式#1,字符42:'s'的未知选项
感谢您的帮助
最终编辑:当前状态
我仍然无法在我的主机上使用docker使其工作,但我在GCP虚拟机上进行了尝试,它实际上工作正常。我的linux虚拟机和windows计算机之间可能存在一些与复制粘贴相关的问题。对不起,如果是这样的话,我很感谢你的回答和评论
编辑:
我对该方法的安全性有一些担忧,因此我将尝试澄清:
我的意思是在构建时插入这个令牌,而不是在运行时。原因是我们在package.json中使用私有git repos作为依赖项。要在不在构建容器中设置git的情况下安装它们,我们可以使用github部署令牌。我们正计划使用谷歌云为我们的建设与此令牌加密。在构建期间(在同一构建步骤中),我们计划:
- 制作原始package.json的副本
- 解密令牌
- 使用sed用解密的令牌替换package.json的部分内容
- 运行npm安装
- 将被篡改的package.json替换为原始package.json
有关类似方法的博客文章,请参阅在构建时传递参数时使用的参数,例如:
docker build -t mydocker \
--build-arg TOKEN=MySecretToken .
我假设您希望在映像启动时传递该令牌,因此您应该将该参数作为环境参数传递,这样您可以重用相同的容器,但传递不同的令牌。还将令牌注入entrypoint.sh中的package.json中
docker run -d --rm --name mydoc -e GITHUB_TOKEN=MySecretToken mydocker
这样,GITHUB_令牌将成为环境变量的一部分,这很好
当然,在entrypoint.sh中,您可以进行替换:
#!/bin/bash
sed -i -E "s/git\+ssh:\/\/git/git\+https:\/\/${GITHUB_TOKEN}:/g" package.json
...
我的建议是根本不要传递该令牌,我假设您计划在容器内运行npm install,并在其他容器(缓存容器)中生成node_模块,并将node_模块文件夹复制到您的容器中。这样,您就不会暴露您的令牌。注意,这将使任何拥有您的图像并可以在其上运行
docker history
的人都可以看到令牌。您可能不希望这样。两个sed
技巧:(1)将echo
放在sed命令之前,以查看shell引用后发送的实际命令,如果错误,请修复它。(2) 您可以在s
命令上使用任何标点符号,并且必须转义该特定字符,例如s@git\+ssh://git@…@g
可能更容易阅读。很可能您的斜杠转义得不够。docker正在解析dockerfile或容器中的shell,或者两者都在解析反斜杠,然后再返回到sed命令。@DavidMaze:我知道这个方法带来的安全问题。为了简洁起见,我遗漏了一个加密密钥,在运行sed之前,它将在同一步骤中被解密。在同一构建步骤中,Package.json也将替换为原始Package.json,这意味着解密的密钥在任何地方都不可见。此外,它是一个多阶段构建,因此最终映像不会包含package.json或令牌。我会更新我的帖子,提供更多关于这个过程的信息。谢谢你的回复。不过,我确实希望在构建时使用此令牌,而不是像您建议的那样在运行时使用。原因是我需要使用几个私有git存储库运行npm安装。我会更新我的帖子,提供更多细节。
#!/bin/bash
sed -i -E "s/git\+ssh:\/\/git/git\+https:\/\/${GITHUB_TOKEN}:/g" package.json
...