By: Seve, Joey, and Richi
Rensselaer Center for Open Source
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
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 ?
Docker is based on LXC (Linux Containers) which allows
it to isolate containers from each other.
LXC use mainly two Linux Kernel features:
Docker can be split in multiple different parts :
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.
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
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_1Why
What
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
$ 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 psRun cowsay in an ubuntu container!
Many applications put containers on docker hub.
Docker hub usually gives simple instructions for running the image, independent of the host operating system!
Running a docker application from existing 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/image1You can now create as many container from this image as you want :
$ docker run -dit ekkinox/image1-d : Daemonized
-it : Allocate TTY
Image name
This approach is nice but as developers
we highly prefer working in files than terminals, right ?
That's why Docker uses Dockerfiles.
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 .To create a container from our new image :
$ docker run -dit ekkinox/image2-d : Daemonized
-it : Allocate TTY
Image name
Build a 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" ]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 !
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 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).
docker logindocker build -t seveibar/exampleApp .$ docker push seveibar/exampleApp$ docker pull seveibar/exampleAppDocker 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.
So, running all containers by hand can
be really messy and complicated... saw it.
"Damned, i'll never use this Docker stuff..."
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 !Solutions ?
No. Bad idea.
The solution is Docker compose
Docker compose works by putting a single yaml file in your project.
Using Compose is basically a three-step process.
version: '2'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}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)Some docker-compose useful commands:
$ docker-compose up -d$ docker-compose down$ docker-compose build$ docker-compose logs -f$ docker-compose restartBuilding a simple docker-compose application
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