There are a lot of benefits when you’re running applications on Docker. For one, you don’t have to set up different development environments for each version of your application. For instance, if you’re creating a Maven and Java-based application and you’ret using Docker, you would need to install both Maven and JDK on your machine. But using Docker, you only have to get the Maven image from the Docker Hub and then use that image to create, test, and run your applications.
Speaking of testing, you can also rely on Docker to easily test your application on different database frameworks, different Java versions, and other run time variations. It can effortlessly give you all the test environments you need by putting your applications and databases in multiple containers.
And you’ll also appreciate how it makes packaging and deployment a whole lot easier and simpler. An application that runs on your local machine using a Docker container will run on any of your target servers. You can package your applications in a container and include the dependencies and configurations to ensure that it will work on another machine, in test environments, and even in production. You do not have to worry about installing the same set of configurations on different machines.
How can you get your application’s configuration onto Docker containers?
1. Just bake the application configuration into the Docker container.
The easiest way is to just put all your configurations into a Docker container and then make the Dockerfile, which contains all the configuration settings, available for download. You can change the configurations using sed or echo through the RUN command.
It’s easy, too. If there is an available container on the Docker Hub Registry that has the most of the configurations you want to use, you can just fork that particular Dockerfile on GitHub and create the changes to make it fully conform to the configuration you want. After making the modifications, you can just add it as a new container on the Docker Hub Registry.
The good thing about this method is that you can get the same development and production environments because these will use the same configuration settings within the container image.
However, because the configuration settings are baked into the image, you might have to do more when you want to introduce some changes in the future, such as needing to have additional revisions to the build file or Dockerfile and then adding a new build of the image itself.
2. Use environment variables.
There is also another reason why baking the configuration into the image would be a bad idea. If you want your application to run in different versions, you would end up having a lot of Docker containers for each version. Now, how about being able to use environment variables?
Docker allows you to store configuration settings, external resource addresses, encryption keys, and other data in environment variables. When you run your application, these environment variables are then checked and the relevant files are inserted into your app before it is launched.
There are two ways to introduce environment variables into the application configuration.
The first is to include pre-set environment variables during docker run. The docker run will check the container’s startup script, look for the right environment variables, and then echo or sed them into the relevant config files that your application uses. All this happens before the app is even started.
The benefit of this approach is that you can make your container a whole lot more dynamic, especially when it comes to configuration. However, there are three things that you should consider:
- Your container’s entry point script should have enough defaults for each of the environment variables that you use; so that it will start without hitches even when the user does not specify values for these variables.
- You will not have the same production and development environments because the user can now configure the container to act differently.
- There will always be configurations, such as NGINX/Apache virtual host configurations that are too complex and you cannot use simple key and value pairs for these configurations.
3. Find another way to use environment variables.
Working on the same principle as above, you can also use key value stores on the network to help serve configuration parameters. These stores, such as etcd and consul, are accessed by the container’s own startup script.
With this method, you can deal with more complex configurations because the key value store can handle hierarchies with many different levels. Not only that, there are several tools available that would help you write scripts that work with key value stores, such as confd. Confd even has a way to automatically reload apps when there are changes to the key value configuration, making your configuration very dynamic.
The benefits of using this method are that you have more dynamic containers as far as configurations are concerned, plus it can manage more complex configuration settings. However, you will be introducing an external dependency, and that should be always-available. And you cannot say that you have the same development and production environments, because users can now set the container to behave rather differently in production environments.
These are the two ways you can use environment variables to pass configuration values to your Docker containers.
There is yet another way to get your configuration files with Docker – and that is to map the configuration files using Docker Volumes.
Docker Volumes lets you map any directory or file from the host operating system into a container using
docker run -v <source path>:<destination path> ...
This way, the configuration files that are found in the base operating system could be used by the containerized app.
This will be very beneficial if you do not want to change the container – when you are only trying to include arbitrary configurations. However, you again lose the parity between your production and development environments. Further, if you do this method during production, you would need to put that external configuration file on your base operating system to enable the containerized app to use it. You can use Puppet, Chef, Ansible or any other configuration management tools to make this easier. (Check out our list of 51 third-party Docker tools for more tools you can use to get more out of Docker.)
Additional Resources and Tutorials
For more information on container configuration and using environment variables, check out the following resources and tutorials:
- Tiller Project and Docker Container Configuration
- How do I pass environment variables to Docker containers?
- Best way to pass config file during Docker build
- Environment variables in Compose
- How can I use environment variables in Nginx.conf
Docker is a game-changer for application development; you can even use it with ASP.NET. No matter how you configure your applications, few things will help you troubleshoot your code better than log files. Our Docker Logging 101 guide offers a helpful primer on Docker logs and best practices to help you get the most from your logs.
- Constructing Test Cases That Don’t Suck (and How to Avoid Common Mistakes) - August 21, 2017
- 35 Leading PaaS Providers Offering Built-In Infrastructure and Scalability - August 21, 2017
- Biggest Mistakes Companies Make When Evaluating & Purchasing APM Software - August 18, 2017
- Why Security Should be Top-of-Mind for Developers - August 16, 2017
- ViewBag 101: How It Works, When It’s Used, Code Examples, and More - August 11, 2017