Execute um script no Dockerfile

97

Estou tentando executar um script durante meu processo de construção no meu Dockerfile. Mas não parece funcionar.

Eu tentei assim:

FROM php:7-fpm
ADD bootstrap.sh /
ENTRYPOINT ["/bin/bash", "/bootstrap.sh"]

Também desta forma:

FROM php:7-fpm    
ADD bootstrap.sh /
RUN bash -c "/bootstrap.sh"

E também executando meu contêiner em execução:

docker exec symfony /bin/bash -c "/bootstrap.sh"

Nada parece funcionar.

Você sabe como fazê-lo?

Kevin
fonte
O bootstarp.shbit executável está definido?
jwodder
Como aquele RUN chmod + x /bootstarp.sh?
Kevin
2
Com "não funciona", o que exatamente está acontecendo? Isso mostra um erro? O arquivo está presente dentro da imagem? Se você estiver docker exec -it symfony bashdentro do contêiner, poderá executar o script manualmente e verificar seu conteúdo? ( cat bootstarp.sh)?
thaJeztah 01 de
tente isto: docker exec symfony /bin/bash /bootstarp.she me diga o resultado.
Boynux
13
Ermahgerd bootstarp!
Bruno Bronosky

Respostas:

135

RUNe ENTRYPOINTsão duas maneiras diferentes de executar um script.

RUNsignifica que ele cria um contêiner intermediário, executa o script e congela o novo estado desse contêiner em uma nova imagem intermediária. O script não será executado depois disso: sua imagem final deve refletir o resultado desse script.

ENTRYPOINT significa que sua imagem (que ainda não executou o script) criará um contêiner e executará esse script.

Em ambos os casos, o script precisa ser adicionado e RUN chmod +x /bootstrap.shé uma boa ideia.

Também deve começar com um shebang (como #!/bin/sh)

Considerando seu script ( bootstarp.sh: alguns git config --globalcomandos), seria melhor usar RUNesse script uma vez em seu Dockerfile, mas certifique-se de usar o usuário certo (o git configarquivo global é %HOME%/.gitconfig, que por padrão é o /rootúnico)

Adicione ao seu Dockerfile:

RUN /bootstart.sh

Em seguida, ao executar um contêiner, verifique o conteúdo de /root/.gitconfigpara confirmar se o script foi executado.

VonC
fonte
5
Além disso, você pode querer dizer em bootstrap.shvez de bootstarp.sh: consulte stackoverflow.com/a/1254561/6309
VonC 01 de
Legal! Funciona muito bem com RUN /bootstrap.sh
Kevin
1
A coisa da primeira linha fez isso por mim, obrigado! :)
GDICommander de
36

Além das respostas acima:

Se você criou / editou seu arquivo de script .sh no Windows, certifique-se de que ele foi salvo com a linha terminando no formato Unix . Por padrão, muitos editores no Windows converterão as terminações de linha do Unix para o formato do Windows e o Linux não reconhecerá o shebang (#! / Bin / sh) no início do arquivo. Então o Linux irá produzir a mensagem de erro como se não houvesse shebang.

Dicas:

  • Se você usa o Notepad ++, você precisa clicar em "Editar / Conversão EOL / UNIX (LF)"
  • Se você usar o Visual Studio, sugiro instalar o plugin " End Of Line ". Em seguida, você pode tornar as terminações de linha visíveis pressionando Ctrl-R, Ctrl-W. E para definir terminações no estilo Linux, você pode pressionar Ctrl-R, Ctrl-L. Para o estilo Windows, pressione Ctrl-R, Ctrl-C.
VeganHunter
fonte
4
Uau, você salvou meu dia. Obrigado por isso.
mw
2
Brilhante! este era o meu EXATO problema!
Kevinsyel
1
Meu VSCode definiu automaticamente as terminações alinhadas de um script de shell para CRLF no Windows. A compilação do docker estava falhando devido a alguns caracteres aleatórios. Mudei as configurações do VS Code e imediatamente começou a funcionar. Obrigado! Eu votei a favor.
Adithya Upadhya
24

Tente criar um script com ADDcomando e especificação de diretório de trabalho Assim ("script" é o nome do script e /root/script.shé onde você deseja no container, pode ser um caminho diferente:

ADD script.sh /root/script.sh

Neste caso ADDtem que vir antes CMD, se você tiver um BTW, é uma maneira legal de importar scripts para qualquer local no contêiner da máquina host

No CMDlugar[./script]

Deve executar automaticamente o seu script

Você também pode especificar WORKDIRcomo /root, então você será automaticamente colocado na raiz, ao iniciar um contêiner

Michael
fonte
Como o docker identifica onde script.sh está inicialmente? Quer dizer, o primeiro parâmetro,script.sh
pôr do sol
já que você está construindo o contêiner, você também é responsável por colocar os caminhos
Michael
o caminho e o nome do primeiro parâmetro script.shé relativo aoDockerfile
eja
3

É uma prática recomendada usar em COPYvez de ADDao copiar do sistema de arquivos local para a imagem. Além disso, recomendo criar uma subpasta para colocar seu conteúdo. No mínimo, mantém as coisas organizadas. Certifique-se de marcar o script como executável usando chmod.

Aqui, estou criando uma scriptssubpasta para colocar meu script e executá-lo:

RUN mkdir -p /scripts
COPY script.sh /scripts
WORKDIR /scripts
RUN chmod +x script.sh
RUN script.sh
ldobson
fonte
0
WORKDIR /scripts
COPY bootstrap.sh .
RUN ./bootstrap.sh 
Anthony Awuley
fonte
Olá e bem-vindo ao SO! Embora este código possa responder à pergunta, fornecer contexto adicional sobre como e / ou por que ele resolve o problema melhoraria o valor da resposta a longo prazo. Leia o tour e como escrevo uma boa resposta?
Tomer Shetah