Slide 1

Slide 1 text

INTRODUCTION TO DOCKER ! ! WORKSHOP, PHPNW2014

Slide 2

Slide 2 text

ANDREAS HUCKS Software Architect at SensioLabs DE @meandmymonkey

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

$  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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

SOFTWARE DEVELOPMENT IS ABOUT BREAKING PROBLEMS INTO SMALLER PIECES

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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)

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

USE CASE: TESTING

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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)

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

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)

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

DOCKERIZING A WEB APP

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

HANDS ON: MYSQL • Cheat: we use the official MySQL Dockerfile ;) • Try to add DB creation, see SQL in web application root • Tag and push

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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