Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 在sed正则表达式中使用docker--build arg_Linux_Bash_Docker_Sed - Fatal编程技术网

Linux 在sed正则表达式中使用docker--build arg

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 然后,当我

作为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
然后,当我构建它时: $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历史记录)将只包含已编译的应用程序,不包含任何构建时依赖项(如源代码目录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
...