Increasing Velocity with
Vagrant and Docker
Say What?
The New Buzz Word
Some seem to be putting DevOps into the same category as cloud, big data, and those other ambiguous terms that have no precise meaning, so can be spun however you want to help you sell stuff.
– Dale Vile, Feb 2016
What does it really mean?
DevOps is the practice of operations and development engineers participating together in the entire service lifecycle, from design through the development process to production support.
– The Agile Admin Blog
Breaking Down Silos
By having people from those silos all working together, it built a lot of empathy. And we were finally able to get moving.
– Rob Cummings, Director of Technical Operations at Nordstrom
DEV
QA
OPS
PM
Philosphy vs. Organization
"DevOps is a culture shift or a movement...." Instead, [companies] think that DevOps is a job or a role, so they create a new silo called DevOps
– Five Signs That Your DevOps Initiative is Failing by Mike Cavis
What does DevOps do?
Activities: Code, Build, Test, Package, Release, Configure, Monitor
Methods: C.A.L.M.S. (Culture, Automation, Lean, Measurement, Sharing)
development to production
On Production
How close does is your laptop to production?
Chaos Reigns
How do services respond?
Response
Fixing or Preventing
virtual systems
Automates virtual machines
Provisioning
Apply configuration on your virtual machine(s)
Virtualization Providers
Throw Away virtual systems
Disposable Virtual Systems (Linux)
Development system (Mac OS X)
vs
Shared Dev
Environments
Segregated Dev
Environments
vs
Example
# Create Scripts
vi Vagrantfile
# Bootstrap
vagrant up
# Interaction / Start Service
vagrant ssh
# Stop Web Service
vagrant halt
# Test
curl -i localhost:8080
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.provision :shell, path: "install_app.sh"
config.vm.network :forwarded_port, guest: 80, host: 8080
end
Overview
Vagrantfile
images and containers
Virtual Machines vs. Containers
KVM
HVM
LXC
Containers vs. Docker
Docker adds layered imaging and automation to containers
Automation
Provides host environment
Docker Machine
# Bootstrap (VM)
docker-machine create
eval "$(docker-machine env default)"
build images, pull images, run container, push images
Workflow
Orchestration of Docker Machine
Docker Compose (Fig)
web:
build: ./app
volumes:
- "./app:/src/app"
ports:
- "80:3000"
links:
- redis
- db
environment:
- PGHOST=db
- PGDATABASE=postgres
- PGUSER=postgres
redis:
image: redis:latest
ports:
- "6379:6379"
db:
image: postgres
Example
# Create Scripts
vi Dockerfile
# Bootstrap (Container)
docker build -t mywebapp .
docker run -d -p 8080:8080 mywebapp
# Interaction
docker exec -it mywebapp bash
# Test Web Service
curl -i ${SERVER}:8080
# Stop Web Service
docker ps
docker kill ${CONTAINER_HASH}
Docker Engine
Example
# Create Scripts
vi Dockerfile
vi docker-compose.yml
# Bootstrap (Container)
docker-compose up -d
# Interaction
docker exec -it mywebapp bash
# Test Web Service
curl -i ${SERVER}:8080
# Stop Container
docker-compose stop
Docker Compose
Example
# Create Scripts
vi Dockerfile
# Bootstrap (Container)
docker build -t mywebapp .
docker run -d -p 8080:8080 mywebapp
# Interaction
docker exec -it mywebapp bash
# Test Web Service
curl -i ${SERVER}:8080
# Stop Web Service
docker ps
docker kill ${CONTAINER_HASH}
# Create Scripts
vi Dockerfile
vi docker-compose.yml
# Bootstrap (Container)
docker-compose up -d
# Interaction
docker exec -it mywebapp bash
# Test Web Service
curl -i ${SERVER}:8080
# Stop Container
docker-compose stop
Docker Engine
Docker Compose
On Production
Workflow Example
Pets
Cattle
vs
Snowflake
Configured
At
Deployment
Tools for Snowflake
Pheonix
Configured
At
Build Time
Tools for Pheonix
Awesome Demo
Dockerfile
FROM node:argon
# Create app directory
ENV APP_HOME /usr/src/app
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME
# Install app dependencies
COPY package.json $APP_HOME/package.json
RUN npm install
# Bundle app source
COPY . $APP_HOME
EXPOSE 8080
CMD [ "npm", "start" ]
docker-compose.yml
version: '2'
services:
web:
build: .
ports:
- "8080:8080"
Start VM
# Configure Environment
docker-machine create
# Configure Environment
eval "$(docker-machine env default)"
Start Container & Test
# Boostrap Container
docker-compose up -d
# Get VM's IP Address
WEBSERVER=$(docker-machine ip "${DOCKER_MACHINE_NAME}") # set to docker ip
WEBSERVER=${WEBSERVER:-localhost} # default to localhost if not set
# Run Test
curl -i "${WEBSERVER}":8080
C – Culture A – Automation L – Lean M – Measurement S – Sharing
What does DevOps do?
server.js
'use strict';
const express = require('express');
// Constants
const PORT = 8080;
// Application
const app = express();
var ip = 0
// Multiple Route Scenario
app.get('/', function (req, res) {
res.send('Hello world!\n');
});
app.listen(PORT);
var ip = require("ip");
console.log('Running on http://' + ip.address() + ':' + PORT);
package.json
{
"name": "express_hello_world",
"version": "1.0.0",
"description": "Express Hello World",
"author": "Joaquin Menchaca <jmenchaca@gobalto.com>",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.13.3",
"ip": "^1.1.2"
}
}
Vagrantfile
PRIVATE_IP="10.10.10.4"
Vagrant.configure(2) do |config|
# base system is Ubuntu
config.vm.box = "ubuntu/trusty64"
# private IP for Docker Machine
config.vm.network "private_network", ip: PRIVATE_IP
# Install Docker short-cut
config.vm.provision "shell", path: "install_docker.sh"
end
Start VM
# Start Virtual Machine
vagrant up
# Docker Machine uses Vagrant
PRIVATE_IP="10.10.10.4"
PRIVATE_KEY=".vagrant/machines/default/virtualbox/private_key"
docker-machine create --driver generic \
--generic-ssh-user vagrant \
--generic-ssh-key "${PWD}/${PRIVATE_KEY}" \
--generic-ip-address "${PRIVATE_IP}" \
hello_vm
# Configure Environment
eval "$(docker-machine env hello_vm)"