+ All Categories
Home > Software > Running Docker in Development & Production (DevSum 2015)

Running Docker in Development & Production (DevSum 2015)

Date post: 28-Jul-2015
Category:
Upload: ben-hall
View: 1,708 times
Download: 0 times
Share this document with a friend
Popular Tags:
91
Containers in Development & Production @Ben_Hall [email protected] Blog.BenHall.me.uk
Transcript

Running Docker and Containers in Development & Production

@[email protected]

Who?

@Ben_Hall

Tech Support > Tester > Developer > Founder > Freelancer

Agenda

• Introduction To Docker & Containers• Dockerizing Dockerising Applications• Docker As Development Environment• Testing Containers• Production

A Load Balanced ASP.NET/NancyFX/Node.js Website running inside Docker

https://www.dropbox.com/s/gbcifo094c9v8ar/nancy-lb-demo-optimised.gif?dl=0

WHAT ARE CONTAINERS?

Virtual Machine

https://www.docker.com/whatisdocker/

Container

https://www.docker.com/whatisdocker/

Container

Container

Own Process SpaceOwn Network InterfaceOwn Root Directories

Sandboxed

Like a lightweight VM. But it’s not a VM.

Container

Native CPUNative Memory

Native IONo Pre-Allocation

Instant On

Zero Performance Overheard

Build, Ship and Run Any App, Anywhere

Docker - An open platform for distributed applications for developers and sysadmins.

RUNNING CONTAINERS

ElasticSearch Before Docker> curl -L -O http://download.elasticsearch.org/PATH/TO/VERSION.zip > unzip elasticsearch-$VERSION.zip> cd elasticsearch-$VERSIONThe only requirement for installing Elasticsearch is a recent version of Java. Preferably,

you should install the latest version of the official Java from www.java.com.

1. Download the jre-8u40-macosx-x64.dmg file. 2. Review and agree to the terms of the license agreement before downloading the

file.3. Double-click the .dmg file to launch it4. Double-click on the package icon to launch install Wizard5. The Install Wizard displays the Welcome to Java installation screen. Click Next6. Oracle has partnered with companies that offer various products. After ensuring

the desired programs are selected, click the Next button to continue the installation.

7. After the installation has completed, a confirmation screen appears. Click Close to finish the installation process.

> ./bin/elasticsearch

> docker run -d #Run In Background dockerfile/elasticsearch #Image Name

https://www.dropbox.com/s/fbe8briq6ayycrh/start-elastic.gif?dl=0

> docker run -d -p 9200:9200 -p 9300:9300 #Bind Ports dockerfile/elasticsearch

curl b2d:9200 ?

> boot2docker ip192.168.59.103> echo “192.168.59.103 b2d” >> /private/etc/hosts> cat /private/etc/hosts192.168.59.103 b2dfor i in {49000..49900}; do VBoxManage modifyvm "boot2docker-vm" --natpf1 "tcp-port$i,tcp,,$i,,$i"; VBoxManage modifyvm "boot2docker-vm" --natpf1 "udp-port$i,udp,,$i,,$i";done

Installing In Development

https://github.com/boot2docker/

https://github.com/docker/machine

DOCKERISING YOUR APPLICATIONS

Dockerfile

Dockerfile & App Source

Build

Image

https://docs.docker.com/reference/builder/

FROM

FROM ubuntu:14.01 # Base Image

FROM ubuntu:latest # Caution

COPY / WORKDIR / RUN

COPY . /src # Copy current directory into image

WORKDIR /src # Set working directory

RUN apt-get update # Run a shell command

EXPOSE

EXPOSE 3000 # Allow binding to port 3000

EXPOSE 7000-8000 # Expose range of ports

CMD

CMD ./bin/www # Default command when container starts

Complete .NET/Mono DockerfileFROM benhall/docker-monoCOPY . /srcWORKDIR /srcRUN xbuild Nancy.Demo.Hosting.Docker.slnEXPOSE 8080CMD ["mono", "src/bin/Nancy.Demo.Hosting.Docker.exe"]

benhall/docker-mono DockerfileFROM ubuntu:14.01MAINTAINER Ben Hall "[email protected]"

RUN apt-get update -qq && \ apt-get -yqq install mono-complete && \ apt-get -yqq clean

> docker build #Build Image -t scrapbook/app:20150520 #Image Name:Tag . #Directory

https://www.dropbox.com/s/k7h0tdu28160nil/scrapbook-node-build-optimised.gif?dl=0

> cat .dockerignore #Ignore file in rootall_the_passwords.txt.git/node_modules/bower_components/

> docker run -it #Run In Foreground scrapbook/app:20150520 #Image Name:Tag

> docker run -it -p 3000 #Bind Random Port to Port 3000 scrapbook/app:20150520

> docker run -it -p 3000:3000 #Bind Known Port scrapbook/app:20150520

> docker ps #List Running Processes -a #Include Stopped

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES1e5b37b0a2bc scrapbook/app:20150520133000 "npm start" 4 minutes ago Up 4 minutes 0.0.0.0:49176->3000/tcp mad_fermi

> docker logs # Stream logs 1e5b37b0a2bc # ContainerID

> docker run -d -p 9200:9200 -p 9300:9300 --name es # Friendly Name dockerfile/elasticsearch > docker run –it –p 3000

--link es:elasticsearch # Link container:alias scrapbook/app:20150520> cat /etc/hosts172.17.0.79 elasticsearch

> envHOSTNAME=2f3b959b13a0ELASTICSEARCH_PORT=tcp://172.17.0.79:9200ELASTICSEARCH_PORT_9200_TCP=tcp://172.17.0.79:9200ELASTICSEARCH_PORT_9200_TCP_ADDR=172.17.0.79ELASTICSEARCH_PORT_9200_TCP_PORT=9200ELASTICSEARCH_PORT_9200_TCP_PROTO=tcpELASTICSEARCH_NAME=/scrapbookv2_web_1/esNODE_ENV=production

> docker run –it –p 3000 --link es:elasticsearch -e SQLSERVER=10.10.20.50 #Environment Variable scrapbook/app:20150520> envSQLSERVER.10.10.20.50HOSTNAME=2f3b959b13a0ELASTICSEARCH_PORT=tcp://172.17.0.79:9200ELASTICSEARCH_PORT_9200_TCP=tcp://172.17.0.79:9200ELASTICSEARCH_PORT_9200_TCP_ADDR=172.17.0.79ELASTICSEARCH_PORT_9200_TCP_PORT=9200ELASTICSEARCH_PORT_9200_TCP_PROTO=tcpELASTICSEARCH_NAME=/scrapbookv2_web_1/esNODE_ENV=production

http://12factor.net/

http://blog.benhall.me.uk/2015/05/using-make-to-manage-docker-image-creation/

> make build

NAME = benhall/docker-make-demo

default: build

build: docker build -t $(NAME) .

debug: docker run --rm -it $(NAME) /bin/bash

run: docker run --rm $(NAME)

push: docker push $(NAME)

release: build push

> cat docker-compose.ymlweb: # Container Name build: . # Build links: # Links - elasticsearch ports: # Ports - 3000 environment: # Environment VIRTUAL_HOST: 'app.joinscrapbook.com' NODE_ENV: 'production'elasticsearch: # 2nd Container Name

# Use Image image: dockerfile/elasticsearch:latest ports: # Ports - 9200:9200

> docker-compose up # Start containers–d # In background

Recreating scrapbookv2_nginx_1...Recreating scrapbookv2_redis_1...Recreating scrapbookv2_db_1...Recreating scrapbookv2_elasticsearch_1...Recreating scrapbookv2_web_1…

> docker-compose stop # Stop containersStopping scrapbookv2_web_1...Stopping scrapbookv2_elasticsearch_1...Stopping scrapbookv2_db_1...Stopping scrapbookv2_redis_1...Stopping scrapbookv2_nginx_1...

Sidekick Container For Testing

> docker run –d # No need to bind ports --name es # Friendly Name dockerfile/elasticsearch > docker run –it

--link es:es # Link Container:alias benhall/curl # Curl Image curl http://es:9200 # Ping service

> echo $? # Exit Code0 # Success

Schema Management Containers

> docker run –d # No need to bind ports --name es # Friendly Name dockerfile/elasticsearch > docker run –rm

--link es:es # Link Container:alias myapp/schema:latest # Schema Image

Taggingubuntu 15.04 2427658c75a1 12 weeks ago 117.5 MBubuntu vivid 2427658c75a1 12 weeks ago 117.5 MBubuntu vivid-20150218 2427658c75a1 12 weeks ago 117.5 MBubuntu 14.10 78949b1e1cfd 12 weeks ago 194.4 MBubuntu utopic-20150211 78949b1e1cfd 12 weeks ago 194.4 MBubuntu utopic 78949b1e1cfd 12 weeks ago 194.4 MBubuntu latest 2d24f826cb16 12 weeks ago 188.3 MBubuntu trusty 2d24f826cb16 12 weeks ago 188.3 MBubuntu 14.04 2d24f826cb16 12 weeks ago 188.3 MBubuntu 14.04.2 2d24f826cb16 12 weeks ago 188.3 MBubuntu trusty-20150218.1 2d24f826cb16 12 weeks ago 188.3 MBubuntu 12.04 1f80e9ca2ac3 12 weeks ago 131.5 MBubuntu precise 1f80e9ca2ac3 12 weeks ago 131.5 MBubuntu precise-20150212 1f80e9ca2ac3 12 weeks ago 131.5 MBubuntu 12.04.5 1f80e9ca2ac3 12 weeks ago 131.5 MBubuntu 14.04.1 5ba9dab47459 3 months ago 188.3 MB

> docker push # Push Image To Remote Registry benhall/nancy-demo:latest # Image Name:Tag

> docker export # Export Image to Tar containerid # Container ID

> container.tar # Name of Tar

> docker run -p 5000:5000 registry:2.0 # Docker Registry Container

> docker push b2d:5000/aspnet:beta5

Recap

• Docker Client / Boot2docker• Docker Daemon• Docker Images• Docker Container• Docker Hub / Registry

DOCKER AS A DEVELOPMENT ENVIRONMENT

ASP.NET vNext DNX> cat Makefilerestore:

docker run -it -v /Users/ben/.dnx:/home/dev/.dnx -v $(shell pwd)/WebApplication:/app -w="/app" benhall/aspnet-vnext-npm dnu restore

build:docker run -v /Users/ben/.dnx:/home/dev/.dnx -v $

(shell pwd)/WebApplication:/app -w="/app" benhall/aspnet-vnext-npm dnu build

run:docker run -it -v /Users/ben/.dnx:/home/dev/.dnx

-v $(shell pwd)/WebApplication:/app -w="/app" -p 5001 benhall/aspnet-vnext-npm dnx . kestrel

> docker run –it --name scrapbook-iojs # Name it for future -v $(pwd):/app -v $(pwd)/iojs:/app/node_modules # Move location -w="/app” # Set working directory --entrypoint /bin/bash # Override entrypoint

iojs

GoLang> cat DockerfileFROM golang:onbuild

> cat MakefileNAME = ocelotuproar/docker-outdatedbuild:

docker build -t $(NAME) .run:

docker run --rm --name $(INSTANCE) $(NAME)

> make build # Run Golang Compiler & Build

container> make run # Run built application

Run Unit Tests Inside Containers

Run UI Inside Containers> docker run -d -p 4444:4444 --name selenium-hub selenium/hub:2.45.0> docker run -d --link selenium-hub:hub selenium/node-chrome:2.45.0> docker run -d --link selenium-hub:hub selenium/node-firefox:2.45.0

Private NPM Repository

https://github.com/BenHall/docker-local-npm-registry

> docker run -d -v $(pwd)/config.yaml:/opt/sinopia/config.yaml -p 4873:4873 keyvanfatehi/sinopia:latest

> npm set registry http://b2d:4873> npm adduser --registry http://b2d:4873

RStudio

• docker run -d -p 8787:8787 rocker/rstudio

PRODUCTION

> docker pull # Pull Image To Remote Registry benhall/nancy-demo:latest # Image Name:Tag

Always include tag otherwise pulls everything

> cat docker-compose.yml

web: build: . links: - elasticsearch volumes: # Mount Directories Outside Container - /opt/docker/scrapbook/db:/usr/src/app/ocelite-db - /opt/docker/scrapbook/uploads:/usr/src/app/uploads - /opt/docker/scrapbook/tmp:/usr/src/app/tmpelasticsearch: image: dockerfile/elasticsearch:latest volumes: # Host:Container - /opt/docker/scrapbook_elasticsearch:/data

Persisting Data

Port 80

Problematic Approach

> docker run -d --name nginx_root --link blog_benhall-1:blog_benhall-1 --link scrapbook-1:scrapbook-1 --link scrapbook_web_1:scrapbook_web_1 --link brownbag_web_1:brownbag_web_1 -p 80:80 -v /opt/docker/nginx/www:/data -v /opt/docker/nginx/sites:/etc/nginx/sites-enabled -v /opt/docker/nginx/logs:/var/log/nginx dockerfile/nginx

Problems

• Static link – /etc/hosts

• Adding new website? Reboot everything• Requires nginx config for each site

Nginx Proxyhttps://github.com/jwilder/nginx-proxy

https://www.dropbox.com/s/2f6y2frfjafc409/nginx-proxy-optimised.gif?dl=0

• VIRTUAL_HOST=my.container.com

• -v /var/run/docker.sock:/tmp/docker.sock

1) Docker raises events when containers start / stop

2) Registrator listens to events adds the new container’s details into Consul

3) Consul links container’s IP / Ports to DNS names & discovery API

> ping redis.service.consul

4) Nginx uses Consul API to write & load config

A Load Balanced ASP.NET/NancyFX/Node.js Website running inside Docker

https://www.dropbox.com/s/gbcifo094c9v8ar/nancy-lb-demo-optimised.gif?dl=0

Installing In Production

'curl -sSL https://get.docker.com/ | sh'

> docker run -d --restart=always # Restart if exits

redis

Ports> docker run –p 3000:3000 nodejs node.app> sudo apt-get install ufw && sudo ufw disable> sudo ufw default deny> sudo ufw allow 22> sudo ufw allow 80> sudo ufw enable

Docker manages IPTables, ufw won’t block

> echo "DOCKER_OPTS=\”--iptables=false\"" > /etc/default/docker> docker run –p 127.0.0.1:3000 nodejs node.app

Memory / CPU Usage> docker run –m 128m –cpu 50 mysql

Space UsageLinux cgroups…

Bandwidth Usage> iptables -A OUTPUT -p tcp --sport 80 -m state --state ESTABLISHED,RELATED -m quota –quota 1310720 -j ACCEPT

Log Files5.8M Mar 29 07:17 /var/lib/docker/containers/0e3bcd1ca248316a13d9b3157M Mar 29 14:25 /var/lib/docker/containers/1922c7a7a8e2116a13d9b1.8M Mar 6 07:23 /var/lib/docker/containers/2774be7d8de20c57dc33432K Jan 14 16:18 /var/lib/docker/containers/38e7c4ae373bdee0b157d5e08924183K Mar 17 10:00 /var/lib/docker/containers/4a207c6da1962c5e09c35f9851a74955M Mar 29 14:25 /var/lib/docker/containers/5408f6a43646906674bfd7991721.3M Mar 6 10:17 /var/lib/docker/containers/6e41977a8521553a1e827a541.3M Mar 6 10:11 /var/lib/docker/containers/756f64b3be19024e9db2071 Jan 28 11:50 /var/lib/docker/containers/b1a2d887ea4ab92dc509M Mar 29 14:25 /var/lib/docker/containers/c5784ce2225e29290b2787e0f102716K Feb 2 18:26 /var/lib/docker/containers/daa45cebdf95b5a268f3006e2fd07488K Mar 6 10:43 /var/lib/docker/containers/ec80d6a8a2cfe8607989bfba4e

Handling Machine Name Changes

• Couchbase• InfluxDB

THE FUTURE?

Docker and Microsoft Partnership

SQL Server as a Container?

Spoon.NET

Visual Studio as a Container?

Docker as a Platform

http://www.joinscrapbook.com

IN SUMMARY…

Only tool I use for deployment

• Close gap between development and production

• Everything is a container!

• Running platforms like Logstash, ElasticSearch, Redis, EventStore, RavenDB, NancyFX etc? Consider containers for deployment.

@[email protected]

Thank you

http://www.joinscrapbook.com


Recommended