Como atribuir variável e usar sed para substituir o conteúdo do arquivo de configuração no Dockerfile?

1

Estou executando um Dockerfile , mas estou encontrando um problema quando atribuo uma variável para modificar /etc/fail2ban/jail.local , com seu conteúdo de cadeia de caracteres "PRIVATEIP".

Dockerfile gera um erro e pára. Porque eu não tenho idéia sobre como atribuir uma variável com sed para modificar o conteúdo da string em um arquivo específico.

RUN IP=$(cat /root/ip_variable) | sed -i -r "s/PRIVATEIP/${IP}/g" /etc/fail2ban/jail.local
 ---> Running in 1e78ef4318ab

Se houver algum método alternativo para lidar com isso, avise-nos.

=============================================== ============================

Adicione mais explicações para um método alternativo, conforme abaixo, em 2018/11 de julho:

Eu adiciono algumas linhas de comando no Dockerfile. O objetivo é o mesmo de antes. Eu uso alternativamente o eco para escrever um script como abaixo. Mas é estranho. Por que o personagem companheiro "/" depois de "s" em "sed" esse comando é perdido? (Se houver algum método para adicionar luz alta ou marcar o caractere na saída do código, agradeço a você.) Se esse problema for resolvido, acho que posso fechar esses problemas.

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
    
por jefferyear 09.07.2018 / 05:32

3 respostas

0

Obrigado a todos. Eu o assunto está no delimitador. Eu mudo "/" para ser ":" e trabalhe. Eu posto o resultado aqui. Na "Etapa 65/78", imprimo o conteúdo do script e "Etapa 67/78" executa bem o script. Obrigado @xenoid e @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
    
por 11.07.2018 / 18:10
1

Isso funciona para mim:

FROM alpine

COPY ipaddr /ipaddr
COPY ipconf /ipconf
RUN export IPADDR=$(cat /ipaddr) ; sed -i -r "s/IPADDR/${IPADDR}/g" /ipconf
CMD cat /ipconf

Com ipconf & ipaddr

IP address is IPADDR

1.2.3.4

Então:

>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

No entanto, é exatamente assim que eu não faria isso. Uma maneira melhor é usar um argumento de construção:

FROM alpine

COPY ipconf /ipconf
ARG IPADDR
RUN sed -i -r "s/IPADDR/${IPADDR}/g" /ipconf
CMD cat /ipconf

Então:

>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

No entanto, não tenho certeza se esta é a solução correta. Eu também:

  • crie o arquivo de configuração fora do contêiner e crie / substitua-o por um COPY . Isso dá controle total sobre seu conteúdo.
  • passa esse endereço IP como um parâmetro quando o contêiner é executado (variável de ambiente ou outra), portanto, você tem uma única imagem de contêiner que pode ser usada em vários ambientes. O CMD ou ENTRYPOINT pode ser um script que corrige o arquivo antes de chamar o comando principal. Você também pode passar o arquivo de configuração como um VOLUME (isso pode evitar problemas se o CMD for executado como um usuário do aplicativo e a correção da configuração exigir privilégios de root).
por 11.07.2018 / 10:38
0

Uma atribuição não produz saída e, portanto, é inútil canalizá-la para outro processo.

Em vez disso, use ; para dividir o inte do pipeline em dois comandos sequenciais:

IP=$(cat /root/ip_variable); sed -i "s/PRIVATEIP/$IP/g" /etc/fail2ban/jail.local

Eu não estou familiarizado com o Docker e seu comando RUN . Se for necessário apenas um comando single , use

RUN sh -c 'IP=$(cat /root/ip_variable); sed -i "s/PRIVATEIP/$IP/g" /etc/fail2ban/jail.local'

ou

RUN sed -i "s/PRIVATEIP/$(cat /root/ip_variable)/g" /etc/fail2ban/jail.local
    
por 09.07.2018 / 08:05