I'm pretty new to Docker and configuration management tools.

At first I started writing bash scripts to provision my Vagrant boxes for my development machines, but now I've switched to using Chef for that so that I can use the same source to provision both development and production environments to try and get them as similar as possible.

Since I've started using Chef I've come to enjoy the DRY aspect of not having to copy and paste shell script lines from project to project, the ability to provision machines running a variety of linux distributions using one consolidated source, and the convenience of using community provided cookbooks.

Now that I've been using Chef to provision my vm's it feels like taking a step backwards when I am adding RUN commands followed by shell commands to a Dockerfile to achieve what could be achieved by just running a Chef recipe.

I've googled and haven't found anything (but maybe I just missed it) but it doesn't look like there is an easy way to use Chef recipes to build Docker containers. Why is that?

I understand that containers are meant to be immutable and configuration management tools are commonly used to re-configure machines during their entire lifespan, but wouldn't they still offer a lot of benefits if used during the initial building of the container?

  • 1
    Configuration Management tools can still be used immutably to configure your server/docker container/etc after it is provisioned. Then simply don't change the configuration and deploy a new one. Similarly, there is near-immutability with idempotency. Commented Nov 2, 2017 at 14:58
  • @JamesShewey Idempotent does not mean immutable. Immutable machines must be rolled in order to be updated.
    – Matt O.
    Commented Nov 2, 2017 at 17:54
  • @Matt O. Correct. But you can use an idempotent configuration management system to roll an immutable server. Once the rolled machine is brought back online, the configuration management system configures the system to the final, immutable state - installing packages, setting configuration files and starting services and such. Just because a system is idempotent does not mean it cannot also be immutable. It's just a matter of whether you decide to burn it down and redeploy when you make a change to the configuration, or whether you push that change out and update the existing system. Commented Nov 2, 2017 at 22:28

2 Answers 2


The tool you need is Packer using Docker as the "builder" and Chef as the "provisioner". Then you can add the resulting image to your repo and reuse it without having to pack again, until your recipes change.


These strategies have nothing to do with one another.

Containers (like Docker) are a methodology for deploying and isolating applications. Containers are well liked because they're transportable. They can be developed on and previewed locally in most cases, so putting applications in them makes sense.

As for why Docker uses shell scripting: A docker image is literally a linux container image. It's a linux operating system and the point of that container to be as lightweight and efficient as possible. If you started adding Chef, Ruby, Erlang, and all the other libraries required to have Chef as a provisioner on a Dockerfile you'd be eliminating the point of using containers.

Configuration Management is for provisioning a compute node. Your configuration end state is usually reflected in code and has a central server for maintaining state. Tools like vagrant allow you to use chef to configure Vagrant machines, largely out of convenience for developers. While you can use most of these tools in a local-only mode, the maintenance of them becomes quite burdensome. Those central servers are for things like automatically sorting out versioning and dependency management.

Bash is not inherently a step back. For instance, many organizations building fully immutable image pipelines build their images using Bash. This ensures stability and predictability as well as a common language among engineers (Many engineers may come from different config management backgrounds).

Immutable vs Config Management. Immutable infrastructure does not change and must be entirely replaced in order to be updated. Config Management implies that the state of a machine is maintained by an agent or foreign connection (like with Ansible).

Docker containers are inherently immutable. You don't persist data on them and they must be rolled in order to be updated.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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