In Object Oriented Programming (OOP) there are Design Patterns (DP). DP are best practices for tackling certain problems. For example, a singleton is acceptable to be used in a logger class.

What about applying DPs to creation of images, e.g. docker. In our situation we have the core, i.e. the application, application configuration (customization per customer), and different artifacts per customer.

At the moment, a bash script is used that contains various if-else statements and it is getting more and more a spaghetti.

  • 2
    this is quite interesting and challenging question: would you share a couple of (pseudocode-formatted) if-else passages to make it more clear? that is, that seems that design patterns is a high level consideration, yet current problem is spaghetti bash code. What functional blocks are there to abstract from? – Peter Muryshkin Mar 15 '18 at 7:00

The general design pattern is one container = one running service - see the initial comment at https://docs.docker.com/config/containers/multi-service_container/

Now, after spending about a year developing a multi-service application relying heavily on docker this is what works for me:

Avoid creating files inside the container unless it is your storage engine - in which case use volumes (recommended by Docker and also common sense) - we use Elasticsearch for that.

If I need multiple custom configurations I am trying to either load it from somewhere (DB, Environment) or I mount the configuration as a volume like

-v config.yml:/usr/src/app/config.yml

In general, we have one service = one repository, but sometimes you have to copy all the dependencies in order to just create one script. So we have one repository where these scripts are aggregated and I change the CMD with an environment variable like this:

CMD cd /usr/src/app && python -u $RUN_SCRIPT

It can be probably improved with a combination of ENTRYPOINT and CMD as described here http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/

Then we use various docker-compose.yml files for getting the setup we need.

For some operations (like DB setup) we either run one container like

docker run --network ournetwork init-profiling

or I can run a command inside that container

docker run -it --network ournetwork init-profiling bash
# run_command.sh

We spent some time minimizing the footprint of containers, they can quickly get bloated. For example, we use a common base image for our python containers. Also, things like pip freeze do make sense only if you use a separate virtual environment for each repository/container.

We do not use swarm/kubernetes for now, so I cannot add any additional guidelines for that.

  • Do the developers in your company docker themselves? In what way has DTAP been implemented in terms of using docker in every phase? – 030 Apr 10 '18 at 14:39
  • We have now a stable set of services so after creating the new repository the developers usually do git commit + Jenkins for building and putting the containers into AWS ECS repository (dev/stage/prod branches and environments). The new deployment is mostly checkout docker-compose, docker-compose pull and docker-compose up. It's not perfect, but it works. It's a little bit more complex than this, but this is the core. – petrchpetr Apr 10 '18 at 19:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.