Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to Docker at PHPBenelux2015

Introduction to Docker at PHPBenelux2015

Andreas Hucks

January 23, 2015

More Decks by Andreas Hucks

Other Decks in Programming


  1. 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
  2. $  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
  3. $  cd  /path/to/vagrantfile   $  vagrant  up   $  vagrant

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

    $  lsb_release  -­‐a   Distributor  ID:  Ubuntu   Description:        Ubuntu  14.04  LTS   Release:                14.04   Codename:              trusty ENVIRONMENT
  5. WHAT ARE (DOCKER) CONTAINERS? • Linux Containers • Have been

    around for some years • They are not VMs • Use the same kernel
  6. WHAT ARE (DOCKER) CONTAINERS? • Docker creates a simple API

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

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

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

    DIY PaaS • … although this will not fit into today's schedule ;)
  10. 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
  11. 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!
  12. WHAT HAPPENED? • Docker downloaded an image from a registry

    • Docker ran our command • It quit (this is important)
  13. HANDS ON • Spin up an Ubuntu Container • Install

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

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

     docker  ps   $  curl  localhost:8080 PROPERLY DETACH AND CONNECT
  16. $  docker  ps   $  docker  stop  [name|tag]   $

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

     docker  push  \      registry.dockerworkshop.dev/myfirstcontainer PROPERLY TAG & PUSH THE CONTAINER
  18. $  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
  19. 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
  20. 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)
  21. 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
  22. 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
  23. server  {                

       […]          access_log  /dev/stdout;   $  docker  logs  -­‐f  nginx LOGGING
  24. 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
  25. 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
  26. 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)
  27. 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)
  28. fugu  <command>  [fugufile]  \            [label]

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

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

         command:  nginx      name:        fugutest      detach:    true      publish:          -­‐  8080:80 EXAMPLE: OUR FIRST CONTAINER
  31. 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
  32. 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 • …
  33. REQUIREMENTS • Extend our Nginx container with PHP-FPM • Build

    a separate MySQL container • Connect them somehow
  34. 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
  35. $  docker  run  -­‐d  -­‐P  -­‐-­‐name  php5  \    

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

    Dockerfile ;) • Try to add DB creation, see SQL in web application root • Tag and push
  37. 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
  38. $  docker  run  -­‐d  -­‐P  -­‐-­‐name  php5  —link  mysql:mysql  \

         -­‐v  /home/vagrant/docker-­‐workshop-­‐app/:/var/www/  \      registry.dockerworkshop.dev/php5 PHP
  39. 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
  40. #  fig.yml   web:      build:  .    

     command:  python  app.py      links:        -­‐  db      ports:        -­‐  "8000:8000"   db:      image:  postgres FIG