Docker

Getting started

VM vs Container

Let's get our hands dirty with Docker

https://github.com/alyyousuf7/docker-workshop

Lesson #1

Install Docker

Lesson #1

# Install Docker
$ curl -sSL get.docker.com | bash

Lesson #1

# Install Docker
$ curl -sSL get.docker.com | bash

# Check if it's working
$ sudo docker info

Lesson #1

# Install Docker
$ curl -sSL get.docker.com | bash

# Check if it's working
$ sudo docker info

# Give it some access
$ usermod -aG docker $(whoami)

# Re-login

Lesson #1

# Install Docker
$ curl -sSL get.docker.com | bash

# Check if it's working
$ sudo docker info

# Give it some access
$ usermod -aG docker $(whoami)

# Re-login

# Check again without sudo
$ docker info

Lesson #2

Spin up a container

Lesson #2

# docker container run <image name>

Lesson #2

$ docker container run hello-world:latest

Lesson #2

$ docker container run hello-world:latest

# or

$ docker container run hello-world

Lesson #2

$ docker container run hello-world:latest

# or

$ docker container run hello-world

$ docker container ls

Lesson #2

$ docker container run hello-world:latest

# or

$ docker container run hello-world

$ docker container ls

# Nothing showed up? Try...
$ docker container ls --all

Lesson #2

$ docker container run hello-world:latest

# or

$ docker container run hello-world

$ docker container ls

# Nothing showed up? Try...
$ docker container ls --all

# Remove the container
$ docker container rm <container id>

Lesson #2

# docker container run <image name>
$ docker run <image name>

Lesson #2

# docker container run <image name>
$ docker run <image name>

# Similarly,

# docker container ls
$ docker ps

# docker container rm <container id>
$ docker rm <container id>

Lesson #3

Registry

Lesson #3

# Search an image from registry
$ docker search nginx

Lesson #3

# Search an image from registry
$ docker search nginx

# Pull the image
$ docker pull <image name>

Lesson #3

# Search an image from registry
$ docker search nginx

# Pull the image
$ docker pull nginx

Lesson #3

# Search an image from registry
$ docker search nginx

# Pull the image
$ docker pull nginx

# List all the images
$ docker image ls

Lesson #3

# Search an image from registry
$ docker search nginx

# Pull the image
$ docker pull nginx

# List all the images
$ docker image ls

# Remove an image
$ docker rmi <image name>

Lesson #3

# Search an image from registry
$ docker search nginx

# Pull the image
$ docker pull nginx

# List all the images
$ docker image ls

# Remove an image
$ docker rmi hello-world

Private Registry

Lesson #3

Lesson #3

# Add our private registry certificate

$ sudo mkdir -p /etc/docker/certs.d/10.0.0.156

$ sudo curl -sSL https://goo.gl/4fGu2M \
    -o /etc/docker/certs.d/10.0.0.156/ca.crt

Lesson #4

Images

Lesson #4

# [image name]:[tag]

Lesson #4

# [image name]:[tag]

# hello-world : latest

Lesson #4

# [image name]:[tag]

# hello-world : latest

# myserver    : v1.0

Lesson #4

# [image name]:[tag]

# hello-world : latest

# myserver    : v1.0
# myserver    : latest -- Same image, different tags

Lesson #4

# [image name]:[tag]

# hello-world : latest

# myserver    : v1.0
# myserver    : latest -- Same image, different tags

# myserver    : v2.0

Lesson #4

# [image name]:[tag]

# hello-world : latest

# myserver    : v1.0


# myserver    : v2.0
# myserver    : latest -- Same image, different tags

Lesson #4

# [image name]:[tag]

# hello-world : latest

# [repo name]/[image name]:[tag]

Lesson #4

# [image name]:[tag]

# hello-world : latest

# [repo name]/[image name]:[tag]

# alyyousuf7 / sshtron    : latest

Lesson #4

# [image name]:[tag]

# hello-world : latest

# [repo name]/[image name]:[tag]

# alyyousuf7 / sshtron    : latest

# [registry addr]/[repo name]/[image name]:tag

Lesson #4

# [image name]:[tag]

# hello-world : latest

# [repo name]/[image name]:[tag]

# alyyousuf7 / sshtron    : latest

# [registry addr]/[repo name]/[image name]:tag

# 10.0.0.156     / alyyousuf7/ sshtron    : latest

Lesson #4

# [image name]:[tag]

# hello-world : latest

# [repo name]/[image name]:[tag]

# alyyousuf7 / sshtron    : latest

# [registry addr]/[repo name]/[image name]:tag

# 10.0.0.156     / alyyousuf7/ sshtron    : latest

# 10.0.0.156     / nginx  : latest

Lesson #4

# Tag an image with another name
# docker tag <old image name> <new image name>

Lesson #4

# Tag an image with another name
$ docker tag sshtron:latest alyyousuf7/sshtron:latest

Lesson #4

# Tag an image with another name
$ docker tag sshtron:latest alyyousuf7/sshtron:latest

# Push an image
$ docker push alyyousuf7/sshtron:latest

Lesson #4

# Tag an image with another name
$ docker tag sshtron:latest alyyousuf7/sshtron:latest

# Push an image
$ docker push alyyousuf7/sshtron:latest

# But you'll need to login first
$ docker login

Lesson #5

Working inside a container

Lesson #5

# Run ubuntu container
$ docker run --interactive --tty ubuntu:latest

Lesson #5

# Run ubuntu container
$ docker run -it ubuntu:latest

# Did you see something like this?
root@<container id>:/#

Lesson #5

# Run ubuntu container
$ docker run -it ubuntu:latest

# Run `ls`
root@<container id>:/# ls

Lesson #5

# Run ubuntu container
$ docker run -it ubuntu:latest

# Run `curl`
root@<container id>:/# curl https://aliyousuf.com

Lesson #5

# Run ubuntu container
$ docker run -it ubuntu:latest

# Run `curl` - got error? why?
root@<container id>:/# curl https://aliyousuf.com

Lesson #5

# Run ubuntu container
$ docker run -it ubuntu:latest

# Install `curl`
root@<container id>:/# apt-get update && \
                       apt-get install curl -y

Lesson #5

# Run ubuntu container
$ docker run -it ubuntu:latest

# Run `curl`
root@<container id>:/# curl https://aliyousuf.com

Lesson #5

# Run ubuntu container
$ docker run -it ubuntu:latest

# Prepare directory
root@<container id>:/# mkdir mydata && cd mydata

Lesson #5

# Run ubuntu container
$ docker run -it ubuntu:latest

# Prepare directory
root@<container id>:/# mkdir mydata && cd mydata

# Run `curl` and save it in a file
root@<cid>/mydata# curl https://aliyousuf.com > index.html

Lesson #5

# Run ubuntu container
$ docker run -it ubuntu:latest

# Prepare directory
root@<container id>:/# mkdir mydata && cd mydata

# Run `curl` and save it in a file
root@<cid>/mydata# curl https://aliyousuf.com > index.html

# `cat` index.html
root@<cid>/mydata# cat index.html

Lesson #5

# Run ubuntu container
$ docker run -it ubuntu:latest

# Prepare directory
root@<container id>:/# mkdir mydata && cd mydata

# Run `curl` and save it in a file
root@<cid>/mydata# curl https://aliyousuf.com > index.html

# `cat` index.html
root@<cid>/mydata# cat index.html

# exit
root@<cid>/mydata# exit

Lesson #5

# Check the container
$ docker ps -a

Lesson #5

# Check the container
$ docker ps -a

# Restart the container
$ docker start <container id>

Lesson #5

# Check the container
$ docker ps -a

# Restart the container
$ docker start <container id>

# Run `/bin/bash`
$ docker exec -it <container id> /bin/bash

Lesson #5

# Check the container
$ docker ps -a

# Restart the container
$ docker start <container id>

# Run `/bin/bash`
$ docker exec -it <container id> /bin/bash

# Check the file again
root@<container id>:/# cat mydata/index.html
root@<container id>:/# exit

Lesson #5

# Check the container
$ docker ps -a

# Restart the container
$ docker start <container id>

# Run `/bin/bash`
$ docker exec -it <container id> /bin/bash

# Check the file again
root@<container id>:/# cat mydata/index.html
root@<container id>:/# exit

# Check container list
$ docker ps

Lesson #5

# Copy file to container
# docker cp <src path> <container id>:<dst path>

Lesson #5

# Copy file to container
# docker cp <src path> <container id>:<dst path>

# Prepare data
$ echo "hello world" > myfile.txt

Lesson #5

# Copy file to container
# docker cp <src path> <container id>:<dst path>

# Prepare data
$ echo "hello world" > myfile.txt

# Now copy it
$ docker cp myfile.txt <container id>:/mydata/hello-world.txt

Lesson #5

# Copy file to container
# docker cp <src path> <container id>:<dst path>

# Prepare data
$ echo "hello world" > myfile.txt

# Now copy it
$ docker cp myfile.txt <container id>:/mydata/hello-world.txt

# Let's check it
$ docker exec -it <container id> cat /mydata/hello-world.txt

Lesson #5

# Copy file to container
# docker cp <src path> <container id>:<dst path>

# Prepare data
$ echo "hello world" > myfile.txt

# Now copy it
$ docker cp myfile.txt <container id>:/mydata/hello-world.txt

# Let's check it
$ docker exec -it <container id> cat /mydata/hello-world.txt

# Stop the container
$ docker stop <container id>

Lesson #5

# Save the changes
$ docker commit <container id> my-first-image:latest

Lesson #5

# Save the changes
$ docker commit <container id> my-first-image:latest

# Check the image list
$ docker image ls

Lesson #5

# Save the changes
$ docker commit <container id> my-first-image:latest

# Check the image list
$ docker image ls

# Run it once with image
$ docker run -it my-first-image:latest

Lesson #5

# Save the changes
$ docker commit <container id> my-first-image:latest

# Check the image list
$ docker image ls

# Run it once with image
$ docker run -it my-first-image:latest

# Check file and exit it again
root@<container id>:/# cat /mydata/hello-world.txt
root@<container id>:/# exit

Lesson #6

Dockerfile

Lesson #6

# Setup
$ mkdir ~/docker-demo && cd ~/docker-demo
$ echo "hello-world" > myfile.txt
$ touch Dockerfile

Lesson #6

# Write Dockerfile
$ vim Dockerfile

Lesson #6

FROM ubuntu:latest

Lesson #6

FROM ubuntu:latest

RUN apt-get update && apt-get install curl -y

Lesson #6

FROM ubuntu:latest

RUN apt-get update && apt-get install curl -y

WORKDIR /mydata

Lesson #6

FROM ubuntu:latest

RUN apt-get update && apt-get install curl -y

WORKDIR /mydata

RUN curl https://aliyousuf.com > index.html

Lesson #6

FROM ubuntu:latest

RUN apt-get update && apt-get install curl -y

WORKDIR /mydata

RUN curl https://aliyousuf.com > index.html

ADD myfile.txt hello.txt

Lesson #6

# Build the image
# docker build --file <path to Dockerfile> \
#              --tag <new image name> <context path>

Lesson #6

# Build the image
# docker build --file <path to Dockerfile> \
#              --tag <new image name> <context path>

$ docker build -f Dockerfile -t my-second-image:latest .

Lesson #6

# Build the image
# docker build --file <path to Dockerfile> \
#              --tag <new image name> <context path>

$ docker build -f Dockerfile -t my-second-image:latest .

# Check the image list
$ docker image ls

Lesson #7

Mounting port and volume

Lesson #7

# Pull nginx image
$ docker pull nginx:latest

Lesson #7

# Pull nginx image
$ docker pull nginx:latest

# Run a container + publish a port
# docker run -it \
#   --publish <host port>:<container port> nginx:latest

Lesson #7

# Pull nginx image
$ docker pull nginx:latest

# Run a container + publish a port
$ docker run -it \
    --publish 8080:80 nginx:latest

Lesson #7

# Pull nginx image
$ docker pull nginx:latest

# Run a container + publish a port
$ docker run -it \
    --publish 8080:80 nginx:latest

# Try what it serves from host machine
$ curl http://localhost:8080

Lesson #7

# Pull nginx image
$ docker pull nginx:latest

# Run a container in background + publish a port
$ docker run -it --detach \
    --publish 8080:80 nginx:latest

Lesson #7

# Pull nginx image
$ docker pull nginx:latest

# Run a container in background + publish a port
$ docker run -it --detach \
    --publish 8080:80 nginx:latest

# Try what it serves
$ curl http://localhost:8080

Lesson #7

# Pull nginx image
$ docker pull nginx:latest

# Prepare some directory and data to mount
$ mkdir ~/my-website && cd ~/my-website
$ echo "My name is <b>Ali Yousuf</b>" > index.html

Lesson #7

# Pull nginx image
$ docker pull nginx:latest

# Prepare some directory and data to mount
$ mkdir ~/my-website && cd ~/my-website
$ echo "My name is <b>Ali Yousuf</b>" > index.html

# Run container + attach a volume + publish a port
# docker run -dit -p 8080:80                     \
#   --volume <src path>:<dst path>               \
#   nginx:latest

Lesson #7

# Pull nginx image
$ docker pull nginx:latest

# Prepare some directory and data to mount
$ mkdir ~/my-website && cd ~/my-website
$ echo "My name is <b>Ali Yousuf</b>" > index.html

# Run container + attach a volume + publish a port
$ docker run -dit -p 8080:80                     \
    --volume ~/my-website:/usr/share/nginx/html/ \
    nginx:latest

Lesson #7

# Pull nginx image
$ docker pull nginx:latest

# Prepare some directory and data to mount
$ mkdir ~/my-website && cd ~/my-website
$ echo "My name is <b>Ali Yousuf</b>" > index.html

# Run container + attach a volume + publish a port
$ docker run -dit -p 8080:80                     \
    --volume ~/my-website:/usr/share/nginx/html/ \
    nginx:latest

# Change the file at run time
$ echo " and I'm learning how to use Docker" >> index.html

Lesson #7

# Pull nginx image
$ docker pull nginx:latest

# Prepare some directory and data to mount
$ mkdir ~/my-website && cd ~/my-website
$ echo "My name is <b>Ali Yousuf</b>" > index.html

# Run container + attach a volume + publish a port
$ docker run -dit -p 8080:80                     \
    --volume ~/my-website:/usr/share/nginx/html/ \
    nginx:latest

# Change the file at run time
$ echo " and I'm learning how to use Docker" >> index.html
$ curl http://localhost:8080

Lesson #8

Use containers to compile tools

Lesson #8

# Clone the repo and see the Dockerfile
$ git clone https://github.com/alyyousuf7/twenty48.git
$ cd twenty48 && cat Dockerfile

# Get inside the container
$ make shell

Lesson #8

# Clone the repo and see the Dockerfile
$ git clone https://github.com/alyyousuf7/twenty48.git
$ cd twenty48 && cat Dockerfile

# Get inside the container
$ make shell

# Build the Golang binary
root@<container-id>:/twenty48# make binary

Lesson #8

# Clone the repo and see the Dockerfile
$ git clone https://github.com/alyyousuf7/twenty48.git
$ cd twenty48 && cat Dockerfile

# Get inside the container
$ make shell

# Build the Golang binary
root@<container-id>:/twenty48# make binary

# Check the bin/ directory
root@<container-id>:/twenty48# ls bin/

Lesson #8

# Clone the repo and see the Dockerfile
$ git clone https://github.com/alyyousuf7/twenty48.git
$ cd twenty48 && cat Dockerfile

# Get inside the container
$ make shell

# Build the Golang binary
root@<container-id>:/twenty48# make binary

# Check the bin/ directory
root@<container-id>:/twenty48# ls bin/
root@<container-id>:/twenty48# exit

# Play 2048
$ ./bin/twenty48

Lesson #8

# make shell
$ docker build -t twenty48:latest .
$ docker run -v $(pwd)/bin:/long-path/bin twenty48:latest

Lesson #8

# make shell
$ docker build -t twenty48:latest .
$ docker run -v $(pwd)/bin:/long-path/bin twenty48:latest

# make binary
root@<container id>:path/# go build -o bin/twenty48 ./...

Lesson #8

# make shell
$ docker build -t twenty48:latest .
$ docker run -v $(pwd)/bin:/long-path/bin twenty48:latest

# make binary
root@<container id>:path/# go build -o bin/twenty48 ./...

# host/twenty48/bin == container/twenty48/bin

Lesson #9

Networks

Lesson #9

# Create some networks
$ for net in $(echo frontend backend db); do \
    docker network create $net;              \
  done

Lesson #9

# Create some networks
$ for net in $(echo frontend backend db); do \
    docker network create $net;              \
  done

# List networks
$ docker network ls

Lesson #9

# Create some networks
$ for net in $(echo frontend backend db); do \
    docker network create $net;              \
  done

# List networks
$ docker network ls

# Connect containers to relevant networks
# docker network connect <network name> <container id>

Lesson #9

# Create some networks
$ for net in $(echo frontend backend db); do \
    docker network create $net;              \
  done

# List networks
$ docker network ls

# Connect containers to relevant networks
$ docker network connect frontend reactjs-app

Lesson #9

# Create some networks
$ for net in $(echo frontend backend db); do \
    docker network create $net;              \
  done

# List networks
$ docker network ls

# Connect containers to relevant networks
$ docker network connect frontend reactjs-app
$ docker network connect frontend nodejs-api
$ docker network connect backend  nodejs-api
$ docker network connect backend  worker
$ docker network connect db       worker
$ docker network connect db       postgres

Lesson #10

Docker Compose

Lesson #10

# Install Docker Compose from
# https://docs.docker.com/compose/install/#install-compose

Lesson #10

# Install Docker Compose from
# https://docs.docker.com/compose/install/#install-compose

Lesson #10

# Install Docker Compose from
# https://docs.docker.com/compose/install/#install-compose

# Pull https://github.com/dockersamples/example-voting-app

Lesson #10

# Install Docker Compose from
# https://docs.docker.com/compose/install/#install-compose

# Pull https://github.com/dockersamples/example-voting-app

Lesson #10

Lesson #10

# Install Docker Compose from
# https://docs.docker.com/compose/install/#install-compose

# Pull https://github.com/dockersamples/example-voting-app

# Open docker-compose.yml

Lesson #10

version: "3"

services:
  [container 1 name]:
    [fixed image or build method]
    [ports to expose]
    [volumes to mount]
    [networks to mount]

  ...

volumes:
  [volume 1]:
    [mount mode and options]

  ...

networks:
  [network 1]:
    [mount mode and options]

  ...

...

Lesson #10

# Install Docker Compose from
# https://docs.docker.com/compose/install/#install-compose

# Pull https://github.com/dockersamples/example-voting-app

# Spin up the complete app

Lesson #10

# Install Docker Compose from
# https://docs.docker.com/compose/install/#install-compose

# Pull https://github.com/dockersamples/example-voting-app

# Spin up the complete app
$ docker-compose up

Lesson #10

# Install Docker Compose from
# https://docs.docker.com/compose/install/#install-compose

# Pull https://github.com/dockersamples/example-voting-app

# Spin up the complete app
$ docker-compose up

# Inspect containers for more details
$ docker inspect <container id>

Thank You

Made with Slides.com