Con Docker Swarm y los stacks puedes describir, versionar y automatizar despliegues multinodo con la misma sintaxis de Docker Compose. Además, controlas dónde corre cada servicio con constraints, inspeccionas tareas y puertos publicados, y actualizas repitiendo un único comando. Todo queda claro en un archivo legible que actúa como documentación viva de la arquitectura.
¿Qué es un stack en Docker Swarm?
Un stack es, en la práctica, un conjunto de servicios definido con un Compose file que Swarm entiende para correr en múltiples nodos. No es un objeto rígido: puedes administrar servicios por separado aunque pertenezcan al mismo stack. Su fuerza está en que reutiliza formato conocido y añade opciones pensadas para producción.
¿Cómo se relaciona con Docker Compose?
Usa el mismo archivo de Compose.
La sección deploy se ignora en docker compose, pero sí aplica en docker stack deploy.
Permite declarar placement y constraints para controlar el despliegue en nodos manager o worker.
¿Qué ventajas aporta como archivo versionado?
Trazabilidad: el archivo vive en GitHub o Bitbucket.
Claridad arquitectónica: “servicio A usa imagen X, servicio B usa imagen Y”.
Onboarding simple: quien llega nuevo entiende rápido servicios, imágenes y constraints.
¿Cómo desplegar, inspeccionar y actualizar servicios?
El flujo es directo: limpias lo anterior, despliegas el stack, inspeccionas servicios y tareas, y si editas el archivo, vuelves a desplegar para que Swarm aplique diferencias.
¿Cómo limpiar servicios y puertos previos?
Eliminar servicios libera puertos publicados.
dockerservicerm app db
¿Cómo desplegar con docker stack deploy?
Despliega el stack con un Compose file y un nombre.
En stack services verás puertos publicados por servicio.
En stack ps verás tareas por servicio.
Si defines réplicas, se reflejan en el conteo esperado/actual.
¿Cómo actualizar sin recrear todo?
Edita el archivo y vuelve a ejecutar el mismo comando.
docker stack deploy -c stack.yml app
Swarm detecta diferencias y rota solo lo necesario, por ejemplo reubicando tareas según nuevas reglas.
¿Cómo controlar el placement y la exposición?
Puedes decidir que ciertos servicios corran en workers y otros en managers, manteniendo conexiones internas mediante overlay network y publicando puertos solo donde corresponda. En entornos como Play With Docker, los puertos expuestos quedan accesibles desde el exterior.
¿Cómo fijar constraints de worker en el Compose?
Usa la sección deploy con placement constraints.
services:app:image: swarm-networking
# ... otras claves de Compose que ya usabasdeploy:placement:constraints:- node.role == worker
En docker compose esta sección se ignora. En docker stack deploytoma efecto.
¿Cómo ver puertos publicados y redes?
Con docker stack services app verificas puertos publicados por servicio.
Swarm crea automáticamente una overlay network para interconectar servicios del stack en múltiples nodos.
¿Te gustaría que revisemos un ejemplo con múltiples réplicas y distintos constraints por servicio? Cuéntame en comentarios qué arquitectura quieres desplegar y lo exploramos juntos.
Yaml es muy sensible a los espacios en blanco, a mi me marco muchos errores por tener espacio en blanco demás.
Esto sirve para validarlo:
Nos ayuda a simplificar la administración.
docker service rm app
docker service rm db
docker network rm app-net
docker stack deploy --compose-file stackfile.yml app
docker service ls
docker stack ls
docker stack ps app
docker stack services app
docker service scale app_app=3docker stack rm app
Lo que siempre debemos versionar y ejecutar es un archivo yml ya que tiene más funcionalidad que compose.
Aparte que es muy útil para describir la estructura de la aplicación.
Cuando ejecutas contenedores que se exponen en Play-with-docker, te aparece un link a los mismos en la parte superior, con el número de puerto que estás exponiendo.
En un swarm real (no Play-with-docker), lo accedes mediante tu navegador, con el IP de cualquiera de los nodos del swarm, y el puerto donde expusiste el visualizador.
Tengo ese stack, cuando se despliegan los servicios en nodos diferentes no pueden comunicarse uno con otro, ¿que me falta?
Saludos.
Para empezar, no deberías usar links, es un flag deprecado y no hay garantía de que funcione correctamente.
Por otra parte, qué comando estás usando?
Ahora no aparece el puerto, to le tienes que dar en open port y decirle que puerto vas a usar, tiene que el mismo puerto con el que lo expusiste.
ya hay demasiadas cosas que **no funcionan ** en este tutorial a esta fecha.
creo que es hora de actualizarlo para el bien de la comunidad interesada.
# deploy or redeploy stackfile with name "app"docker stack deploy --compose-file stackfile.yml app
#view stack
docker stack ls
docker stack ps app
docker stack services app
# remove stack "app"docker stack rm app
Tengo una pregunta para el profesor Guido, cuando se trabaja con infraestructuras de Amazon, es recomendable trabajar con ECS (Elastic Container Services), que tienen un sobre costo por el uso de recursos de máquina y que no son baratos, o se podría trabajar con la alternativa de levantar un cluster dentro de una imagen típica EC2, con todas las características de un entorno productivo?, muchas gracias de antemano por su valiosa respuesta.
Hola Guido,
Tengo una duda, quiero me gustaría un despliegue de una aplicación web en drupal (docker4drupal) con docker swarm, tengo 3 servicios:
Base de datos
PHP
Servidor web (nginx)
He realizado un volumen para el código de mi aplicación (subido a un repositorio GIT) en el servicio nginx
¿Cómo puedo hacer para que el código de mi aplicación esté dentro de mi servicio nginx?
¿y cómo importar los datos de mi base de datos?
Cuando he trabajado con php lo que hago es tener nginx y php en el mismo contenedor para tener todas las extensiones instaladas para que funcione el servidor web y un contenedor para la base de datos. Solo pasas como el host de la base de datos el alias que defines en networks para el contenedor de la base de datos.
networks:net:aliases:- mariadb
Con esto la url de la base de datos dentro de la red va a ser mariadb
Compartir volúmenes entre distintos servicios de un swarm puede ser complejo porque no hay garantía que los contenedores sean scheduleados en los mismos nodos, por lo que no tendrían acceso al mismo filesystem. Por lo tanto hay que pensar alternativas. Lo que te recomendaría es alguno de estos enfoques:
que uses nginx como reverse proxy y que delegue la petición a tu contenedor de PHP, así no tienes que compartir volúmenes
que compartas volúmenes entre nodos con algún driver especial para swarm volume sharing utilizando como backing storage un servicio de almacenamiento en la nube. El más popular open source es REX-Ray