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
Tweet

More Decks by Andreas Hucks

Other Decks in Programming

Transcript

  1. INTRODUCTION TO DOCKER
    WORKSHOP, PHPBENELUX2015

    View Slide

  2. ANDREAS HUCKS
    Software Architect at SensioLabs DE
    @meandmymonkey

    View Slide

  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

    View Slide

  4. View Slide

  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

    View Slide

  6. $  cd  /path/to/vagrantfile  
    $  vagrant  up  
    $  vagrant  ssh  playground
    SETUP: SPIN UP VAGRANT & CONNECT

    View Slide

  7. $  pwd  
    /home/vagrant  
    $  whoami  
    vagrant  
    $  lsb_release  -­‐a  
    Distributor  ID:  Ubuntu  
    Description:        Ubuntu  14.04  LTS  
    Release:                14.04  
    Codename:              trusty
    ENVIRONMENT

    View Slide

  8. SOFTWARE DEVELOPMENT
    IS ABOUT BREAKING
    PROBLEMS INTO SMALLER
    PIECES

    View Slide

  9. WHAT ARE (DOCKER) CONTAINERS?
    • Linux Containers
    • Have been around for some years
    • They are not VMs
    • Use the same kernel

    View Slide

  10. WHAT ARE (DOCKER) CONTAINERS?
    • Kernel Namespaces
    • cgroups
    • See https:/
    /linuxcontainers.org/

    View Slide

  11. WHAT ARE (DOCKER) CONTAINERS?
    • Docker creates a simple API for all of this
    • Written in Go
    • Provides a CLI and a RESTlike API

    View Slide

  12. RUNNING DOCKER
    • Kernel 3.8 or above
    • Union Filesystem support
    • Cgroups and namespaces enabled
    • This means no OSX (yet)
    • Although there is boot2docker

    View Slide

  13. WHY RUN DOCKER?
    • Fast, disposable development
    environments
    • Easy deployment of applications
    • Testing and integrations tasks

    View Slide

  14. WHY RUN DOCKER?
    • Microservice architectures
    • Scaling applications
    • DIY PaaS
    • … although this will not fit into today's
    schedule ;)

    View Slide

  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

    View Slide

  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!

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  21. $  docker  run  \  
       registry.dockerworkshop.dev/ubuntu:14.04  \  
       echo  "Hello  World"
    HELLO WORLD

    View Slide

  22. WHAT HAPPENED?
    • Docker downloaded an image from a
    registry
    • Docker ran our command
    • It quit (this is important)

    View Slide

  23. $  docker  run  \  
       registry.dockerworkshop.dev/ubuntu:14.04  \  
       /bin/bash
    INSIDE THE CONTAINER

    View Slide

  24. $  docker  run  -­‐ti  \  
       registry.dockerworkshop.dev/ubuntu:14.04  \  
       /bin/bash
    OOPS, SECOND TRY

    View Slide

  25. $  docker  images  
    $  docker  images  -­‐a
    LIST DOCKER IMAGES

    View Slide

  26. HANDS ON
    • Spin up an Ubuntu Container
    • Install Nginx*
    • Exit
    *  echo  "daemon  off;"  >>  /etc/nginx/nginx.conf

    View Slide

  27. $  docker  ps  -­‐a  
    $  docker  commit  [hash]  myfirstcontainer  
    $  docker  run  myfirstcontainer  nginx
    WHAT NOW?

    View Slide

  28. $  docker  run  -­‐d  -­‐p  8080:80  myfirstcontainer  nginx  
    $  docker  ps  
    $  curl  localhost:8080
    PROPERLY DETACH AND CONNECT

    View Slide

  29. $  docker  exec  nginx  ps  -­‐aux
    A SNEAK PEEK INSIDE

    View Slide

  30. $  docker  ps  
    $  docker  stop  [name|tag]  
    $  docker  rm  [name|tag]  
    $  docker  rm  -­‐f  [name|tag]
    CLEAN UP

    View Slide

  31. $  docker  tag  myfirstcontainer  \  
       registry.dockerworkshop.dev/myfirstcontainer  
    $  docker  push  \  
       registry.dockerworkshop.dev/myfirstcontainer
    PROPERLY TAG & PUSH THE CONTAINER

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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)

    View Slide

  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

    View Slide

  37. $  docker  build  \  
       -­‐t  registry.dockerworkshop.dev/nginx:phpbnl15  ./
    DOCKERFILE

    View Slide

  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

    View Slide

  39. server  {  
             
           […]  
           access_log  /dev/stdout;  
    $  docker  logs  -­‐f  nginx
    LOGGING

    View Slide

  40. USE CASE: TESTING

    View Slide

  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

    View Slide

  42. $  docker  run  -­‐rm  \  
       registry.dockerworkshop.dev/phpunit:php55  phpunit
    EXECUTE

    View Slide

  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

    View Slide

  44. $  docker  run  -­‐rm  \  
       registry.dockerworkshop.dev/phpunit:php53  phpunit
    EXECUTE

    View Slide

  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)

    View Slide

  46. View Slide

  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)

    View Slide

  48. fugu    [fugufile]  \  
             [label]  [docker-­‐options]  [command]  [args...]  
    commands:  
       run                  wraps  docker  run  
       build              wraps  docker  build
    FUGU

    View Slide

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

    View Slide

  50. #  fugu.yml  
    default:  
       image:      registry.dockerworkshop.dev/myfirstcontainer  
       command:  nginx  
       name:        fugutest  
       detach:    true  
       publish:  
           -­‐  8080:80
    EXAMPLE: OUR FIRST CONTAINER

    View Slide

  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

    View Slide

  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
    • …

    View Slide

  53. DOCKERIZING A
    WEB APP

    View Slide

  54. REQUIREMENTS
    • Extend our Nginx container with PHP-FPM
    • Build a separate MySQL container
    • Connect them somehow

    View Slide

  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

    View Slide

  56. $  docker  run  -­‐d  -­‐P  -­‐-­‐name  php5  \  
       -­‐v  /home/vagrant/docker-­‐workshop-­‐app/:/var/www/  \  
       registry.dockerworkshop.dev/php5
    PHP

    View Slide

  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

    View Slide

  58. $  docker  run  -­‐d  -­‐P  -­‐-­‐name  mysql  \  
       registry.dockerworkshop.dev/mysql
    MYSQL

    View Slide

  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

    View Slide

  60. $  docker  run  -­‐d  -­‐P  -­‐-­‐name  php5  —link  mysql:mysql  \  
       -­‐v  /home/vagrant/docker-­‐workshop-­‐app/:/var/www/  \  
       registry.dockerworkshop.dev/php5
    PHP

    View Slide

  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

    View Slide

  62. #  fig.yml  
    web:  
       build:  .  
       command:  python  app.py  
       links:  
         -­‐  db  
       ports:  
         -­‐  "8000:8000"  
    db:  
       image:  postgres
    FIG

    View Slide

  63. THANKS!
    Please give feedback:
    https:/
    /joind.in/13101

    View Slide