Save 37% off PRO during our Black Friday Sale! »

Introduction to Docker at PHPBenelux2015

Introduction to Docker at PHPBenelux2015

E9612cd342dbddff6640b99db21deee7?s=128

Andreas Hucks

January 23, 2015
Tweet

Transcript

  1. INTRODUCTION TO DOCKER WORKSHOP, PHPBENELUX2015

  2. ANDREAS HUCKS Software Architect at SensioLabs DE @meandmymonkey

  3. WHAT TO COPY FROM USB DRIVES • Only copy /boxes

    if you didn't download them already • Only copy /installers if you don't have Vagrant and/or Virtualbox • … and even then only the necessary files
  4. None
  5. $  vagrant  box  add  -­‐-­‐name  phpbnl15-­‐services  \      /path/to/phpbnl15-­‐services.box

      
 $  vagrant  box  add  -­‐-­‐name  phpbnl15-­‐playground  \      /path/to/phpbnl15-­‐playground.box SETUP: VAGRANT BOXES
  6. $  cd  /path/to/vagrantfile   $  vagrant  up   $  vagrant

     ssh  playground SETUP: SPIN UP VAGRANT & CONNECT
  7. $  pwd   /home/vagrant   $  whoami   vagrant  

    $  lsb_release  -­‐a   Distributor  ID:  Ubuntu   Description:        Ubuntu  14.04  LTS   Release:                14.04   Codename:              trusty ENVIRONMENT
  8. SOFTWARE DEVELOPMENT IS ABOUT BREAKING PROBLEMS INTO SMALLER PIECES

  9. WHAT ARE (DOCKER) CONTAINERS? • Linux Containers • Have been

    around for some years • They are not VMs • Use the same kernel
  10. WHAT ARE (DOCKER) CONTAINERS? • Kernel Namespaces • cgroups •

    See https:/ /linuxcontainers.org/
  11. WHAT ARE (DOCKER) CONTAINERS? • Docker creates a simple API

    for all of this • Written in Go • Provides a CLI and a RESTlike API
  12. RUNNING DOCKER • Kernel 3.8 or above • Union Filesystem

    support • Cgroups and namespaces enabled • This means no OSX (yet) • Although there is boot2docker
  13. WHY RUN DOCKER? • Fast, disposable development environments • Easy

    deployment of applications • Testing and integrations tasks
  14. WHY RUN DOCKER? • Microservice architectures • Scaling applications •

    DIY PaaS • … although this will not fit into today's schedule ;)
  15. BUT WHAT ABOUT PUPPET|ANSIBLE|CHEF|SALT? • Docker does not replace configuration

    management tools • These tools can in fact be used to provision docker platforms and/or containers themselves
  16. CONTAINER GOTCHAS • Not a VM! • There is no

    init process, *your* process is PID 1 instead • Security implications, isolation is not complete • No reaping, no cron, no services • Zombies!
  17. NODE (PID 1) SOMESCRIPT (PID 2) SOMETOOL (PID 3)

  18. NODE (PID 1) SOMESCRIPT (PID 2) SOMETOOL (PID 3)

  19. NODE (PID 1) SOMETOOL (PID 3)

  20. NODE (PID 1) SOMETOOL (PID 3) Brraaainns.

  21. $  docker  run  \      registry.dockerworkshop.dev/ubuntu:14.04  \    

     echo  "Hello  World" HELLO WORLD
  22. WHAT HAPPENED? • Docker downloaded an image from a registry

    • Docker ran our command • It quit (this is important)
  23. $  docker  run  \      registry.dockerworkshop.dev/ubuntu:14.04  \    

     /bin/bash INSIDE THE CONTAINER
  24. $  docker  run  -­‐ti  \      registry.dockerworkshop.dev/ubuntu:14.04  \  

       /bin/bash OOPS, SECOND TRY
  25. $  docker  images   $  docker  images  -­‐a LIST DOCKER

    IMAGES
  26. HANDS ON • Spin up an Ubuntu Container • Install

    Nginx* • Exit *  echo  "daemon  off;"  >>  /etc/nginx/nginx.conf
  27. $  docker  ps  -­‐a   $  docker  commit  [hash]  myfirstcontainer

      $  docker  run  myfirstcontainer  nginx WHAT NOW?
  28. $  docker  run  -­‐d  -­‐p  8080:80  myfirstcontainer  nginx   $

     docker  ps   $  curl  localhost:8080 PROPERLY DETACH AND CONNECT
  29. $  docker  exec  nginx  ps  -­‐aux A SNEAK PEEK INSIDE

  30. $  docker  ps   $  docker  stop  [name|tag]   $

     docker  rm  [name|tag]   $  docker  rm  -­‐f  [name|tag] CLEAN UP
  31. $  docker  tag  myfirstcontainer  \      registry.dockerworkshop.dev/myfirstcontainer   $

     docker  push  \      registry.dockerworkshop.dev/myfirstcontainer PROPERLY TAG & PUSH THE CONTAINER
  32. $  docker  search  registry.dockerworkshop.dev/nginx   $  docker  search  registry.dockerworkshop.dev/ubu PROPERLY

    TAG & PUSH THE CONTAINER
  33. $  curl  registry.dockerworkshop.dev/v1/search?q=ubu  |  jq  .   $  curl  registry.dockerworkshop.dev/v1/search

     |  jq  .   $  curl  \      registry.dockerworkshop.dev/v1/repositories/ubuntu/tags  \      |  jq  . ADVANCED: REGISTRY JSON API
  34. SHOULDN'T THIS BE AUTOMATED? • It's called Dockerfile • Defines

    all build steps • Build and tag (not push) in a single command • Cache results to speed up consecutive builds
  35. FROM  ubuntu:14.04   RUN  apt-­‐get  -­‐y  install  python-­‐pip   RUN

     apt-­‐get  -­‐y  install  python-­‐dev  liblzma-­‐dev  […]   ADD  .  /docker-­‐registry   ADD  ./config/boto.cfg  /etc/boto.cfg   RUN  pip  install  /docker-­‐registry/depends/docker-­‐ registry-­‐core   […]   EXPOSE  5000   CMD  exec  docker-­‐registry DOCKERFILE (Excerpt from Dockerfile for Docker Registry)
  36. docker  build  [OPTIONS]  PATH      -­‐-­‐force-­‐rm=false      

       Remove  intermediate  containers      -­‐-­‐no-­‐cache=false          Do  not  use  cache  when  building      -­‐q,  -­‐-­‐quiet=false        Suppress  verbose  output      -­‐-­‐rm=true                        Remove  intermediate  containers      -­‐t,  -­‐-­‐tag=""                  Repository  name  and  tag DOCKERFILE
  37. $  docker  build  \      -­‐t  registry.dockerworkshop.dev/nginx:phpbnl15  ./ DOCKERFILE

  38. HANDS ON • Write a Dockerfile for a Nginx container

    • Build and push it • You may check the cheat folder for "nginx" to save some typing
  39. server  {                

       […]          access_log  /dev/stdout;   $  docker  logs  -­‐f  nginx LOGGING
  40. USE CASE: TESTING

  41. HANDS ON • We need a container running PHP-CLI •

    For simplicity, a global phpunit.phar install • We need a workdir to define where we will run our tests later • Tag as registry.dockerworkshop.dev/ phpunit:php55
  42. $  docker  run  -­‐rm  \      registry.dockerworkshop.dev/phpunit:php55  phpunit EXECUTE

  43. HANDS ON • Build another phpunit container • This time,

    running PHP 5.3.x • (Yes, 5.3) • Hint: There is a ubuntu:12.04 in the registry • Tag as registry.dockerworkshop.dev/ phpunit:php53
  44. $  docker  run  -­‐rm  \      registry.dockerworkshop.dev/phpunit:php53  phpunit EXECUTE

  45. NICE, BUT… • Isolated, throw-away testing environments! • We still

    have a dedicated config on the CI side, because it needs to know about specifics (like the container names)
  46. None
  47. INTRODUCING FUGU • Written in Go • Utility to preconfigure

    docker run & build commands • For single containers • A single, simple YAML file • Allows us to configure our tests a bit similar to Travis (right in our project)
  48. fugu  <command>  [fugufile]  \            [label]

     [docker-­‐options]  [command]  [args...]   commands:      run                  wraps  docker  run      build              wraps  docker  build FUGU
  49. #  fugu.yml   default:      image:    dockerfile/nginx  

       name:      hello-­‐world-­‐nginx      detach:  true      publish:          -­‐  8080:80      volume:          -­‐  /host/path:/container/path            […] FUGUFILE
  50. #  fugu.yml   default:      image:      registry.dockerworkshop.dev/myfirstcontainer

         command:  nginx      name:        fugutest      detach:    true      publish:          -­‐  8080:80 EXAMPLE: OUR FIRST CONTAINER
  51. HANDS ON • Add a fugu.yml to our PHP Project

    • Use two labels to run both PHP Versions • Result: • $  fugu  run  php55   • $  fugu  run  php53
  52. IDEAS • Build a complete single container with DB and

    fixtures and run Behat • Build separate DB containers with different fixtures • If a test fails, push the resulting container to a registry for further analysis • …
  53. DOCKERIZING A WEB APP

  54. REQUIREMENTS • Extend our Nginx container with PHP-FPM • Build

    a separate MySQL container • Connect them somehow
  55. HANDS ON: PHP • Base: our Nginx container • Install

    PHP Packages and supervisord • Download and install composer • Replace webroot, Nginx config, index.html • Set CMD to supervisor • Tag and push
  56. $  docker  run  -­‐d  -­‐P  -­‐-­‐name  php5  \    

     -­‐v  /home/vagrant/docker-­‐workshop-­‐app/:/var/www/  \      registry.dockerworkshop.dev/php5 PHP
  57. HANDS ON: MYSQL • Cheat: we use the official MySQL

    Dockerfile ;) • Try to add DB creation, see SQL in web application root • Tag and push
  58. $  docker  run  -­‐d  -­‐P  -­‐-­‐name  mysql  \    

     registry.dockerworkshop.dev/mysql MYSQL
  59. CONNECTING • The PHP container needs to now where to

    find the DB • Solution: Links • Create environment variables with network info • Add entries to /etc/hosts
  60. $  docker  run  -­‐d  -­‐P  -­‐-­‐name  php5  —link  mysql:mysql  \

         -­‐v  /home/vagrant/docker-­‐workshop-­‐app/:/var/www/  \      registry.dockerworkshop.dev/php5 PHP
  61. HANDS ON • Run the PHP container interactively and check

    out the /etc/hosts file • Modify the database connection code in src/app.php line 27 to use the new hostname
  62. #  fig.yml   web:      build:  .    

     command:  python  app.py      links:        -­‐  db      ports:        -­‐  "8000:8000"   db:      image:  postgres FIG
  63. THANKS! Please give feedback: https:/ /joind.in/13101