Create a gist now

Instantly share code, notes, and snippets.

@cmheisel /Berksfile
Last active Jan 10, 2017

What would you like to do?
OpsWorks Docker image-based deployment

opsworks-docker

Things to make Docker go on Ops Works. We need help.</pakled>

Described in this blog post of mine and based on this AWS blog entry

Instructions

  1. Set up a new stack in OpsWorks. Under Advanced set the following:
    • Chef version: 11.10
    • Use custom Chef cookbooks: https git url to a repo containing the other files in the gist inside owdocker/recipes/
    • Manage Berkshelf: Yes
    • Berkshelf version: 3.1.3
  2. Add a layer
    • Type: Other
    • Recipes
      • Setup: owdocker::install
      • Deploy: owdocker::docker-image-deploy
  3. Add an App
    • Type: Other
    • Repository type: Other
    • Environment variables:
      • registry_image: The path portion of a docker pull command ala: docker pull $registry_image
      • registry_tag: The tag of the image that should be pulled from the registry ala quay.io/yourusername/yourimage:$registry_tag
      • layer: The shortname of the layer the image should be deployed to
      • service_port: The port on the HOST that will be connected to the container
      • container_port: The port on the CONTAINER that will be connected to the service port
      • registry_username: OPTIONAL username to login to the registry
      • registry_password: OPTIONAL password to login to the registry
      • registry_url: OPTIONAL url to a non hub.docker.com registry ala quay.io
source "https://supermarket.getchef.com"
metadata
cookbook "apt", '~>2.6.0'
cookbook 'docker', '~> 0.36.0'
cookbook 'windows', '~> 1.34.0'
include_recipe 'deploy'
include_recipe 'docker'
Chef::Log.info("Entering docker-image-deploy")
node[:deploy].each do |application, deploy|
if node[:opsworks][:instance][:layers].first != deploy[:environment_variables][:layer]
Chef::Log.warn("Skipping deploy::docker application #{application} as it is not deployed to this layer")
next
end
opsworks_deploy_dir do
user deploy[:user]
group deploy[:group]
path deploy[:deploy_to]
end
opsworks_deploy do
deploy_data deploy
app application
end
Chef::Log.info('Docker cleanup')
bash "docker-cleanup" do
user "root"
returns [0, 1]
code <<-EOH
if docker ps | grep #{deploy[:application]};
then
docker stop #{deploy[:application]}
sleep 3
docker rm -f #{deploy[:application]}
fi
if docker ps -a | grep #{deploy[:application]};
then
docker rm -f #{deploy[:application]}
fi
if docker images | grep #{deploy[:environment_variables][:registry_image]};
then
docker rmi -f $(docker images | grep -m 1 #{deploy[:environment_variables][:registry_image]} | awk {'print $3'})
fi
EOH
end
if deploy[:environment_variables][:registry_username]
Chef::Log.info("REGISTRY: Login as #{deploy[:environment_variables][:registry_username]} to #{deploy[:environment_variables][:registry_url]}")
docker_registry "#{deploy[:environment_variables][:registry_url]}" do
username deploy[:environment_variables][:registry_username]
password deploy[:environment_variables][:registry_password]
email deploy[:environment_variables][:registry_username]
end
end
# Pull tagged image
Chef::Log.info("IMAGE: Pulling #{deploy[:environment_variables][:registry_image]}:#{deploy[:environment_variables][:registry_tag]}")
docker_image "#{deploy[:environment_variables][:registry_image]}" do
tag deploy[:environment_variables][:registry_tag]
end
dockerenvs = " "
deploy[:environment_variables].each do |key, value|
dockerenvs=dockerenvs+" -e "+key+"="+value unless key == "registry_password"
end
Chef::Log.info("ENVs: #{dockerenvs}")
Chef::Log.info('docker-run start')
bash "docker-run" do
user "root"
code <<-EOH
docker run #{dockerenvs} -p #{node[:opsworks][:instance][:private_ip]}:#{deploy[:environment_variables][:service_port]}:#{deploy[:environment_variables][:container_port]} --name #{deploy[:application]} -d #{deploy[:environment_variables][:registry_image]}:#{deploy[:environment_variables][:registry_tag]}
EOH
end
Chef::Log.info('docker-run stop')
end
Chef::Log.info("Exiting docker-image-deploy")
include_recipe 'apt'
package 'apt-transport-https'
apt_repository "docker" do
uri "https://get.docker.com/ubuntu"
distribution "docker"
components ["main"]
keyserver "hkp://keyserver.ubuntu.com:80"
key "36A1D7869245C8950F966E92D8576A8BA88D21E9"
end
execute "apt-get update" do
user "root"
end
# Install Docker latest version
package "docker" do
package_name "lxc-docker"
action :install
end
service "docker" do
action :start
end

Thanks for the update Chris..

I have been reading about these 'Berksfile'(s) for house now trying everything under the sun.. I think I am more or less starting to grasp what it is they do. While I haven't tried your Berksfile yet, I will. I am pretty sure it's going to complain about metadata not existing as that's where I was before your post. Albeit my Berksfile was wrong.
The other question is that since I am not using Ubuntu I assume I should remove the apt piece because apt is not used in CentOS. I do have to admit that I am a little confused why it's needed as apt is already installed in the default installation of Ubuntu and I didn't see anything in the docker recipe that makes it 'Ubuntu' centric. It's entirely possible I missed that tho. The original owdocker_install.rb was Ubuntu centric but I changed that.

Thanks for your time.

J

Chris,

I get what the apt cookbook is doing now. ( Updating apt to the latest before it runs any apt-get commands)
I changed that to the yum-epel cookbook and will see what works from there.
It does in fact break down because of the metadata.rb file.

Thanks so much for your help!,

J

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment