
Docker by Example
By: Seve, Joey, and Richi
Rensselaer Center for Open Source

Outline
- What is docker?
- Installing docker
- What are containers? What are images?
- Why do developers use docker?
- How to run containers
- How to run applications via containers
- How to make a docker image
- Docker Compose overview

Examples
This presentation will frequently break to execute examples.
To follow along, clone the docker-examples repo:
https://github.com/rcos/docker-examples
Warning: Docker will download images for these demonstrations, these images can be removed but may take up 1-3gb
What is Docker ?

Wikipedia Definition
Docker is an open-source project that automates the deployment of applications inside software containers, by providing an additional layer of abstraction and automation of operating-system-level virtualization on Linux.

... nice, thanks, and ?
Linux Containers
Docker is based on LXC (Linux Containers) which allows
it to isolate containers from each other.
LXC use mainly two Linux Kernel features:
- Namespaces (Isolation of resources)
- Cgroups (Isolation of resource usage, as CPU/RAM)

Docker World
Docker can be split in multiple different parts :
- Docker Engine
- Docker Hub
- Docker Company

Container VS VM


Container VS Image

Image
An image is an inert snapshot of a container.
When runned (with a docker run command) it becomes a container.
As images can be quite heavy they are designed to be composed of layers of other images which allows to minimize an image weight, and those layers can be reused between images.
Images are stored (mainly) on Docker Hub.
Container VS Image

Image
An image is built from a Dockerfile. A file describing how the image is supposed to behave, what it extends from, ...
docker images command lists all local images :
➜ image2 git:(master) ✗ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ekkinox/image2 latest 99575a3e62ce 19 minutes ago 126.6 MB
ekkinox/image1 latest e4d90038788c 32 minutes ago 126.6 MB
doclersfbasicworkshop_nginx latest e40e5460d6cb 18 hours ago 183.2 MB
doclersfbasicworkshop_php latest 29c570fb5d03 18 hours ago 392.3 MB
tianon/true latest 2cf9735a9162 19 hours ago 125 B
nazarpc/phpmyadmin latest 5e14ef86056e 44 hours ago 433.5 MB
php 5.6-fpm c90bf43470d1 46 hours ago 362.7 MB
phpmyadmin/phpmyadmin latest de9568a72415 2 days ago 116.2 MB
mysql 5.6 72bb9d97fb75 11 days ago 328.9 MB
nginx stable 5c9792e3619e 2 weeks ago 182.8 MB
ubuntu 16.04 bd3d4369aebc 3 weeks ago 126.6 MB
ubuntu 14.04 4a725d3b3b1c 3 weeks ago 188 MBContainer VS Image

Container
Programmatically speaking, if an image is a class, then a container would be an instance of this class.
So, you can launch multiple containers for the same image (multiple instances).
docker ps command lists all running containers :
➜ image2 git:(master) ✗ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
396fa752515e ekkinox/image2 "/bin/bash" 20 minutes ago Up 20 minutes high_panini
aa60196275a3 ekkinox/image1 "/bin/bash" 29 minutes ago Up 29 minutes reverent_fermi
c7f259822acb ubuntu:16.04 "/bin/bash" 36 minutes ago Up 36 minutes awesome_elion
70ef83fa7097 ubuntu:14.04 "/bin/bash" 37 minutes ago Up 37 minutes silly_mclean
698cd8bd50fe nazarpc/phpmyadmin "/home/entrypoint.sh" 17 hours ago Up 17 hours 0.0.0.0:1234->80/tcp doclersfbasicworkshop_phpmyadmin_1
4c5dd41b5a55 doclersfbasicworkshop_nginx "nginx -g 'daemon off" 18 hours ago Up 18 hours 0.0.0.0:80->80/tcp, 443/tcp doclersfbasicworkshop_nginx_1
e58a4384d27a mysql:5.6 "docker-entrypoint.sh" 18 hours ago Up 18 hours 0.0.0.0:3306->3306/tcp doclersfbasicworkshop_db_1
faf8aba5cd3c doclersfbasicworkshop_php "php-fpm" 18 hours ago Up 18 hours 9000/tcp doclersfbasicworkshop_php_1Technical Details

Why
-
Run everywhere
- Regardless of kernel version
- Regardless of host distro.
- Physical or virtual, cloud or not
- Container and host architecture must match...
-
Run anything
- If it can run on the host, it can run in the container
- If it can run on a Linux kernel, it can run in the container
What
-
High level: a lightweight VM
- Own process space
- Own network interface
- Can run stuff as root
- Can have its own /sbin/init (different from host)
-
Low Level: Chroot on steroids
- Can also not have its own /sbin/init
- Container = isolated processes
- Share kernel with host
Why Developers Care

- A clean, safe, hygienic, portable runtime environment for your app.
- No worries about missing dependencies, packages and other pain points during subsequent deployments.
- Run each app in its own isolated container, so you can run various versions of libraries and other dependencies for each app without worrying.
- Automate testing, integration, packaging... anything you can script.
- Reduce/eliminate concerns about compatibility on different platforms.
- Cheap, zero-penalty containers to deploy services. A VM without the overhead of a VM. Instant replay and reset of image snapshots.
- Makes the entire lifecycle more efficient, consistent, and repeatable
Example 00
Installing Docker

Install Docker: https://docs.docker.com/engine/installation/
Go ahead and install Docker and we'll help you out if you have any problems/question
Build our first container

$ docker run -itd ubuntu:16.04To create a container from the official ubuntu image :
To enter into a container with your terminal (logged as root):
$ docker exec -it CONTAINERID bashTo check your running containers and their ids :
$ docker psExample 01
Run cowsay in an ubuntu container!

Containers on Docker Hub

Many applications put containers on docker hub.
Docker hub usually gives simple instructions for running the image, independent of the host operating system!
Example Docker Hub Image


Example 02
Running a docker application from existing images

Turning containers into images

As said before :
An image is a snapshot of a container
Let's take a snapshot of our container :
$ docker commit -m "First commit" CONTAINERID ekkinox/image1Build a container

You can now create as many container from this image as you want :
$ docker run -dit ekkinox/image1-d : Daemonized
-it : Allocate TTY
Image name
Dockerfile

This approach is nice but as developers
we highly prefer working in files than terminals, right ?
That's why Docker uses Dockerfiles.
Dockerfile

A Dockerfile is a translation of what the image will be :
FROM ubuntu:16.04
MAINTAINER Jonathan VUILLEMIN <ekkinox@gmail.com>
RUN mkdir -p /home/ekkinox
To build an image from this Dockerfile :
$ docker build -t ekkinox/image2 .Container

To create a container from our new image :
$ docker run -dit ekkinox/image2-d : Daemonized
-it : Allocate TTY
Image name
Example 03
Build a Dockerfile

How to Dockerize Your Application!

Process:
- Pick a base image (ubuntu, node, python, etc.)
- Copy your application
- Install your dependencies
- Run your Application
Dockerfile

# Choose base image
FROM node:argon
# Copy application files
COPY . /usr/src/app
# Set working directory
WORKDIR /usr/src/app
# Install app dependencies
RUN npm install
# Expose Container's port
EXPOSE 3001
# Run the application
CMD [ "node", "app.js" ]Code changes impacts

A better solution ? volumes
First, remove the COPY directive from our Dockerfile:
# Choose base image
FROM node:argon
# Set working directory
WORKDIR /usr/src/app
# Install app dependencies
RUN npm install
# Expose Container's port
EXPOSE 3001
# Run the application
CMD [ "node", "app.js" ]And build & run the container with a volume (-v)
$ docker build -t exampleApp .
$ docker run -v .:/usr/src/app exampleAppAnd now we can see the changed behavior !
Docker Commands

Useful Docker Commands
# List docker images
docker images
# List running docker containers
docker ps
# Retrieve, Log and Follow output from docker container
docker logs -f <container-id>
# Enter terminal of container
docker exec -it <container-id> bashDocker Hub

Docker Hub contains a lot of images for various purposes.
Docker Hub provides a free storage facility for your public images and a paying storage facility for your private images (GitHub style).
Login to Docker Hub

docker loginBuild your image

docker build -t seveibar/exampleApp .Push on Docker Hub

$ docker push seveibar/exampleAppPull from Docker Hub

$ docker pull seveibar/exampleAppAutomated Builds

Docker Hub allows you to link a GitHub repository to a Docker Hub repository.
Your GitHub repository should contain a Dockerfile on the root directory.
Each time you push on GitHub, Docker Hub (through webhooks) will pull your repository and build an image into your Docker Hub repository.
Orchestration

So, running all containers by hand can
be really messy and complicated... saw it.
"Damned, i'll never use this Docker stuff..."
Orchestration

For the moment our simple application requires us to do those kind of commands :
$ docker run \
--name mysql \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_DATABASE=ekkinox \
-d \
mysql
$ docker run \
-v /home/nox/Dev/docker_workshop/php-fpm/script:/usr/src/myscript \
my-php-script2
$ ... and more and more pain 0_x !Orchestration

Solutions ?
- Put those commands into a README ?
- Put those commands into a bash script ?
No. Bad idea.
The solution is Docker compose
Orchestration

Docker compose works by putting a single yaml file in your project.
Using Compose is basically a three-step process.
- Define your app's environment with a Dockerfile so it can be reproduced anywhere
- Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
- Lastly, run docker-compose up and Compose will start and run your entire app.
Orchestration

version: '2'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}A docker-compose.yml looks like this:
Orchestration

Some docker useful commands:
# Stops all containers
$ docker stop $(docker ps -a -q)
# Delete all containers
$ docker rm $(docker ps -a -q)
# Delete all images
$ docker rmi $(docker images -q)Orchestration

Some docker-compose useful commands:
$ docker-compose up -d$ docker-compose down$ docker-compose build$ docker-compose logs -f$ docker-compose restartExample 04
Building a simple docker-compose application

Scalability

Docker compose allows you to multiply a container by using the scale command :
$ docker-compose scale nginx=5To allow links to properly function you have to stop and remove your nginx container and relaunch it :
$ docker-compose stop nginx
$ docker-compose rm nginx
$ docker-compose run -d nginx
Thanks
- RPI and RCOS
- Professor Goldschmidt
- Professor Moorthy
- Professor Turner
- Docker
- Red Hat
- Microsoft
Docker Talk
By Joseph Lee
Docker Talk
Docker basics
- 1,280