Introducción
Hasta ahora, hemos creado una aplicación Hello World con Spring Boot, la hemos compilado con Maven y la hemos ejecutado correctamente en nuestro equipo. Sin embargo, ejecutar una aplicación en local es solo el primer paso.
En cuanto queremos compartirla, desplegarla en un servidor o moverla entre distintos entornos (desarrollo, pruebas, producción), empiezan a aparecer los problemas clásicos: versiones diferentes de Java, dependencias que no coinciden, configuraciones específicas de la máquina o incluso sistemas operativos diferentes.
Aquí es donde encapsular la aplicación en un contenedor se convierte en el siguiente paso natural.
Qué es un contenedor
Un contenedor nos permite empaquetar la aplicación junto con todo lo que necesita para ejecutarse: la versión de Java, las dependencias y la configuración básica del entorno. El resultado es un paquete autocontenido que se comporta igual en cualquier máquina donde se ejecute.
Docker es una de las herramientas más extendidas para crear, ejecutar y gestionar contenedores de forma sencilla.
Configuración del contenedor
De forma similar al fichero pom.xml de Maven, para configurar un contenedor Docker usaremos un fichero Dockerfile (sin extensión) que se debe ubicar en la misma ruta del proyecto.
Con el siguiente Dockerfile mínimo se está creando de la forma más simple y limpia un contenedor Docker para ejecutar una aplicación Spring Boot:
| |
- En primer lugar se indica una imagen base para el contenedor. En este caso se trata de una distribución ligera de Linux con Java 21 (solo el entorno de ejecución), suficiente para ejecutar una aplicación Spring Boot.
- Después se indica el directorio de trabajo dentro del contenedor. A partir de aquí, todos los comandos se ejecutarán desde /app.
- Se copia el JAR generado por Maven desde el equipo anfitrión al contenedor, renombrándolo como app.jar. El nombre del JAR debe coincidir exactamente con el generado.
- Se indica el puerto en el que escucha la aplicación, que en Spring Boot suele ser el 8080 por defecto, pero a nivel informativo, no se abre el puerto.
- Por último, se define el comando que se ejecutará al arrancar el contenedor, lanzando la aplicación Spring Boot.
Construcción de la imagen
El primer paso es construir una imagen Docker a partir de la cual se podrán crear instancias del contenedor y desplegarlas.
Con Docker ejecutándose, y desde la raíz del proyecto, se lanza el siguiente comando:
| |
Qué significa:
-t helloWorld-api:1.0es el nombre y versión de la imagen..indica que se trabaja en el directorio actual, donde está el Dockerfile sobre el que generar la imagen.

Si todo va bien, podemos listar las imágenes del sistema con el comando docker images.

Ejecutar el contenedor
Para crear y ejecutar un contenedor a partir de la imagen generada, se lanza el siguiente comando:
| |
Qué significa:
-p 8080:8080indica el puerto del equipo donde se quieren recibir las peticiones del contenedor, seguido del puerto del contenedor a donde deben dirigirse. En este caso, usa el mismo.--name helloWorld-api-containerindica un nombre para identificar al contenedor.

De nuevo, si todo va bien, podremos abrir un navegador y acceder a la url http://localhost:8080 y ver el mensaje de ‘Hello World’, esta vez lanzado desde la API en el contenedor.

Para parar el contenedor, que se habrá quedado en la terminal, pulsamos la combinación de teclas Ctrl + C.
Otros comandos útiles
Ejecución del contenedor en segundo plano
Para no tener que mantener la ventana de terminal con el contenedor en ejecución, se puede lanzar en segundo plano añadiendo -d al comando run de la siguiente manera:
| |
Ver logs del contenedor
Para consultar los logs en la consola de Spring Boot dentro del contenedor, lanzamos el siguiente comando:
| |
Detener el contenedor
Al no estar ahora ligada la ejecución del contenedor a la sesión de terminal, para detenerlo, se debe lanzar el siguiente comando:
| |
Conclusiones
Ya hemos dado un paso clave: llevar nuestra aplicación Spring Boot desde un simple JAR hasta un contenedor ejecutable, garantizando que se comporta igual independientemente del entorno donde se despliegue.
El flujo que hemos seguido hasta ahora es muy sencillo, pero extremadamente importante:
- Hemos desarrollado una API sencilla en Spring Boot
- Con Apache Maven hemos generado un artefacto ejecutable (el JAR)
- Ese JAR lo hemos encapsulado en un contenedor usando Docker, resolviendo de un plumazo los problemas de dependencias, versiones y entornos.
- Hemos visto que desplegar la aplicación se reduce a construir una imagen y arrancar un contenedor.
A partir de aquí, se abre un abanico de mejoras naturales como optimizar el proceso, orquestar varios servicios y llegar a automatizar todo el flujo de construcción y despliegue. Todo ello de forma cercana a un entorno real de producción.