Managing Dockerfile dynamically for different tenants in CI/CD pipeline implementation

Quoting from 12 Factor - Config

An app’s config is everything that is likely to vary between deploys (staging, production, developer environments, etc). This includes:

  • Resource handles to the database, Memcached, and other backing services

  • Credentials to external services such as Amazon S3 or Twitter

  • Per-deploy values such as the canonical hostname for the deploy

You should not build separate docker images for each tenant as the binary should be the same and any runtime configurations should be injected through the environment.

There are different options to inject runtime configuration

  1. Environment variables

Instead of hardcoding the profile in the entrypoint add a environment variable

ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=$TENANT_PROFILE" , "TestProject.war"]

Then inject the environment variable from the kubernetes deployment configuration Refer https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/

  1. Mount the profile configuration as a config and refer it

Your entrypoint will look like

ENTRYPOINT ["java", "-jar", --spring.config.location="file:/path/to/tenantconfig.yaml" , "TestProject.war"] Then mount the required config file as a kubernetes config.

Either way externalize the runtime configuration from the docker image and inject it through the deployment configuration as a environment variable or a config.


You can make use of docker ARGS, this will only be available at build time and this can used at entrypoint.

docker build --build-arg CONFIG_FILE=<file_name> -t tag_name .

CONFIG_FILE will hold the location of config file and you can pass it dynamically. Replace your entry point with $CONFIG_FILE

ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=$CONFIG_FILE" , "TestProject.war"]