Context:

We've shifted to Docker for local development and remote testing environments of different applications. Previously, each application was standalone so docker images were built and supplied specifically for each application without a problem.

For each image, application code is mounted as a shared volume, but server configuration for that application such as the nginx server block and php-fpm pool are instead built into the image.

However, a new central application is to be introduced, and the existing applications are to become closely coupled to that application. This means the images now need to handle two or more applications at once for development.

To tackle this for local environments, my plan was to use a more generic approach to the docker image by setting it up as an empty webserver and having the app-specific server configuration mounted at container boot time.

To keep this easy for developers, the plan was to store the app-specific server configuration with the application's source code and have a docker-compose file which would handle the mounting, but I'm not sure if that's a good approach.

Drawbacks:

  • Server-based configuration and the application code are two different layers of the stack.. I'm unsure if the app repo is the best place for both layers.
  • Server configuration becomes frozen across environments unless you store different versions of config (for example, you'd want to allocate more php-fpm pool resources on remote staging that you may not have on local development).
  • The repository has to store information about the environment it's being deployed to rather than localised to the application's directory structure. For example - paths to log files, the full path to the document root, path to the fpm socket file, etc.
  • Our server infrastructure plays a part here - production is not containerised, which means maintaining similar config files in multiple locations (or risking an automated script to update the server configuration if required on deployments, but that's a whole other can of worms)
  • A bad commit can mess up the configuration. Bigger screw-ups would get caught on container boot, but more subtle problems may slip through the net without closely reviewing changes to the files.
  • With more happening on container boot, boot speed is impacted (even if it's only slightly slower).
  • TLS configuration. Private keys and signed certificates are not something I want to carry about in the repository. TLS could be disabled for local dev or self-signed certificates could be generated as part of the process.

Advantages:

  • Single location for managing server configuration.
  • New applications can be easily integrated using the same docker image and technique.
  • Changes to app configuration no longer require an image rebuild.

Assumptions:

  • The application and images are all privately hosted.
  • The server configuration holds absolutely zero secrets

The question - Is it worth storing server config with the application? I haven't really found articles online about a strategy like this, and I get the feeling that the trade-off for convenience actually opens up more problems in the long run.

  • This is similar to how Cloud Foundry applications are set up. A yaml file in the application specifies the settings for each environment, while secrets are stored as environment variables on the hosts. – Dan Wilson Sep 14 at 11:02
  • I'm not sure I quite follow your description of the various environments. But 12factor.net has some very good thoughts about config, in particular that environment-specific configuration should not be part of the image, but should be provided by that environment at run time. It's perfectly fine to check in a development configuration into source control that you can then provide to your containers. – amon Sep 14 at 11:22
  • @amon although I agree with the 12factor ideas mostly, they were written by Heroku engineers who limited themselves to ideas that would work on Heroku, so it's not entirely neutral. – Danack Sep 14 at 17:56
  • @Danack Yes, a critical reading is definitively advised. Some suggestions are quite opinionated, e.g. alternative config mechanisms (like files at pre-determined locations) can also work. But the 12-factor suggestion “the environment provides the config” is the best approach I know to deal with multiple environments. A small example: I worked on a project that had a checked-in default config file. I happily used that to run my tests, until one day a colleague walked up to my desk and asked me to stop using their database server – oops. That database config should never have been checked in. – amon Sep 14 at 18:27

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.