Getting started
Ali Yousuf
Sr. Software Engineer @ 10Pearls
Credits: https://medium.com/@bhagwatimalav
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>