No caso de alguém achar isso útil, eu escrevi um script shell fish
(deve ser facilmente transportável para bash
) usando docker inspect
para iniciar todas as dependências dos meus contêineres. Aqui está o código, usando jq para analisar o json:
#!/usr/local/bin/fish
# Start all containers
# Returns all the dependencies of the input + the input, eg. [dep1, dep2, input]
function docker_links_lookup
set result (docker inspect $argv[1] | jq ".[0].HostConfig.Links" | pcregrep -o1 "\"/(.*):.*\"")
for x in $result
docker_links_lookup $x
echo $x
end
end
# Returns all docker containers in the current directory, including their dependencies
function all_docker_containers
for dir in */
if test -f "$dir/Dockerfile"
set container_name (echo $dir | sed "s/\///") #remove trailing /
docker_links_lookup $container_name
echo "$container_name"
end
end
end
# Take all docker containers and dependencies, filter out duplicates without changing the order (the awk command), then start the containers in that order
all_docker_containers | awk '!seen[$0]++' | xargs docker start
Observe que esse código pressupõe que há subdiretórios no diretório atual que correspondem a um contêiner docker com o mesmo nome. Também não lida com dependências circulares (não sei se alguma das outras ferramentas o faz), mas também foi escrito em menos de meia hora. Se você tiver apenas um único contêiner, basta usar a função docker_links_lookup
assim:
docker_links_lookup {{container_name}} | awk '!seen[$0]++' | xargs docker start
Editar:
Outra função útil que comecei a usar no script acima é esta:
# This starts the docker containers that are passed in, and waits on the ports they expose
function start_and_wait
for container in $argv
set ports (docker inspect $container | jq ".[0].Config.ExposedPorts | keys" 2>/dev/null | egrep -o "[0-9]+" | xargs)
docker start $container
docker run -e PORTS="$ports" --link $container:wait_for_this n3llyb0y/wait > /dev/null
end
end
Em vez de apenas iniciar um contêiner, ele procura as portas que o contêiner expõe e testa para ver se ele pode se conectar a elas. Útil se você tiver coisas como um contêiner de banco de dados, que pode executar limpezas quando é iniciado e, portanto, levar algum tempo para realmente estar disponível na rede. Use assim:
start_and_wait {{container_name}}
Ou, caso você esteja usando o script acima, substitua a última linha por:
start_and_wait (all_docker_containers | awk '!seen[$0]++' | xargs -n 1)
Esta última linha garantirá que todos os contêineres sejam iniciados somente após suas dependências, enquanto aguardam que as dependências realmente concluam sua inicialização. Observe que isso provavelmente não é aplicável a todas as configurações, pois alguns servidores podem abrir suas portas imediatamente, sem estarem realmente prontos (embora eu não conheça nenhum servidor que realmente faça isso, mas essa é a razão pela qual os desenvolvedores do docker perguntam quando perguntam -los sobre um recurso como este).