El problema de partida era una aplicación Java + Spring ya dockerizada con dos entornos: local y docker. En el application.properties se iban comentando y descomentando valores manualmente para cambiar entre entornos, con el riesgo evidente de desplegar una configuración incorrecta.
Problema
Tener que modificar el fichero de propiedades para cambiar entre localhost y el contenedor de base de datos hacía el flujo frágil y propenso a errores.
Solución base
Spring no deja de ser una aplicación Java empaquetada que puede lanzarse con argumentos sobre java -jar. Esos argumentos tienen prioridad sobre el application.properties, por lo que es posible lanzar la aplicación así:
java -jar api-0.0.1.jar --spring.datasource.url=jdbc:postgresql://database:5432/license
Llevando esto a un Dockerfile, podemos fijar por defecto el valor apropiado para el entorno dockerizado:
FROM openjdk:12
EXPOSE 8080
CMD java -jar api-0.0.1.jar --spring.datasource.url=jdbc:postgresql://database:5432/license
Refinando la solución
Podemos ir un paso más allá permitiendo que el contenedor reciba parámetros externos. Para ello usamos ARG y ENV en el Dockerfile:
ARG datasource_url=jdbc:postgresql://database:5432/license
ENV DATASOURCE_URL ${datasource_url}
CMD java -jar api-0.0.1.jar --spring.datasource.url="${DATASOURCE_URL}"
Así, el contenedor apunta por defecto a la base de datos dockerizada, salvo que se le indique otro valor.
Y si usamos docker-compose
Si el ecosistema se levanta con docker-compose.yml, basta con usar args en el servicio correspondiente:
api:
build:
context: .
dockerfile: Dockerfile-api
args:
datasource_url: jdbc:postgresql://database:5432/license
Conclusión
La idea final es propagar una variable hacia capas más profundas, dejando un valor por defecto razonable en cada una:
docker-compose.yml: el valor que define quien despliega.Dockerfile: el valor por defecto para el entorno dockerizado.application.properties: el valor local.
Así reducimos cambios manuales, minimizamos errores de entorno y permitimos mayor flexibilidad sin complicar el uso de la aplicación.