Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Running Docker in Development & Production (#ndcoslo 2015)

11,428 views

Published on

Session on Running Docker in Development & Production given at NDC Oslo 2015 on 18th June 2015

Published in: Software
  • Be the first to comment

Running Docker in Development & Production (#ndcoslo 2015)

  1. 1. Running Docker in Development & Production @Ben_Hall Ben@BenHall.me.uk Blog.BenHall.me.uk
  2. 2. Who? @Ben_Hall Tech Support > Tester > Developer > Founder / Freelancer
  3. 3. Agenda • Introduction to Docker & Containers • One Container • Two Containers • Three Containers • Scale
  4. 4. Aim Demonstrate steps required to create - A Multi-Container - Load Balanced - ASP.NET / Nancy / Node.js Website - Running Inside Containers via Docker With The Lessons I Learned Along The Way
  5. 5. WHAT IS DOCKER?
  6. 6. Virtual Machine https://www.docker.com/whatisdocker/
  7. 7. https://www.docker.com/whatisdocker/ Container
  8. 8. Own Process Space Own Network Interface Own Root Directories Sandboxed Like a lightweight VM. But it’s not a VM. Container
  9. 9. Native CPU Native Memory Native IO No Pre-Allocation No Performance Overheard Container
  10. 10. Docker - An open platform for distributed applications for developers and sysadmins. Otherwise known as tooling / ecosystem to run containers
  11. 11. Registry
  12. 12. Installing on OSX / Windows https://github.com/boot2docker/
  13. 13. Installing In Production 'curl -sSL https://get.docker.com/ | sh'
  14. 14. https://github.com/docker/machine
  15. 15. ONE CONTAINER
  16. 16. $ docker run --name === Friendly name --rm === Remove when finished -t === Attach to terminal -i === Interactive Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
  17. 17. > docker run -d #Run In Background elasticsearch #Image Name https://www.dropbox.com/s/fbe8briq6ayycrh/start-elastic.gif?dl=0
  18. 18. Dockerfile Dockerfile & App Source Build Image https://docs.docker.com/reference/builder/
  19. 19. FROM FROM benhall/aspnet-vnext-npm # Base Image
  20. 20. https://registry.hub.docker.com/u/benhall/aspnet-vnext-npm/
  21. 21. FROM microsoft/aspnet:1.0.0-beta4 RUN useradd -ms /bin/bash dev RUN gpg --keyserver pool.sks-keyservers.net --recv-keys 7937DFD2AB06298B2293C3187D33FF9D0246406D 114F43EE0176B71C7BC219DD50A3051F888C628D ENV NODE_VERSION 0.10.38 ENV NPM_VERSION 2.9.1 ENV APT_PACKAGES git RUN apt-get update -qq && apt-get -yqq install $APT_PACKAGES && apt-get -yqq clean RUN curl -SLO "http://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz" && curl -SLO "http://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" && gpg --verify SHASUMS256.txt.asc && grep " node-v$NODE_VERSION-linux-x64.tar.gz$" SHASUMS256.txt.asc | sha256sum -c - && tar -xzf "node-v$NODE_VERSION-linux-x64.tar.gz" -C /usr/local --strip-components=1 && rm "node-v$NODE_VERSION-linux-x64.tar.gz" SHASUMS256.txt.asc && npm install -g npm@"$NPM_VERSION" && npm cache clear apt-get -y install autoconf automake build-essential libtool run curl -SLO http://libuv.org/dist/v1.0.0/libuv-v1.0.0.tar.gz && tar xvf libuv-v1.0.0.tar.gz && rm libuv-v1.0.0.tar.gz && cd libuv-v1.0.0 && sh ./autogen.sh && ./configure&& make && make install && cd .. && rm -rf libuv-v1.0.0 && ldconfig RUN npm install -g bower grunt-cli USER dev WORKDIR /home/dev
  22. 22. Dockerfile – ADD / WORKDIR / RUN COPY WebApplication /app WORKDIR /app RUN ["dnu", "restore”]
  23. 23. Dockerfile – EXPOSE / CMD EXPOSE 5000 CMD ["dnx", ".", "kestrel"]
  24. 24. Example – ASP.NET vNext FROM benhall/aspnet-vnext-npm COPY WebApplication /app WORKDIR /app RUN ["dnu", "restore”] EXPOSE 5000 CMD ["dnx", ".", "kestrel"]
  25. 25. Example - NancyFX FROM benhall/docker-mono COPY . /src WORKDIR /src RUN xbuild Nancy.Demo.Hosting.Docker.sln EXPOSE 8080 CMD ["mono", "src/bin/Nancy.Demo.Hosting.Docker.exe"]
  26. 26. Example – Node.JS FROM node:0.10.38 RUN mkdir -p /usr/src/app WORKDIR /usr/src/app COPY package.json /usr/src/app/ RUN npm install COPY . /usr/src/app EXPOSE 3001 CMD [ "npm", "start" ]
  27. 27. $ docker build --t === Friendly name. <Docker Hub Username>/<ProjectName>:<tag>
  28. 28. $ docker images
  29. 29. > cat .dockerignore #Ignore file in root all_the_passwords.txt .git/ node_modules/ bower_components/
  30. 30. $ docker run
  31. 31. $ docker ps -a === Show all containers
  32. 32. > docker inspect elasticsearch "NetworkSettings": { "Bridge": "docker0", "Gateway": "172.17.42.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.17.0.3", "IPPrefixLen": 16, "IPv6Gateway": "", "LinkLocalIPv6Address": "fe80::42:acff:fe11:3", "LinkLocalIPv6PrefixLen": 64, "MacAddress": "02:42:ac:11:00:03", "PortMapping": null }
  33. 33. $ docker run –p $CONTAINERPORT
  34. 34. > iptables -t nat -L –n Chain DOCKER (1 references) target prot opt source destination DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:49163 to:172.17.0.27:80 DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:49164 to:172.17.0.29:3000 DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:49165 to:172.17.0.30:80 DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:49166 to:172.17.0.31:3000 DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:49167 to:172.17.0.38:80 DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:49168 to:172.17.0.40:3000 DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.95:80
  35. 35. > docker run -d #Run In Background -p 9200:9200 -p 9300:9300 #Bind Ports elasticsearch #Image Name https://www.dropbox.com/s/fbe8briq6ayycrh/start-elastic.gif?dl=0
  36. 36. > curl b2d:9200 # b2d is my Boot2Docker VM https://www.dropbox.com/s/fbe8briq6ayycrh/start-elastic.gif?dl=0
  37. 37. Recap • docker registry • docker run elasticsearch • Create Dockerfile • docker build –t image-name . • docker run image-name
  38. 38. Go Lang > cat Dockerfile FROM golang:onbuild > cat Makefile NAME = ocelotuproar/docker-outdated build: docker build -t $(NAME) . run: docker run --rm --name $(INSTANCE) $(NAME) > make build # Run Golang Compiler & Build container > make run # Run built application
  39. 39. 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
  40. 40. RStudio • docker run -d -p 8787:8787 rocker/rstudio
  41. 41. TWO CONTAINERS / PRODUCTION
  42. 42. Docker Push / Pull > docker run -p 5000:5000 registry:2.0 > docker push myreg:5000/benhall/aspnet:20150617140759 > docker pull myreg:5000/benhall/aspnet:20150617140759
  43. 43. Persisting Data$ docker run –v <host-dir>:<container-dir> image -v /opt/docker/elasticsearch:/data -v /opt/docker/mysql:/var/lib/mysql -v /docker/scrapbook/uploads:/app/public/uploads -v $(PWD):/host -v /var/log/syslog:/var/log/syslog
  44. 44. > docker run -d --restart=always # Restart if exits non-zero redis
  45. 45. Environment Variables
  46. 46. > docker run -d -p 9200:9200 -p 9300:9300 --name es # 1) Friendly Name elasticsearch > docker run –it –p 3000 --link es:elasticsearch #2) <container>:<alias> your-application > cat /etc/hosts 172.17.0.79 elasticsearch > env HOSTNAME=2f3b959b13a0 ELASTICSEARCH_PORT=tcp://172.17.0.79:9200 ELASTICSEARCH_PORT_9200_TCP=tcp://172.17.0.79:9200 ELASTICSEARCH_PORT_9200_TCP_ADDR=172.17.0.79 ELASTICSEARCH_PORT_9200_TCP_PORT=9200 ELASTICSEARCH_PORT_9200_TCP_PROTO=tcp ELASTICSEARCH_NAME=/scrapbookv2_web_1/es NODE_ENV=production
  47. 47. Two Websites On Port 80?
  48. 48. Nginx
  49. 49. 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-enab -v /opt/docker/nginx/logs:/var/log/nginx dockerfile/nginx
  50. 50. Nginx Proxy https://github.com/jwilder/nginx-proxy https://www.dropbox.com/s/2f6y2frfjafc409/nginx-proxy-optimised.gif?dl=0
  51. 51. • -v /var/run/docker.sock:/tmp/docker.sock • VIRTUAL_HOST=my.container.com
  52. 52. # HTTP 1.1 support proxy_http_version 1.1; proxy_buffering off; proxy_set_header Host $http_host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $proxy_connection; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; upstream my.container.com { # agitated_hopper server 172.17.0.35:5001; } server { listen 80; server_name my.container.com; location / { proxy_pass http://my.container.com; } }
  53. 53. > docker run -d --name blog_benhall_varnish --link blog_benhall:wordpress -e VIRTUAL_HOST=blog.benhall.me.uk -e VARNISH_BACKEND_PORT=80 -e VARNISH_BACKEND_HOST=wordpress benhall/docker-varnish Nginx Varnish blog_benhall_varnish Wordpress blog_benhall
  54. 54. THREE CONTAINERS
  55. 55. > cat docker-compose.yml web: # Container Name build: . # Build links: # Links - elasticsearch ports: # Ports - 3000 environment: # Environment VIRTUAL_HOST: 'app.joinscrapbook.com' NODE_ENV: 'production’ elasticsearch: # 2nd Container Name image: elasticsearch:1.5 # Use Image ports: # Ports - 9200:9200
  56. 56. > 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 containers Stopping scrapbookv2_web_1... Stopping scrapbookv2_elasticsearch_1... Stopping scrapbookv2_db_1... Stopping scrapbookv2_redis_1... Stopping scrapbookv2_nginx_1...
  57. 57. 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
  58. 58. 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 Code 0 # Success
  59. 59. FOUR AND MORE! SCALE!
  60. 60. [tag.]<service>.service[.datacenter][.domain] $ ping redis.service.east-aws.consul $ ping redis.service.consul
  61. 61. 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
  62. 62. 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 discovery API to write & load config
  63. 63. Swarm A Docker-native clustering system
  64. 64. http://12factor.net/
  65. 65. THE FUTURE?
  66. 66. Docker and Microsoft Partnership
  67. 67. SQL Server as a Container?
  68. 68. Spoon.NET
  69. 69. Visual Studio as a Container?
  70. 70. Docker as a Platform
  71. 71. http://www.joinscrapbook.com
  72. 72. IN SUMMARY…
  73. 73. Only tool I use for deployment • Close gap between development and production • Everything is a container! • Docker Machine, Compose & Swarm • Running platforms like Logstash, ElasticSearch, Redis, EventStore, RavenDB, NancyFX etc? Consider containers for deployment.
  74. 74. @Ben_Hall Ben@BenHall.me.uk Blog.BenHall.me.uk Thank you http://www.JoinScrapbook.com 2 Day Training in Oslo with ProgramUtvikling September 2015

×