- Example of sample Docker container setup with Chef - https://github.com/maxivak/template-docker-chef-provisioning
-
Chef provisioning is a framework that allows clusters to be managed by the chef-client and the Chef server in the same way nodes are managed: with recipes.
-
Chef provisioning is a collection of resources that enable the creation of machines and machine infrastructures using the chef-client.
-
Read more: https://docs.chef.io/provisioning.html
We will use Chef provisioning to create a Docker container.
-
It assumes we have chef-repo on the workstation. This chef-repo contains common cookbooks.
-
Also we can have custom cookbooks.
-
Directory structure
our project:
/path/to/project/
|__ .chef/ - directory with settings for knife
|__ cookbooks/ - directory with cookbooks for the machine
|_ mycluster.rb
|_ destroy.rb
chef-repo - somewhere on the workstation
/path/to/chef-repo
|_ cookbooks
...
-
create directory .chef in your project
-
create
.chef/knife.rb
:
log_level :info
current_dir = File.dirname(__FILE__)
#node_name "provisioner"
#client_key "#{current_dir}/dummy.pem"
#validation_client_name "validator"
cookbook_path [ '/mydata/chef-repo/cookbooks', "#{current_dir}/../cookbooks" ]
include paths to cookbooks from chef-repo and to cookbooks in our project.
- Create file mycluster.rb:
require 'chef/provisioning'
with_driver 'docker'
machine 'mycontainer' do
action :converge
#recipe 'apt::default'
recipe 'base::default'
# attributes
attribute 'base', node['base']
#attribute 'java', node['java']
machine_options docker_options: {
base_image: {
name: 'ubuntu',
repository: 'ubuntu',
tag: '14.04'
},
#ENV (Environment Variables)
#Set any env var in the container by using one or more -e flags, even overriding those already defined by the developer with a Dockerfile ENV
:env => {
"deep" => 'purple',
"led" => 'zeppelin'
},
# Ports can be one of two forms:
# src_port (string or integer) is a pass-through, i.e 8022 or "9933"
# src:dst (string) is a map from src to dst, i.e "8022:8023" maps 8022 externally to 8023 in the container
# Example (multiple):
#:ports => ["9022:22"],
# Volumes can be one of three forms:
# src_volume (string) is volume to add to container, i.e. creates new volume inside container at "/tmp"
# src:dst (string) mounts host's directory src to container's dst, i.e "/tmp:/tmp1" mounts host's directory /tmp to container's /tmp1
# src:dst:mode (string) mounts host's directory src to container's dst with the specified mount option, i.e "/:/rootfs:ro" mounts read-only host's root (/) folder to container's /rootfs
# See more details on Docker volumes at https://github.com/docker/docker/blob/master/docs/sources/userguide/dockervolumes.md .
# Example (single):
#:volumes => "/tmp",
# Example (multiple):
#:volumes => ["/tmp:/tmp", "/:/rootfs:ro"],
# if you need to keep stdin open (i.e docker run -i)
# :keep_stdin_open => true
},
docker_connection: {
# optional, default timeout is 600
#:read_timeout => 1000,
}
end
It will run two recipes:
-
apt-get update
-
our recipe 'base'
-
Create recipe 'base' in cookbooks
-
cookbooks/base/recipes/default.rb
file '/tmp/1.txt' do
content "node attributes: #{node['base'].inspect}"
end
cookbooks/base/attributes/default.rb
- specify default attributes for recipe
default['base']['attr1'] = 'v1'
default['base']['attr2'] = 'v2'
- attributes in json file
# mymachine.json
{
"base": {
"sitename": "mysite.com",
"opt1": "11",
"opt2": "22"
}
}
- run provisioning
chef-client -z mycluster.rb -j mymachine.json
It will create a new Docker container named 'mycontainer' and run recipes. Recipe base will create a temp file '/tmp/1.txt' with contents. In our example it should contain:
# /tmp/1.txt
node attributes: {"sitename"=>"mysite.com", "opt1"=>"11", "opt2"=>"22"}
- Create file 'destroy.rb'
require 'chef/provisioning'
machine 'mycontainer' do
action :destroy
end
- run
chef-client -z destroy.rb
it will remove Docker container named 'mycontainer'
- Example of simple Docker container setup and provision with Chef - https://github.com/maxivak/template-docker-chef-provisioning