sed를 사용하여 Dockerfile에서 변수를 할당하고 구성 파일 내용을 바꾸는 방법은 무엇입니까?

sed를 사용하여 Dockerfile에서 변수를 할당하고 구성 파일 내용을 바꾸는 방법은 무엇입니까?

실행 중이지만 수정을 위한 변수와 해당 문자열 내용 "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/07/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가 애플리케이션 사용자로 실행되고 구성 패치에 루트 권한이 필요한 경우 문제가 방지됩니다.

답변2

다들 감사 해요. 내 문제는 구분 기호에 있습니다. "/"를 ":"으로 변경했는데 제대로 작동했습니다. 여기에 결과를 게시하겠습니다. "65/78단계"에서는 스크립트 내용을 인쇄했고 "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

RUN나는 Docker에 익숙하지 않습니다. 명령 입니다 . 하나만 필요하다면하나의명령을 내린 다음 사용하세요.

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

관련 정보