$30 off During Our Annual Pro Sale. View Details »

Introduction to Docker at PHPNW2014

Introduction to Docker at PHPNW2014

Slides for my Docker workshop at PHPNW 2014.

https://joind.in/11762

Andreas Hucks

October 04, 2014
Tweet

More Decks by Andreas Hucks

Other Decks in Programming

Transcript

  1. INTRODUCTION TO DOCKER
    !
    !
    WORKSHOP, PHPNW2014

    View Slide

  2. ANDREAS HUCKS
    Software Architect at SensioLabs DE
    @meandmymonkey

    View Slide

  3. View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

  7. SOFTWARE DEVELOPMENT
    IS ABOUT BREAKING
    PROBLEMS INTO SMALLER
    PIECES

    View Slide

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

    View Slide

  9. WHAT ARE (DOCKER) CONTAINERS?
    • liblxc
    • Separated by Kernel Namespaces
    • cgroups
    • See https:/
    /linuxcontainers.org/

    View Slide

  10. 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

  11. RUNNING DOCKER
    • Kernel 3.8 or above
    • AUFS support
    • Cgroups and namespaces enabled
    • This means no OSX (yet)
    • Although there is boot2Docker

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  20. $  docker  images  
    !
    !
    !
    $  docker  images  -­‐a
    LIST DOCKER IMAGES

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  24. $  docker  ps  
    !
    $  docker  stop  [name]  
    !
    $  docker  rm  [name]
    CLEAN UP

    View Slide

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

    View Slide

  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

    View Slide

  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)

    View Slide

  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

    View Slide

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

    View Slide

  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

    View Slide

  31. USE CASE: TESTING

    View Slide

  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

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

  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)

    View Slide

  37. View Slide

  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)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

  44. DOCKERIZING A
    WEB APP

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

  54. THANKS!
    !
    Please give feedback:
    https:/
    /joind.in/11762

    View Slide