我正在运行,但是,当我分配一个用于修改的变量及其字符串内容“PRIVATEIP”Dockerfile
时遇到问题。/etc/fail2ban/jail.local
Dockerfile
产生错误并停止。因为我不知道如何分配一个变量来sed
修改特定文件中的字符串内容。
RUN IP=$(cat /root/ip_variable) | sed -i -r "s/PRIVATEIP/${IP}/g" /etc/fail2ban/jail.local
---> Running in 1e78ef4318ab
如果有任何替代方法来处理此问题,请告诉我。
=================================================== =========================
2018 年/7 月 11 日对替代方法添加更多说明如下:
我在 Dockerfile 上添加了一些命令行。目的和以前一样。我也可以使用 echo 编写如下脚本。但是,这很奇怪。为什么“sed”这个命令上“s”后面的同伴字符“/”会被错过? (如果有任何方法可以在代码输出中的字符上添加高亮或标记,我谢谢你。)如果这个问题得到解决,我想我可以解决这个问题。
Step 64/73 : RUN echo "#!/bin/bash\nexport PRIVATEIP=$(cat /home/ip_variable)\nsed -i -r \"s/\bPRIVATEIP\b/\${PRIVATEIP}/g\" /etc/fail2ban/jail.local\nsed -i -r \"s/\bPRIVATEIP\b/\${PRIVATEIP}/g\" /etc/opendkim/TrustedHosts" > /home/start_script.sh
---> Running in bbff59f82475
Removing intermediate container bbff59f82475
---> 0068d9d600ff
Step 65/73 : RUN cat /home/ip_variable
---> Running in faeb4bb1a6ba
172.17.0.2/16
Removing intermediate container faeb4bb1a6ba
---> f6cc35fd01e5
Step 66/73 : RUN cat /home/start_script.sh
---> Running in 95a5ef3b7d23
#!/bin/bash
export PRIVATEIP=172.17.0.2/16
sed -i -r "sPRIVATEI/${PRIVATEIP}/g" /etc/fail2ban/jail.local
sed -i -r "sPRIVATEI/${PRIVATEIP}/g" /etc/opendkim/TrustedHosts
Removing intermediate container 95a5ef3b7d23
---> 6720e7c01efc
Step 67/73 : RUN chmod 755 /home/start_script.sh
---> Running in d8ab5e04a846
Removing intermediate container d8ab5e04a846
---> decb9e147db9
Step 68/73 : RUN sh /home/start_script.sh
---> Running in fc86000f9a2f
sed: -e expression #1, char 28: unknown option to `s'
sed: -e expression #1, char 28: unknown option to `s'
The command '/bin/sh -c sh /home/start_script.sh' returned a non-zero code: 1
答案1
这对我有用:
FROM alpine
COPY ipaddr /ipaddr
COPY ipconf /ipconf
RUN export IPADDR=$(cat /ipaddr) ; sed -i -r "s/IPADDR/${IPADDR}/g" /ipconf
CMD cat /ipconf
使用 ipconf 和 ipaddr
IP address is IPADDR
1.2.3.4
然后:
>docker build -t dynchange .
Sending build context to Docker daemon 5.12kB
Step 1/5 : FROM alpine
---> 3fd9065eaf02
Step 2/5 : COPY ipaddr /ipaddr
---> Using cache
---> 1828c3157d41
Step 3/5 : COPY ipconf /ipconf
---> 4f43e88e4425
Step 4/5 : RUN export IPADDR=$(cat /ipaddr) ; sed -i -r "s/IPADDR/${IPADDR}/g" /ipconf
---> Running in 722c3d3d9d9e
Removing intermediate container 722c3d3d9d9e
---> 32e31198b70a
Step 5/5 : CMD cat /ipconf
---> Running in 72ea59543a7f
Removing intermediate container 72ea59543a7f
---> 73f8a50d650a
Successfully built 73f8a50d650a
Successfully tagged dynchange:latest
>docker run --rm dynchange
IP address is 1.2.3.4
然而,这正是我不会这样做的。更好的方法是使用构建参数:
FROM alpine
COPY ipconf /ipconf
ARG IPADDR
RUN sed -i -r "s/IPADDR/${IPADDR}/g" /ipconf
CMD cat /ipconf
然后:
>docker build -t dynchange --build-arg IPADDR=4.5.6.7 .
Sending build context to Docker daemon 5.12kB
Step 1/5 : FROM alpine
---> 3fd9065eaf02
Step 2/5 : COPY ipconf /ipconf
---> Using cache
---> f5ac88ee48d5
Step 3/5 : ARG IPADDR
---> Running in 58d972e14660
Removing intermediate container 58d972e14660
---> fc3de48160c6
Step 4/5 : RUN sed -i -r "s/IPADDR/${IPADDR}/g" /ipconf
---> Running in 8ec855697510
Removing intermediate container 8ec855697510
---> 67e946559316
Step 5/5 : CMD cat /ipconf
---> Running in a5260c593c02
Removing intermediate container a5260c593c02
---> 567a31a517d1
Successfully built 567a31a517d1
Successfully tagged dynchange:latest
>docker run --rm dynchange
IP address is 4.5.6.7
但是我什至不确定这是正确的解决方案。我会:
- 在容器外部构建配置文件,并使用
COPY
.这可以完全控制其内容。 - 当容器运行时(环境变量或其他),将该 IP 地址作为参数传递,这样您就拥有了一个可在多个环境中使用的容器映像。或
CMD
可以ENTRYPOINT
是在调用主命令之前修补文件的脚本。您还可以将配置文件作为 VOLUME 传递(如果 CMD 作为应用程序用户运行并且修补配置需要 root 权限,这可以避免出现问题)。
答案2
谢谢大家。我的问题是在定界符上。我将“/”更改为“:”并使其正常工作。我将结果发布在这里。在“Step 65/78”中,我打印了脚本内容,“Step 67/78”很好地运行了脚本。谢谢@xenoid 和@Kusalananda。
Step 63/78 : RUN echo "#!/bin/sh -x\nsed -i 's:PRIVATEIP:'"$(cat /home/ip_variable)"':g' /etc/fail2ban/jail.local\nsed -i 's:PRIVATEIP:'"$(cat /home/ip_variable)"':g' /etc/opendkim/TrustedHosts" > /home/ip_change_script.sh
---> Running in 251d6741c37e
Removing intermediate container 251d6741c37e
---> 95c4aa62d74a
Step 64/78 : RUN cat /home/ip_variable
---> Running in 8825ef517fb8
172.17.0.2/16
Removing intermediate container 8825ef517fb8
---> 39672eb7021d
Step 65/78 : RUN cat /home/ip_change_script.sh
---> Running in 2161051ee4cf
#!/bin/sh -x
sed -i 's:PRIVATEIP:'172.17.0.2/16':g' /etc/fail2ban/jail.local
sed -i 's:PRIVATEIP:'172.17.0.2/16':g' /etc/opendkim/TrustedHosts
Removing intermediate container 2161051ee4cf
---> 407ccc7106f7
Step 66/78 : RUN chmod 755 /home/ip_change_script.sh
---> Running in 0f6ca7f78ba8
Removing intermediate container 0f6ca7f78ba8
---> 250afb327db0
Step 67/78 : RUN sh /home/ip_change_script.sh
---> Running in 4b209e18854b
Removing intermediate container 4b209e18854b
---> d45d024e1359
Step 68/78 : RUN touch /home/service_boot.log
---> Running in 3548dc45f466
Removing intermediate container 3548dc45f466
---> 587527e18ab2
Step 69/78 : RUN cat /home/service_boot.log
---> Running in b068b00cd584
Removing intermediate container b068b00cd584
---> 3183e6b281ed
Step 70/78 : COPY boot_service.sh /home/boot_service.sh
---> 9a73dd4fd87d
Step 71/78 : RUN chmod 755 /home/boot_service.sh
---> Running in 2f226574e28d
Removing intermediate container 2f226574e28d
---> 8a0c14218e1b
Step 72/78 : RUN cat /home/boot_service.sh
---> Running in 5fa64827b6dd
答案3
分配不会产生输出,因此将其通过管道传输到另一个进程是没有意义的。
相反,使用;
将管道分为两个连续命令:
IP=$(cat /root/ip_variable); sed -i "s/PRIVATEIP/$IP/g" /etc/fail2ban/jail.local
我对 Docker 不熟悉,它是RUN
命令不熟悉。如果只需要一个单身的命令,然后使用
RUN sh -c 'IP=$(cat /root/ip_variable); sed -i "s/PRIVATEIP/$IP/g" /etc/fail2ban/jail.local'
或者
RUN sed -i "s/PRIVATEIP/$(cat /root/ip_variable)/g" /etc/fail2ban/jail.local