是否可以将docker ENV变量设置为命令的结果? 像:
ENV MY_VAR whoami
我希望MY_VAR获得值“root”或者任何whoami返回
答案 0 :(得分:14)
作为DarkSideF答案的补充。
您应该知道Dockerfile中的每一行/命令都在另一个容器中运行。
您可以这样做:
RUN export bleah=$(hostname -f);echo $bleah;
这是在一个容器中运行。
答案 1 :(得分:10)
我有同样的问题,并找到了通过在dockerfile中使用RUN命令将环境变量设置为函数的方法。
例如,我需要为Rails应用程序设置SECRET_KEY_BASE一次而不会像我运行时那样进行更改:
User.idCreator
相反,它写入Dockerfile字符串,如:
docker run -e SECRET_KEY_BASE="$(openssl rand -hex 64)"
即使在bash登录后,和我的env变量也可从root获得。 或者可能是
RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" >> /etc/bash.bashrc'
然后它在CMD和ENTRYPOINT命令中可用
Docker将其缓存为图层,只有在您更改之前的某些字符串时才会更改。
您也可以尝试different ways设置环境变量。
答案 2 :(得分:7)
此时,命令结果可以与RUN export
一起使用,但不能分配给ENV
变量。
答案 3 :(得分:3)
这个答案是对 @DarkSideF ,
的回应他提出的方法如下Dockerfile
:
RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" >> /etc/bash.bashrc'
(在/etc/bash.bashrc
中添加导出)
这很好,但环境变量只能用于进程/bin/bash
,如果您尝试运行docker应用程序(例如Node.js应用程序),/etc/bash.bashrc
将完全被忽略,您的应用程序在尝试访问SECRET_KEY_BASE
时不知道process.env.SECRET_KEY_BASE
是什么。
这就是为什么ENV
关键字是每个人都尝试使用动态命令的原因,因为每次运行容器或使用exec
命令时,Docker都会检查ENV
并管道当前运行的流程中的每个值(类似于-e
)。
一种解决方案是使用包装器(在此github issue中归功于 @duglin )。
在项目根目录中包含一个包装文件(例如envwrapper
),其中包含:
#!/bin/bash
export SECRET_KEY_BASE="$(openssl rand -hex 64)"
export ANOTHER_ENV "hello world"
$*
然后在Dockerfile
:
...
COPY . .
RUN mv envwrapper /bin/.
RUN chmod 755 /bin/envwrapper
CMD envwrapper myapp
答案 4 :(得分:1)
不确定这是否是您想要的,但是为了将ENV var或ARGS注入.Dockerfile构建中,此模式有效。
在您的my_build.sh中:
echo getting version of osbase image to build from
OSBASE=$(grep "osbase_version" .version | sed 's/^.*: //')
echo building docker
docker build -f \
--build-arg ARTIFACT_TAG=$OSBASE \
PATH_TO_MY.Dockerfile \
-t my_artifact_home_url/bucketname:$TAG .
要在您的.Dockerfile中获得ARG,该片段可能如下所示:
FROM scratch
ARG ARTIFACT_TAG
FROM my_artifact_home_url/bucketname:${ARTIFACT_TAG}
或者为了在您的.Dockerfile中获取ENV,该代码段可能如下所示:
FROM someimage:latest
ARG ARTIFACT_TAG
ENV ARTIFACT_TAG=${ARTIFACT_TAG}
这个想法是您运行shell脚本,然后调用Dockerfile,并将args作为选项传递给构建。
答案 5 :(得分:1)
如果您使用 sh 运行命令,因为它似乎是 docker 中的默认设置。
你可以这样做:
Sub Lookup1()
'Runs lookup for open positions & returns position that can apply
'Provides data list of candidates with acceptable position codes
'Declare the variables
Dim JobClass1 As Integer
Dim StaffID As Long
Dim Last As String
Dim Status As String
Dim JobClass2 As Integer
'error statement
On Error GoTo errHandler:
'clear the listbox
lstJDOutput.RowSource = ""
lstSelector.RowSource = ""
**ListBox1.RowSourse = ""**
lstCerts.RowSource = ""
lstMatch.RowSource = ""
Staff_Data.RowSource = ""
'set the variable
Status = Me.bx1.Value
JobClass2 = Me.bx2.Value
JobClass1 = Me.bx5.Value
StaffID = Me.bx3.Value
Last = Me.bx4.Value
'if the results are nil clear the rowsource
'Sheet6 is JDOutput
'Sheet13 is Staffing_Output
If Sheet6.Range("B10").Value = "" Then
lstJDOutput.RowSource = ""
If Sheet13.Range("B8").Value = "" Then
lstSelector.RowSource = ""
Else
'add range to rowsource if range has values
lstlstJDOutput.RowSource = "Filter_Staff5"
lstSelector.RowSource = "Filter_Staff3"
ListBox1.RowSource = "Filter_Staff3"
End If
End If
Exit Sub
'if no JobClass or Status is selected for criteria search
'Sheet12 is JD (job Description), Sheet4 is Staffing_Data
With Sheet12
If Me.bx2 = "" Then
.Range("B6").Value = bx2
With Sheet4
If bx1 = "" Then
.Range("F3").Value = ""
.Range("S3").Value = bx3
End If
End With
End With
'run the filters
AdvFilterStaffing_Data
AdvFilterJD
AdvFilterStaffProgression
AdvFilterMatch
'if the results are nil then clear the rowsource to avoid an error
'Sheet13 is Staffing_Output, Sheet6 is JDOutput
With Sheet13
If Sheet13.Range("C8").Value = "" Then
lstSelector.RowSource = ""
If Sheet6.Range("B10").Value = "" Then
lstJDOutput.RowSource = ""
Else
'add range to rowsource if range has values
lstJDOutput.RowSource = "Filter_Staff4"
lstSelector.RowSource = "Filter_Staff3"
End If
End If
End If
End With
'error block
On Error GoTo 0
Exit Sub**strong text**
errHandler::
MsgBox "An Error has Occurred " & vbCrLf & "The error number is: " _
& Err.Number & vbCrLf & Err.Description & vbCrLf & _
"Please notify the administrator"
End Sub
通过这种方式,您可以通过将输出重定向到您选择的 env 文件来构建 env 文件。它比必须定义配置文件等更明确。
然后,由于该文件可用于其他层,因此可以获取它并使用正在导出的变量。您创建 env 文件的方式并不重要。
然后,当您完成后,您可以删除该文件,使其对正在运行的容器不可用。
RUN echo "export VAR=`command`" >> /envfile
RUN . /envfile; echo $VAR
是 env 文件的加载方式。
答案 6 :(得分:0)
作为@DarkSideF答案的补充,如果您想在构建过程中重用Dockerfile
中的上一条命令的结果 ,则可以使用以下解决方法:< / p>
例如:
RUN echo "bla" > ./result
RUN echo $(cat ./result)
对于更干净的东西,您还可以使用以下gist,它提供了一个名为envstore.py
的小型CLI:
RUN envstore.py set MY_VAR bla
RUN echo $(envstore.py get MY_VAR)
或者您可以使用具有类似CLI的python-dotenv库。