Ladislav Prskavec
4 yearsdocker
packer
Canonical's JuJu serf
CloudFlare
SoundCloud
What is docker?
an open source project to pack,
ship and run any application as
a lightweight container
Why container?
Analogy from logistics
build once,
run anywhere
~ developer
configure once,
run anything
~ operations
Containers are
to Virtual Machines
as threads are to processes.
Or you can think of them as
chroots on steroids.
~ Will Sargent
What is container in docker?
• Kernel namespaces (ipc, uts, mount, pid, network
and user)
• Chroots (using pivot_root)
• Apparmor and SELinux profiles
• Kernel capabilities
• Control groups (cgroups)
• AUFS or replacement in version and later
SERVER
HOST OS
Docker Engine
Container
A
Container
B
Container
C
SERVER
HOST OS
Docker Engine
Container
A
Container
B
Container
C
SERVER
HOST OS
Hypervisor
Guest OS Guest OS Guest OS
APP
A
APP
B
APP
C
Basics
Installation
Finding and
downloading images
docker
search
ubuntu
docker
pull
shykes/ubuntu
Running
docker
run
ubuntu
/bin/echo
hello
world
!
docker
run
-‐i
-‐t
ubuntu
/bin/bash
Committing your
changes
docker
ps
-‐l
docker
commit
ID
base/with_curl
Pushing an image to
the repository
docker
push
abtris/curl
docker
push
internal_repository:5000/curl
Image
Parent Image
Dockerfile Best Practices
• Use the cache
• Use tags
• EXPOSE-ing ports
• CMD and ENTRYPOINT syntax
• CMD and ENTRYPOINT better together
Use the cache
FROM
ubuntu:latest
MAINTAINER
Ladislav
Prskavec
!
RUN
echo
"deb
precise
main
universe"
>
/etc/apt/
!
RUN
apt-‐get
update
RUN
apt-‐get
-‐y
upgrade
Use tags
!
docker
build
-‐t="abtris/sentry"
.
EXPOSE-ing ports
!
#
private
and
public
mapping
EXPOSE
80:8080
!
#
private
only
EXPOSE
80
CMD and ENTRYPOINT
!
!
CMD
/bin/echo
#
or
CMD
["/bin/echo"]
CMD and ENTRYPOINT
better together
RUN
apt-‐get
install
-‐y
rethinkdb
!
#
Rethinkdb
process
EXPOSE
28015
#
Rethinkdb
admin
console
EXPOSE
8080
!
#
Create
the
/rethinkdb_data
dir
structure
RUN
/usr/bin/rethinkdb
create
!
ENTRYPOINT
["/usr/bin/rethinkdb"]
!
CMD
["-‐-‐help"]
Running
'rethinkdb'
will
create
a
new
data
directory
or
use
an
existing
one,
and
serve
as
a
RethinkDB
cluster
node.
File
path
options:
-‐d
[
-‐-‐directory
]
path
specify
directory
to
store
data
and
metadata
-‐-‐io-‐threads
n
how
many
simultaneous
I/O
operations
can
happen
at
the
same
time
!
Machine
name
options:
-‐n
[
-‐-‐machine-‐name
]
arg
the
name
for
this
machine
(as
will
appear
in
the
metadata).
If
not
specified,
it
will
be
randomly
chosen
from
a
short
list
of
names.
!
Network
options:
-‐-‐bind
{all
|
addr}
add
the
address
of
a
local
interface
to
listen
on
when
accepting
connections;
loopback
addresses
are
enabled
by
default
-‐-‐cluster-‐port
port
port
for
receiving
connections
from
other
nodes
-‐-‐driver-‐port
port
port
for
rethinkdb
protocol
client
drivers
-‐o
[
-‐-‐port-‐offset
]
offset
all
ports
used
locally
will
have
this
value
added
-‐j
[
-‐-‐join
]
host:port
host
and
port
of
a
rethinkdb
node
to
connect
to
.................
docker run crosbymichael/rethinkdb
info:
Running
rethinkdb
-‐0ubuntu1~precise
(GCC
)...
info:
Running
on
Linux
-‐45-‐virtual
x86_64
info:
Loading
data
from
directory
/rethinkdb_data
warn:
Could
not
turn
off
filesystem
caching
for
database
file:
"/
rethinkdb_data/metadata"
(Is
the
file
located
on
a
filesystem
that
doesn't
support
direct
I/O
(.
some
encrypted
or
journaled
file
systems)?)
This
can
cause
performance
problems.
warn:
Could
not
turn
off
filesystem
caching
for
database
file:
"/
rethinkdb_data/auth_metadata"
(Is
the
file
located
on
a
filesystem
that
doesn't
support
direct
I/O
(.
some
encrypted
or
journaled
file
systems)?)
This
can
cause
performance
problems.
info:
Listening
for
intracluster
connections
on
port
29015
info:
Listening
for
client
driver
connections
on
port
28015
info:
Listening
for
administrative
HTTP
connections
on
port
8080
info:
Listening
on
addresses:
,
info:
Server
ready
info:
Someone
asked
for
the
nonwhitelisted
file
/js/
-‐,
if
this
should
be
accessible
add
it
to
the
whitelist.
docker run crosbymichael/rethinkdb —bind all
FROM
ubuntu:latest
MAINTAINER
Ladislav
Prskavec
<ladislav@>
RUN
apt-‐get
update
RUN
apt-‐get
-‐y
upgrade
RUN
DEBIAN_FRONTEND=noninteractive
apt-‐get
-‐y
install
curl
apache2
libapache2-‐mod-‐php5
vim-‐tiny
RUN
chown
-‐R
www-‐data:www-‐data
/var/www/
EXPOSE
80
EXPOSE
22
CMD
["/bin/bash"]
git clone
docker build .
Dockerfile
Use raw Dockerfile
1. Cache wins.
2. Chef, ansible, etc, does not use cache.
3. Raw Dockerfile uses cache.
4. Raw Dockerfile wins.
Links
• If you have a docker container with the name CONTAINER
(specified by docker run -name CONTAINER) and in the
Dockerfile, it has an exposed port:
EXPOSE 1337
• docker run -d -link CONTAINER:ALIAS -name LINKED
user/wordpress
• CONTAINER will show up in LINKED with the following
environment variables:
$ALIAS_PORT_1337_TCP_PORT
$ALIAS_PORT_1337_TCP_ADDR
Container Lifecycle
• docker run - creates a container.
• docker stop stops it.
• docker start will start it again.
• docker restart restarts a container.
• docker rm deletes a container.
• docker attach will connect to a running container.
• docker wait blocks until container stops.
Container Info
• docker ps shows running containers.
• docker ps -a shows running and stopped containers.
• docker inspect looks at all the info on a container (including IP
address).
• docker logs gets logs from container.
• docker events gets events from container.
• docker port shows public facing port of container.
• docker top shows running processes in container.
Import / Export
• docker cp copies into a container.
• docker export turns container fs into tarball.
Images Lifecycle
• docker import creates an image from a tarball.
• docker build creates image from Dockerfile.
• docker commit creates image from a container.
• docker rmi removes an image.
• docker insert inserts a file from URL into image
Images Info
• docker images shows all images
• docker history shows history of image
• docker tag tags an image to a name (local or
registry)
Registry & Repository
• docker search searches registry for image
• docker pull pulls an image from registry to local
machine
• docker push pushes an image to the registry from
local machine.
Good practices
• Install a internal docker registry
• Install Shipyard
• Create base image
• Build from your base image
• Push your images
• Save off your registry
Install a internal docker
registry
• Install an internal registry (the fast way) and run it as a
daemon:
docker
run
-‐name
internal_registry
-‐d
-‐p
5000:5000
samalba/docker-‐registry
• Alias server to localhost
echo
"
internal_registry"
>>
/etc/
host
• Check internal_registry exists and is running on port 5000:
curl
-‐-‐get
-‐-‐verbose
http://internal_registry:5000/v1/
_ping
Create base image
• Create a Dockerfile with initialization code such as
`apt-get update / apt-get install’ etc: this is your
base.
• Build your base image, then push it to the internal
registry with
docker
build
-‐t
internal_registry:5000/
base
.
Build from your base image
• Build all of your other Dockerfile pull from “base”
instead of ubuntu.
• Keep playing around until you have your images
working.
Push your images
• Push all of your images into the internal registry.
docker
tag
IMAGE-‐ID
abtris/apache
docker
push
internal_registry:5000/apache
Save off your registry
• If you need to blow away your Vagrant or set
someone else up, it’s much faster to do it with all
the images still intact:
docker
export
internal_registry
>
gzip
mv
/vagrant
Projects uses docker
abtris/devfest-2013/