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

Introduction to Docker at PHPNW2014

Introduction to Docker at PHPNW2014

Slides for my Docker workshop at PHPNW 2014.

https://joind.in/11762

E9612cd342dbddff6640b99db21deee7?s=128

Andreas Hucks

October 04, 2014
Tweet

Transcript

  1. INTRODUCTION TO DOCKER ! ! WORKSHOP, PHPNW2014

  2. ANDREAS HUCKS Software Architect at SensioLabs DE @meandmymonkey

  3. None
  4. $  vagrant  box  add  -­‐-­‐name  phpnw14-­‐services  \      /path/to/phpnw14-­‐services.box

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

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

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

  8. WHAT ARE (DOCKER) CONTAINERS? • LXC • Have been around

    for some years • They are not VMs • Use the same kernel
  9. WHAT ARE (DOCKER) CONTAINERS? • liblxc • Separated by Kernel

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

    for all of this • Written in Go • Provides a CLI and a RESTlike API
  11. RUNNING DOCKER • Kernel 3.8 or above • AUFS support

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

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

    DIY PaaS • … although this will not fit into today's schedule ;)
  14. 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
  15. CONTAINER GOTCHAS • Not a VM! • There is no

    init process, *your* process is PID 1 instead • No reaping, no cron, no services • Zombies! • Security implications, isolation is not complete
  16. $  docker  run  \      registry.dockerworkshop.dev/ubuntu:14.04  \    

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

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

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

       /bin/bash OOPS, SECOND TRY
  20. $  docker  images   ! ! ! $  docker  images

     -­‐a LIST DOCKER IMAGES
  21. HANDS ON • Spin up an Ubuntu Container • Install

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

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

    $  docker  ps   ! $  curl  localhost:8080 PROPERLY DETACH AND CONNECT
  24. $  docker  ps   ! $  docker  stop  [name]  

    ! $  docker  rm  [name] CLEAN UP
  25. $  docker  tag  myfirstcontainer  \      registry.dockerworkshop.dev/myfirstcontainer   !

    $  docker  push  \      registry.dockerworkshop.dev/myfirstcontainer PROPERLY TAG & PUSH THE CONTAINER
  26. 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
  27. 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)
  28. 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
  29. $  docker  build  \      -­‐t  registry.dockerworkshop.dev/nginx:phpnw14  ./ DOCKERFILE

  30. 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
  31. USE CASE: TESTING

  32. 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
  33. $  docker  run  -­‐rm  \      registry.dockerworkshop.dev/phpunit:php55  phpunit EXECUTE

  34. 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
  35. $  docker  run  -­‐rm  \      registry.dockerworkshop.dev/phpunit:php53  phpunit EXECUTE

  36. 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)
  37. None
  38. 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)
  39. fugu  <command>  [fugufile]  \            [label]

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

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

     registry.dockerworkshop.dev/myfirstcontainer      command:  nginx      name:        fugutest      detach:    true      publish:          -­‐  8080:80 EXAMPLE: OUR FIRST CONTAINER
  42. 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
  43. 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 • …
  44. DOCKERIZING A WEB APP

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

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

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

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

     registry.dockerworkshop.dev/mysql MYSQL
  50. 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
  51. $  docker  run  -­‐d  -­‐P  -­‐-­‐name  php5  —link  mysql:mysql  \

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

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