Estou tentando criar um script de shell para configurar um contêiner do docker. Meu arquivo de script se parece com:
#!bin/bash
docker run -t -i -p 5902:5902 --name "mycontainer" --privileged myImage:new /bin/bash
A execução desse arquivo de script executará o contêiner em um bash recém-invocado.
Agora eu preciso executar um arquivo de script (test.sh) que já está dentro do contêiner do script de shell fornecido acima. (Por exemplo: cd /path/to/test.sh && ./test.sh) Como fazer isso?
WORKDIR
eCMD
?Respostas:
Você pode executar um comando em um contêiner em execução usando
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
:docker exec mycontainer /path/to/test.sh
E para executar a partir de uma sessão bash:
docker exec -it mycontainer /bin/bash
A partir daí, você pode executar seu script.
fonte
docker exec -i mycontainer bash < mylocal.sh
Isso lê o script do host local e o executa dentro do contêiner. Você pode fazer isso com outras coisas (como arquivos .tgz canalizados para o tar) - é apenas usar o '-i' para canalizar para a entrada std do processo de contêiner.Get-Content mylocal.sh | docker exec -i mycontainer bash
. Não sei se isso funciona.Supondo que seu contêiner do docker esteja instalado e funcionando, você pode executar comandos como:
docker exec mycontainer /bin/sh -c "cmd1;cmd2;...;cmdn"
fonte
/bin/sh -c "cmd1; cmd2; ...; cmdn"
) como o valor de uma variável de shell? Eu pergunto porque 'docker run' parece esperar um único comando e argumentos individuais não citados em vez de uma string entre aspas.cmd1
, eu preciso passar em um inteiro para-loop - mas espera que;
após o ciclo declaração e fazer declaração. Como posso executar todo o loop for como um único comando, ou sejacmd1
? É possível?Eu estava procurando uma resposta para esta mesma pergunta e encontrei a solução ENTRYPOINT no Dockerfile para mim.
Dockerfile
Agora os scripts são executados quando eu inicio o contêiner e recebo o prompt do bash após a execução dos scripts.
fonte
Você também pode montar um diretório local na imagem do docker e originar o script no seu
.bashrc
. Não se esqueça de que o script deve consistir em funções, a menos que você queira que ele seja executado em cada novo shell. (Isto está desatualizado, consulte o aviso de atualização.)Estou usando esta solução para poder atualizar o script fora da instância do docker. Dessa forma, não preciso executar a imagem novamente se ocorrerem alterações, apenas abro um novo shell. (Livre-se de reabrir um shell - consulte o aviso de atualização)
Aqui está como você vincula seu diretório atual:
docker run -it -v $PWD:/scripts $my_docker_build /bin/bash
Agora seu diretório atual está vinculado à
/scripts
sua instância do docker.(Desatualizado) Para salvar suas
.bashrc
alterações, envie sua imagem de trabalho com este comando:docker commit $container_id $my_docker_build
Atualizar
Para resolver o problema de abrir um novo shell para cada mudança, agora faço o seguinte:
No próprio dockerfile, acrescento
RUN echo "/scripts/bashrc" > /root/.bashrc"
. Dentrozshrc
, exporto o diretório de scripts para o caminho. O diretório de scripts agora contém vários arquivos em vez de um. Agora posso chamar diretamente todos os scripts sem ter que abrir um sub shell em cada mudança.BTW, você também pode definir o arquivo de histórico fora do seu contêiner. Dessa forma, não é mais necessário se comprometer com uma mudança de bash.
fonte
Caso você não queira (ou tenha) um container em execução, você pode chamar seu script diretamente com o
run
comando.Remova os
-i -t
argumentos tty iterativos e use isto:Isso (não testou) também funcionará para outros scripts:
fonte
Dê uma olhada nos pontos de entrada também. Você poderá usar vários CMD https://docs.docker.com/engine/reference/builder/#/entrypoint
fonte
Se você deseja executar o mesmo comando em várias instâncias, pode fazer o seguinte:
for i in c1 dm1 dm2 ds1 ds2 gtm_m gtm_sl; do docker exec -it $i /bin/bash -c "service sshd start"; done
fonte