Docker 1 - Get Docker Started

By Sheldon L Published at 2020-02-29 Updated at 2020-02-29


Installation, test & -it

sudo docker version
sudo docker info

sudo docker container run -it -p 800:80 nginx
# - stdInput & promptTerminal (or iteractive mode, run forend), `ctlC` and `pkill` can affect nginx in the container forend
# - PORT publishing
# 800(outer port, as you like):80(container nginx port)
# nginx will be pulled if it is not installed in the container, search apps in https://hub.docker.com
# docker nginx documentation https://hub.docker.com/_/nginx

# http://localhost:800/


Common Usages & -a, -d, -p, -f

# containers
sudo docker container ls      # runing containers
sudo docker ps                # same as above
sudo docker container ls -a   # all containers inclueding the exited ones
sudo docker ps -a             # same as above

sudo docker stop <name|id[:3]>[list]  # name or first 3 digits of container's id or list many of them
sudo docker stop $(sudo docker ps -aq)

sudo docker start <name|id[:3]>[list]

sudo docker run <name> <command>   # run command when start a container

sudo docker container rm <name|id[:3]>[list]  
sudo docker rm $(sudo docker ps -aq)
sudo docker container rm <name|id[:3]>[list] -f
# images
sudo docker images           # list app images
sudo docker image rmi <name|id[:3]>[list]
sudo docker pull nginx       # see the documentation in https://hub.docker.com
# How to go into docker's bash
sudo docker start mynginx
sudo docker container exec -it mynginx bash
> exit
sudo docker container run -d -p 8080:80 --name mynginx nginx
sudo docker container run -d -p 8081:80 --name myapache httpd
# --detatched (run background independently or it will be attatched by default)
# can run both nginx and httpd at the same time use the same 80 port of the containers

sudo docker attatch <name|id[:3]>[list] # attatch a dettatched container

sudo docker ps

sudo docker container stop myapache
sudo docker container rm myapache    # stop, then remove # force remove
sudo docker image rmi httpd

Environment variables & -e

sudo docker container run -d -p 3306:3306 --name mymysql --env MYSQL_ROOT_PASSWORD=123456 mysql
docker inspect <container>

Dockerfile image, Volume mapping & -v

cd $hub/mysite_test
mkdir dockers
cd dockers
mkdir nginx-web-html
cd nginx-web-html

sudo docker container run -d -p 8080:80 -v $(pwd):/usr/share/nginx/html --name nginx-web nginx
# `-v $(PATH):$(PATH in container)`: bind local PATH to the container PATH

# now can edit html content in this folder
touch index.html
vim index.html    # what ever

# create Dockerfile to set
touch Dockerfile
vim Dockerfile    # see bellow
FROM nginx:latest
WORKDIR /usr/share/nginx/html
COPY . .     # copy all to all
sudo docker image build -t <username_of_docker_account>/nginx-web .
# -t: tag
# dot means in $(pwd)
# run 1 step a layer, if build crupt, can modify Dockerfile and will build from the break point next time.

sudo docker images   # check
sudo docker rm nginx-web -f    # remove old

sudo docker container run -d -p 8080:80 <username_of_docker_account>/nginx-web
docker login

cd <projectfolder>

sudo docker push  <username_of_docker_account>/<projectname>

Inspect Container

docker inspect <container>  # will return in json

Container Logs

docker logs <container>

Network

docker container run <container> --network=[bridge|none|host] # bridge is the default
docker network ls
docker instpect <container> # check network
docker network create --driver bridge --subnet 128.18.0.0/16 <costum-isolated-network>

Storage

docker volume create <data_volume>
# |_ /var/lib/docker
#   |_ /volumes
#     |_ /<data_volume>

docker run -v <data_volume>:/var/lib/mysql mysql
# mount to the container

docker run -v <data_volume_new>:/var/lib/mysql mysql
# new volume will be automatically created
docker run -v /path/to/data/:/var/lib/mysql mysql

# OR
docker run \
--mount type=bind,source=/path/to/data,target=/var/lib/mysql mysql

Docker Compose

Example

python (voting) -> redis (inMemoryDb) <- .net (worker) -> postgresql (db) <- node.js (results)

frontend                                  backend                              frontend
docker run -d --name=redis redis
docker run -d --name=db postgresql

docker run -d --name=vote -p 5000:80 --link redis:redis voting-app
docker run -d --name=result -p 5001:80 --link db:db result-app

docker run -d --name=worker --link db:db --link redis:redis worker
redis:
  image: redis           # already in dockerhub

postgresql:
  image: postgresql:9.4  # already in dockerhub

voting-app:                # buildp
  build: ./vote          # code folder with Dockerfile
  ports:
    - 5000:80
  links:
    - redis

result-app:                # build
  build: ./result
  ports:
    - 5001:80
  links:
    -db # db:db = db

worker:                    # build
  build: ./worker
  links:
    - redis
    - db
doker-compose up
# above is version 1

# version 2 will create network auto
# services can talk to each other, link to the same name the are looking for
# no need to spicify links

# version 2 introduce `depends on` and  `networks`
version: 2

services:
  redis:
    image: redis           # already in dockerhub
    networks:              # add backend services to backend network
      - backend
  postgresql:
    image: postgresql:9.4  # already in dockerhub
    networks:
      - backend

  voting-app:                # buildp
    build: ./vote          # code folder with Dockerfile
    ports:
      - 5000:80
    depends_on:
      - redis
    networks:              # add front services to both frontend and backend network
      - frontend
      - backend

  result-app:                # build
    build: ./result
    ports:
      - 5001:80
    depends_on:
      - postgresql
    networks:
      - frontend
      - backend

  worker:                    # build
    build: ./worker
    depends_on:
      - postgresql
      - redis
    networks:
      - back-end
networks:
  front-end
  back-end

# version 3 similar to 2
# support dockers on
# docker stacks
version: 3

services:
  #...

Docker Registry

image: nginx/nginx  # docker.io_(defult)/user_account_name/image_repo
# more
image: gcr.io/kubernetes-e2e-test-images/dnsutils  # may be private, asuar, gcp, aws may provide you account when registered

docker login private-registry.io
docker run private-registry.io/apps/internal-app

# always login before pulling or pushing private

# if no private accout, how to push in your own orgnization?
# example:
docker run -d -p 5000:5000 --name registry registry:2
docker image tag my-image localhost:5000/my-image  # url
# localhost
docker push localhost:5000/my-image
docker pull localhost:5000/my-image
# OR LAN
docker push 192.168.x.x:5000/my-image
docker pull 192.168.x.x:5000/my-image

Docker Engine

Docer CLI (may on remote Laptop) <-> REST API (Docer engine) <-> Docker Deamon (Docer engine)
# CLI to remote engin
docker -H=10.23.0.1:2375 run nginx

Name Space PID

Linux Sys
  |_ PID 1
    |_ PID 2    map to container
    |_ PID 3    _________________
    |_ PID 4    |               |
    |_ PID 5  --+-> PID 1       |
    |_ PID 6  --+->  |_PID 2    |
                |   ...         |
                |_______________|

Control Groups

docker run --cpu=.5 ubuntu  # no more than 50% of the host
docker run --memory=100m ubuntu