Hoje eu estava tentando gerar uma imagem Docker a partir de um projeto Node.js e queria fazer o deploy no meu swarm local de testes.
Infelizmente, se alguém constrói uma imagem Docker local, essa imagem fica armazenada e acessível apenas no nó em que foi criada, e os outros nós do swarm não conseguem acessá-la.
A solução é enviar (push) a imagem para um registro Docker (registry), de onde ela pode ser baixada (pull) por todos os nós do swarm.
Criando o registro
Para instanciar um serviço de registro no swarm, execute:
docker service create —name registry —publish 5000:5000 registry:latest
Isso vai criar o serviço de registro e executá-lo no swarm, tornando-o acessível a todos os nós do swarm.
Enviando uma imagem para o registro
Para enviar uma imagem para o registro, você precisa fazer duas coisas – tagear e então fazer o push da imagem.
Aqui vai um exemplo de como construir e tagear a imagem de uma vez só:
docker build . -t localhost.localdomain:5000/
E como enviá-la para o registro:
docker push localhost.localdomain:5000/
Para usar a imagem em um serviço ou em um container, você especifica o caminho completo de cima, ou seja, localhost.localdomain:5000/<image-name>:latest.
Os nós do swarm vão ter acesso à imagem e conseguirão baixá-la e executá-la.
Nota importante sobre o endereço do registro
Na maioria dos tutoriais por aí, a URL do registro aparece como localhost:5000. Infelizmente isso não funciona e normalmente dá timeout quando se tenta usá-la. Se trocarmos para localhost.localdomain, funciona!
Não sei por que isso acontece, já que tanto localhost quanto localhost.localdomain resolvem para 127.0.0.1.