4

I'm building docker images for our servers, and I'm looking for the best practices related to multi environments support, when creating the DOCKERFILE(s).

The main purpose of the servers is to run LAMP on top of Centos 6, and I want to make the DOCKERFILE(s) as generic as possible to support both development and production environments. The images will have lot of common configurations / utils, and some differences.

Differences for example:

  • Production only: monitoring tools, AntiVirus and different LAMP configurations
  • Development only: xdebug, profiling utils and different LAMP configurations

I thought about using something like the following structure:

  • Customized Base OS (C1)
    • Prod. Base OS (C1E1)
    • Dev. Base OS (C1E2)
  • Web image (httpd, apache..) (C2)
    • Prod. adjustments (C2E1)
    • Dev. adjustments (C2E2)
  • DB image (C3)
    • Prod. adjustments (C3E1)
    • Dev. adjustments (C3E2)
  • Data image (C4)
    • Prod. adjustments (C4E1)
    • Dev. adjustments (C4E2)
  • Samba image (dev. only) (C5)

but as you can see, it is impossible to do it with the current inheritance mechanism, and even if it was, it is not maintainable.

I can't find a way to use ENV conditions within a DOCKERFILE (only with Linux based conditions in the RUN command for example).

At the moment I'm using the following structure:

  • Base Image (Common things, such as LAMP, utils..)
    • Dev. Image (Dev. specific utils / configuration)
    • Prod. Image (Prod. specific ...)

Are there any best practices for the above? Duplication of images (double maintenance) is the only possibility?

1 Answer 1

3

One of the concept of Docker is to have the same environment - if you have a different environment in production than dev, then you don't know that it will really work with full total certainty when the application is moved into production.

From docker.com:

Eliminate Environment Inconsistencies

By packaging up the application with its configs and dependencies together and shipping as a container, the application will always work as designed locally, on another machine, in test or production. No more worries about having to install the same configs into a different environment.

That said, of course production and dev will have differences, but that should be mostly in terms of application configuration - for example, the dev instance would not send out emails to customers but rather to a dummy mail box, etc.

I don't think it would be the right thing to do to have so much difference between production and dev as what you go over in your post.

As for the difference between the dev and production configuration (like the example I gave above), I personally see two workable ways of doing it.

  1. In Dev, a Dockerfile which overwrite certain configuration of a common base for both production and dev.

  2. Your container runs something - starts httpd, etc. The script that starts the process would first pull the config from Git or whatever repository, based on an environment variable (e.g. docker run ... -e RUNAS=PROD ...) - this is what I do. In my case, running a container for Tomcat, the Tomcat start up scripts simply downloads the war file version based on an environment variable (e.g. -e VERSION=current) and pulls from Git the configuration files based on a variable that defines whether it's production or dev (-e RUNAS=DEV).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .