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
$ 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
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
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
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
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