A ver, seamos directos. Hay veces que necesitas mover una imagen Docker de una máquina a otra y, por la razón que sea, no tienes un registry disponible o simplemente no quieres pasar por el lío de configurarlo. Tienes dos caminos principales para hacer esto, y el que elijas depende mucho de tu contexto.
El camino explícito: docker save y docker load
Esta es la forma más obvia y, de hecho, la que más uso si no hay complicaciones. Consiste en guardar tu imagen como un archivo .tar, transferir ese archivo como harías con cualquier otro, y luego cargarlo en la máquina de destino. Simple, ¿no?
Para guardar la imagen:
docker save -o mi_aplicacion.tar mi_aplicacion:latest
Luego, copias ese archivo a la máquina de destino. Puedes usar scp, rsync, o incluso una unidad USB si estás en la misma oficina o datacenter. Por ejemplo:
scp mi_aplicacion.tar usuario@servidor_destino:/tmp/
Y en la máquina de destino, la cargas:
docker load -i /tmp/mi_aplicacion.tar
Esto me ha salvado un par de veces cuando un cliente tenía una red tan segmentada que hasta un registry privado era un dolor de cabeza de configurar. Era más rápido mover el archivo a mano y listo. Tienes control total del archivo, lo puedes guardar, hacerle un backup. Es fácil de debugear si algo falla en la transferencia.
El pipe directo con SSH y compresión: Para los 'power users'
Pero, ¿qué pasa si tu imagen es gigante, la red es lenta o simplemente quieres hacer todo en una sola línea de comando? Aquí entra en juego la magia de los pipes de Bash y SSH. Puedes guardar, comprimir y transferir tu imagen en un solo flujo, sin necesidad de un archivo intermedio.
docker save mi_aplicacion:latest | bzip2 | ssh usuario@servidor_destino 'docker load'
Esta solución es elegante, especialmente útil cuando la red es tu enemigo. Puedes usar bzip2 (más lento, mejor compresión), gzip (más rápido, compresión decente) o xz (el que más comprime, más lento) para adaptarte a tu conexión. Ojo que puedes meterle pv en el medio para ver el progreso, lo que siempre se agradece cuando no sabes si la transferencia sigue viva o se murió el túnel SSH:
docker save mi_aplicacion:latest | bzip2 | pv | ssh usuario@servidor_destino 'docker load'
Soy honesto, esta solución me costó entenderla bien al principio. Pensaba, '¿por qué no hago un archivo y listo?'. Pero cuando tienes que mover 10GB por una conexión de esas que se caen cada cinco minutos, o necesitas automatizar la copia de muchas imágenes, entiendes el valor de la compresión en tiempo real y de no tener archivos temporales en el disco. De hecho, es bastante eficiente.
El tradeoff real
Al final, no hay una única respuesta. La opción de docker save y docker load es ideal para la simplicidad, si necesitas un archivo físico, si tu red es fiable y no estás moviendo cosas gigantescas. Es clara y fácil de entender.
El pipe con SSH, por otro lado, brilla cuando necesitas eficiencia en redes lentas, con imágenes muy grandes, o si quieres un one-liner para automatización. Eso sí, requiere que tengas las herramientas de compresión (bzip2, gzip, etc.) y SSH bien configurado en ambas puntas, y puede ser más difícil de debugear si el pipe se rompe a mitad de camino.
Yo, en mi caso, prefiero la claridad del archivo intermedio para el día a día, a menos que la situación de red o la escala de la operación me obligue a ir por el pipe directo. ¿Qué prefieres tú cuando tienes que mover tus imágenes Docker?