How Should I Get Application Configuration into my Docker Containers?

A commonly asked question by folks that are deploying their first Docker containers into production is, “How should I get application configuration into my Docker container?” The configuration in question could be settings like the number of worker processes for a web service to run with, JVM max heap size, or the connection string for a database. The reality is that there are several standard ways to do this, each with their own pros and cons.

The ~3.5 Ways to Send Configuration to your Dockerized Apps

1. Baking the Configuration into the Container

Baking your application’s configuration into a Docker image is perhaps the easiest pattern to understand. Basically one can use commands within the “Dockerfile” to drop configuration files into the right places via the Dockerfile’s COPY directive, or modify those configuration files at image build time with “sed” or ”echo” via the RUN command.

If there’s a container available on the Docker Hub Registry that does everything you want save for one or two config settings, you could fork that “Dockerfile” on GitHub, make modifications to the “Dockerfile” in your GitHub fork to drop in whatever configuration changes you want, then add it as a new container on the Docker Hub Registry.

That is what I did for:



  • Since the configuration is baked into the image, any future configuration changes will require additional modifications to the image’s build file (its “Dockerfile”) and a new build of the container image itself.

2a. Setting the Application Configuration Dynamically via Environment Variables

This is a commonly-used pattern for images on the Docker Hub Registry. For an example, see the environment variables “POSTGRES_USER” and “POSTGRES_PASSWORD” for the official PostgreSQL Docker image.

Basically, when you “docker run” you will pass in pre-defined environment variables like so: "docker run -e SETTING1=foo -e SETTING2=bar ... <image name>". From there, the container’s entry point (startup script) will look for those environment variables, and “sed” or “echo” them into whatever relevant config files the application uses before actually starting the app.

It’s worth mentioning that the container’s entry point script should contain reasonable defaults for each of those environment variables if the invoker does not pass those environment variables in, so that the container will always be able to start successfully. 


  • This approach makes your container more dynamic in terms of configuration. 


  • You are sacrificing dev/prod parity because now folks can configure the container to behave differently in dev & prod.
  • Some configurations are too complex to model with simple key/value pairs, for example an nginx/apache virtual host configuration.

2b. Setting the Application Configuration Dynamically via Environment Variables

This is a similar idea to using environment variables to pass in configuration, but instead the container’s startup script will reach out to a key-value (KV) store on the network like Consul or etcd to get configuration parameters.

This makes it possible to do more complex configurations than is possible with simple environment variables, because the KV store can have a hierarchical structure of many levels. It’s worth noting that widely-used tooling exists for grabbing the values from the KV store substituting them into your config files. Tools like confd even allow for automatic app-reloading upon changes to the KV configuration. This allows you to make your app’s configuration truly dynamic!



  • This approach makes your container more dynamic in terms of configuration.
  • The KV store allows for more complex & dynamic configuration information 


  • This introduces an external dependency of the KV store, which must be highly-available.
  • You are sacrificing dev/prod parity because now folks can configure the container to behave differently in dev & prod.

3. Map the Config Files in Directly via Docker Volumes

Docker Volumes allow you to map any file/directory from the host OS into a container, like so: “docker run -v <source path>:<dest path> ...”

Therefore if the config file(s) for your containerized app happened to be available on the filesystem of the base OS, then you could map that config file (or dir) into the container. Ex:

“docker run -v /home/dan/my_statsd_config.conf:/etc/statsd.conf hopsoft/graphite-statsd”


  • You don’t have to modify the container to get arbitrary configurations in.


  • You lose dev/prod parity because now your app’s config can be anything
  • If you’re doing this in production, now you have to get that external config file onto the base OS for sharing into the container (a configuration management tool like Ansible, Chef, or Puppet comes in handy here)


As you can see, there are many potential ways to get application configuration to your Dockerized apps, each with their own trade-offs. Which way is best? It really depends on how much dynamism you require and whether or not you want the extra burden of managing dependencies like a KV store.

12 thoughts on “How Should I Get Application Configuration into my Docker Containers?

  1. Pingback: 1p – How Should I Get Application Configuration into My Docker Containers? | Profit Goals

  2. Pingback: 1p – How Should I Get Application Configuration into My Docker Containers? – Exploding Ads

  3. Alternatively, you can also use Tiller ( which provides a standardized, easy to use way of generating configuration files. Many containers already use it, as it can generate configuration files from a variety of sources: environment variables; a HTTP webservice; zookeeper cluster; or even just plain YAML files on disk. I wrote it specifically so that you can build a single Docker container, but ship configuration files for different environments (or let users specify parameters at run time). As it has a plugin architecture, you could say it sort of combines points 1 & 2 in your examples above.

  4. I think you’re taking “dev/prod parity” a little too far. Transient configurables like names and addresses don’t have to be the same between dev and prod; the more important idea is that the the tools and infrastructure are as close as possible. Moreover, you do not want to be baking sensitive information like the password to your production database into a container image. Otherwise, you will have to lock down the custody chain for the image, which is almost certainly going to create more problems than it solves.

  5. I appreciate that most software is configured by configuration files located somewhere distinctly separate for that application (e.g. /etc/) but what if the configuration is in a database that is modified after the container starts?

  6. Nice and concise. I note that where those variables might be secret is not covered in terms of pros and cons. It does convey that the problem of managing variable configuration has not gone away with the magic container bullet. Really practical way to get started with the actual use case though, thank you.

  7. I’m still new to Docker but not to separation of environments. It sometimes can simply come down to how you’re environments are configured. eg.

    1. your dev environment domain is, your prod is
    2. your /etc/resolv.conf has search for those domains in each environment.
    3. your apps now just request db connections to : db, for production, for dev.

    this way configs are the same but where they end up is different. some other things can be done this way too but this may not work for everything.

    CNAME->CNAME->HOST is also another trick. eg -> ->
    if the app-db needs to change, change the pointer to a different cluster. if app the apps using this db has to move, you move the cluster-db-1 to point to the new db-X back end.. all without changing the application.

  8. Is there a 4th option? Is it possible to put your configuration settings or files into another “File” container and just link the application container to the configuration container?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s