Slide 1

Slide 1 text

INTRODUCTION TO DOCKER WORKSHOP, PHPBENELUX2015

Slide 2

Slide 2 text

ANDREAS HUCKS Software Architect at SensioLabs DE @meandmymonkey

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

$  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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

SOFTWARE DEVELOPMENT IS ABOUT BREAKING PROBLEMS INTO SMALLER PIECES

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 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 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 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 16

Slide 16 text

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!

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

NODE (PID 1) SOMETOOL (PID 3)

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

$  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

Slide 34

Slide 34 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 35

Slide 35 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 36

Slide 36 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 37

Slide 37 text

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

Slide 38

Slide 38 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 39

Slide 39 text

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

Slide 40

Slide 40 text

USE CASE: TESTING

Slide 41

Slide 41 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 42

Slide 42 text

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

Slide 43

Slide 43 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 44

Slide 44 text

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

Slide 45

Slide 45 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 46

Slide 46 text

No content

Slide 47

Slide 47 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 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 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 52

Slide 52 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 53

Slide 53 text

DOCKERIZING A WEB APP

Slide 54

Slide 54 text

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

Slide 55

Slide 55 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 56

Slide 56 text

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

Slide 57

Slide 57 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 58

Slide 58 text

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

Slide 59

Slide 59 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 60

Slide 60 text

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

Slide 61

Slide 61 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 62

Slide 62 text

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

Slide 63

Slide 63 text

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