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
Container
Own Process SpaceOwn Network InterfaceOwn Root Directories
Sandboxed
Like a lightweight VM. But it’s not a VM.
Build, Ship and Run Any App, Anywhere
Docker - An open platform for distributed applications for developers and sysadmins.
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
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
COPY / WORKDIR / RUN
COPY . /src # Copy current directory into image
WORKDIR /src # Set working directory
RUN apt-get update # Run a shell command
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
> 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 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://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 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
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 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
> 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
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
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
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
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.