Awesomify Your Dev Environment

[Docker + Vagrant] 

Jeff French

Moonswitch

@jeff_french

Works

on my machine!

An open platform for distributed applications

for developers and sysadmins.

Built on LXC Containers

Like a lightweight VM

$ docker run -d nginx

Unable to find image 'nginx' locally

Pulling repository nginx

e2d4f91968f1: Download complete

...

f0d53eb7f804: Download complete

51961fc2396c556399b77b4e2276dc1d2202a9509365639efced56f34297bd84

$ docker inspect 51961f | grep IPAddress | cut -d '"' -f 4

172.17.0.4

$ curl -IL 172.17.0.4:80

HTTP/1.1 200 OK
Server: nginx/1.7.6
Date: Wed, 08 Oct 2014 23:21:50 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 30 Sep 2014 14:16:33 GMT
Connection: keep-alive
ETag: "542abb41-264"
Accept-Ranges: bytes
$ docker run -d -p 80:80 nginx

$ docker ps

CONTAINER ID        IMAGE               COMMAND                
3e619719e1b0        nginx:latest        "nginx -g 'daemon of"   

CREATED             STATUS              PORTS                         NAMES
5 seconds ago       Up 4 seconds        443/tcp, 0.0.0.0:80->80/tcp   suspicious_ritchie
$ docker run -d --name some-redis redis

$ docker run -d --link some-redis:redis -p 80:80 mycoolcontainer


ENV VARS:

REDIS_NAME=some-redis
REDIS_PORT=tcp://172.17.0.5:6379
REDIS_PORT_6379_TCP=tcp://172.17.0.5:6379
REDIS_PORT_6379_TCP_PROTO=tcp
REDIS_PORT_6379_TCP_PORT=6379
REDIS_PORT_6379_TCP_ADDR=172.17.0.5
FROM debian:wheezy

MAINTAINER NGINX Docker Maintainers "docker-maint@nginx.com"

RUN apt-key adv --keyserver pgp.mit.edu --recv-keys 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
RUN echo "deb http://nginx.org/packages/mainline/debian/ wheezy nginx" >> /etc/apt/sources.list

ENV NGINX_VERSION 1.7.6-1~wheezy

RUN apt-get update && apt-get install -y nginx=${NGINX_VERSION}

# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log
RUN ln -sf /dev/stderr /var/log/nginx/error.log

VOLUME ["/usr/share/nginx/html"]
VOLUME ["/etc/nginx"]

EXPOSE 80 443

CMD ["nginx", "-g", "daemon off;"]

Automation of Virtual Machines

Virtual machine providers

  • Virtual Box
  • VM Ware
  • Hyper-V
  • Docker
box      = 'precise32'
url      = 'http://files.vagrantup.com/precise32.box'
hostname = 'myprecisebox'
domain   = 'example.com'
ip       = '192.168.0.42'
ram      = '256'

Vagrant::Config.run do |config|
  config.vm.box = box
  config.vm.box_url = url
  config.vm.host_name = hostname + '.' + domain
  config.vm.network :hostonly, ip

  config.vm.customize [
    'modifyvm', :id,
    '--name', hostname,
    '--memory', ram
  ]
end

Why do i need both?

FROM dockerfile/nodejs
MAINTAINER Jeff French <jeff.french@moonswitch.com>

ENV PM2_BIND_ADDR 0.0.0.0

RUN npm install -g pm2
RUN pm2 web

ADD ./package.json /app/
WORKDIR /app
RUN npm install

EXPOSE 3000 9615
WORKDIR /app/src
cmd ["pm2", "start", "index.js", "--watch", "--no-daemon"]
# -*- mode: ruby -*-
# vi: set ft=ruby :

$start = <<SCRIPT
docker start rabbitmq_ambassador
docker start redis_ambassador
docker start webhook-server
docker start background-worker
SCRIPT

Vagrant.configure("2") do |config|

    config.vm.define "services" do |services|
        services.vm.box = "ubuntu-14.04-amd64-vbox"
        services.vm.box_url = "https://oss-binaries.phusionpassenger.com/vagrant/boxes/latest/ubuntu-14.04-amd64-vbox.box"
        services.vm.network "private_network", ip: "192.168.50.4"
        services.vm.network "forwarded_port", guest: 15672, host: 15672
        services.vm.provision "docker" do |d|
            d.pull_images "tutum/rabbitmq"
            d.pull_images "tutum/redis"
            d.pull_images "ctlc/ambassador"

            d.run "rabbitmq",
                image: "tutum/rabbitmq",
                args: "-e RABBITMQ_PASS='pwd@123'"

            d.run "rabbitmq_ambassador",
                image: "ctlc/ambassador",
                args: "--link rabbitmq:rabbitmq -p 5672:5672 -p 15672:15672"

            d.run "redis",
                image: "tutum/redis",
                args: "-e REDIS_PASS='pwd@123' -e REDIS_MODE='LRU' -e REDIS_MAXMEMORY='128mb'"

            d.run "redis_ambassador",
                image: "ctlc/ambassador",
                args: "--link redis:redis -p 6379:6379"
        end
    end

    config.vm.define "apps" do |apps|
        apps.vm.box = "phusion/ubuntu-14.04-amd64"
        #apps.vm.box_url = "https://oss-binaries.phusionpassenger.com/vagrant/boxes/latest/ubuntu-14.04-amd64-vbox.box"

        apps.vm.network "private_network", ip: "192.168.50.5"
        apps.vm.network "forwarded_port", guest: 3000, host: 3000
        apps.vm.network "forwarded_port", guest: 9615, host: 9615

        apps.vm.synced_folder "./webhook-server", "/webhook-server", type: "nfs"
        apps.vm.synced_folder "./background-worker", "/background-worker", type: "nfs"

        config.vm.provision "docker" do |d|
            d.build_image "/webhook-server",
                args: "-t shoppinpal/webhook-server"
            d.build_image "/background-worker",
                args: "-t shoppinpal/background-worker"
            d.pull_images "ctlc/ambassador"

            d.run "rabbitmq_ambassador",
                image: "ctlc/ambassador",
                args: "--expose 5762 --expose 15672 -e RABBITMQ_PORT_5762_TCP=tcp://192.168.50.4:5762 -e RABBITMQ_PORT_15762_TCP=tcp://192.168.50.4:15762"

            d.run "redis_ambassador",
                image: "ctlc/ambassador",
                args: "--expose 6379 -e REDIS_PORT_6379_TCP=tcp://192.168.50.4:6372"

            d.run "webhook-server",
                image: "shoppinpal/webhook-server",
                args: "-v /webhook-server:/app/src -e PORT=3000 -p 3000:3000 -p 9615:9615 --link redis_ambassador:redis --link rabbitmq_ambassador:rabbitmq"

            d.run "background-worker",
                image: "shoppinpal/background-worker",
                args: "-v /background-worker:/app/src --link redis_ambassador:redis --link rabbitmq_ambassador:rabbitmq"
        end

        config.vm.provision "shell", run: "always", inline: $start
    end
end

Questions?

Jeff French

Moonswitch

@jeff_french

Made with Slides.com