Docker

Main Page

    • https://www.docker.com/

    • Docker is the world’s leading software container platform. Developers use Docker to eliminate “works on my machine” problems when collaborating on code with co-workers. Operators use Docker to run and manage apps side-by-side in isolated containers to get better compute density. Enterprises use Docker to build agile software delivery pipelines to ship new features faster, more securely and with confidence for both Linux and Windows Server apps.

Doc., Download and Install Page

  • https://docs.docker.com/

Command and bash ::

    • Remove all None Images : sudo docker rmi -f $(sudo docker images -f "dangling=true" -q);

    • Go to Bash : docker run -i -t ubuntu /bin/bash

  • Check Version : docker version

Reference :

(CHINESE) http://wiki.jikexueyuan.com/list/docker

(CHINESE) http://www.runoob.com/docker/docker-tutorial.html

https://docs.docker.com/

(CHINESE) http://dockone.io/article/101

(CHINESE) https://www.w3cschool.cn/docker/docker-tutorial.html

Reference : https://blog.longwin.com.tw/2017/01/docker-learn-initial-command-cheat-sheet-2017/

Docker 可以在機器上,快速產生出各種不同的 VM 環境,而且對機器沒有什麼負載(loading)。

    • ex: 於 Ubuntu Linux 跑 Debian、CentOS 或 於 Debian 7 跑 Debian 8... 等等...

Docker 初學筆記 - 基本指令操作教學(常用指令)

Docker 可以產生 VM (OS Level),所以指令非常的多,在這邊只把初學者常用到的命令列出來,進階的就用到再去官方查詢即可(或者 docker help 都可以看到)。

在指令操作前,需要先有下述幾個名詞的基本觀念:

    • Image 映像檔:Docker 都是唯讀的 Image,Image 執行(instance) 產生 Container

    • Container 容器:Container 可以 run、start、stop、rm,每個 Container 都是獨立分離的。Image 是唯讀的,所以 Container 啟動時,會在上面建立一層可以寫入的層級。(最多寫入127層)

    • Registry 倉庫 (Public / Private) https://hub.docker.com/ # Image 預設都由此處抓取

上述名詞於系統的流程

    1. 由 Registry 抓取 Image 到 Local 端,可以把 Image 想成是作業系統的 IMG、ISO 檔

    2. 啟動此作業系統(Image) 會產生 Container (實體化)

        • 註1:一個 Image 可以產生、執行出多組 Container (同一個 VM 可以多重執行,執行當下會產生 Container,Container 上面會有自己寫入的 aufs 層級)

        • 註2:可以想像 Container 就是 Image 上面的一層 Layer

Docker 常用命令

官方出版的 Docker

Docker commands 官方文件:

常用命令:run、exec、ps、rm、rmi、images

Docker 版本資訊

    • docker version

    • docker info

Docker 搜尋 Image

    • docker search image-name

    • docker search debian

    • docker search nginx

Docker 抓取 Image

    • docker pull ubuntu # 抓所有 ubuntu image 回來, tag 可於後面附加上去

    • docker pull ubuntu:16.04 # 只抓取 Ubuntu 16.04 的 Image

    • docker pull debian:jessie

    • docker pull debian:latest # library/debian - Docker Hub,latest 只會抓最新版 (Debain Docker 官方版)

    • docker pull ubuntu:latest # library/ubuntu - Docker Hub

Docker 列出 Local Images

    • docker images # 列出 images

Docker 啟動 Image 產生 Container (start)

    • docker start hash-id # docker ps -a 看到想要讓他執行,可以直接 start

Docker 暫停 Image 產生 Container (stop)

    • docker stop hash-id # 此 hash-id 由 docker ps 可找到

Docker 執行 Image 產生 Container (run)

    • docker run

        • docker run -d debian:jessie # 會自動執行 docker pull + 啟動並進入背景執行

        • docker run -it debian:jessie bash # 會自動執行 docker pull,跑起來自動執行 bash 程式進入此 Container

        • docker run --rm debian:jessie bash # Container 執行停止(docker stop container-name)後,會自動移除

        • docker run -d -p 80:80 nginx # 把裡面的 80 port 導到外面的 80 port (host Port:container Port)

        • docker run ubuntu:trusty /bin/echo "hello world" # 說明如下

            • image name:ubuntu:trusty

            • execute:/bin/echo

            • argument:"hello world"

        • docker run ubuntu:latest /bin/sh -c "while true; do echo hello, world; sleep 1; done;"

        • docker run -d ubuntu:latest /bin/sh -c "while true; do echo hello, world; sleep 1; done;" # -d 會進入背景執行

        • docker run -d ubuntu:latest /bin/sh -c "apt install apt-utils; done;" # 安裝套件

        • docker run -it --name test ubuntu # 指定名稱

        • docker run -d -p 3306:3306 -e MYSQLROOTPASSWORD=1234 mysql # 指定 port 與 密碼

            • mysql -u root -p1234 -h 172.17.42.1 # 於外部可直接連進 Docker 內部 MySQL

        • docker run -d -p 3307:3306 -e MYSQLROOTPASSWORD=1234 mysql # 本機 3307 對應到 docker 3306

            • mysql -u root -p1234 -P 3307 -h 172.17.42.1

        • docker run -d --name web -m 512m -p 8080:80 nginx # 限制記憶體大小

        • docker run -d --expose=80 --name nginx-web nginx

        • docker run -d -v $(pwd)/project:/var/www --rm --name container-name -p 80:80 container-name # 綜合上述,啟動執行,docker stop 順便移除

Docker 執行 Container 某命令 (exec)

  • docker exec hash-id /sbin/ifconfig

    • docker exec -t hash-id /bin/bash

    • docker exec -it debian:latest /bin/bash

    • docker exec -it debian:latest /sbin/ifconfig

Docker 掛載目錄進入 Container (run -v)

    • docker -v 掛載點

    • docker run -d --name xxx -p 80:80 -p 3306:3306 -v /mnt/xxx:/mnt debian:jessie

        • /mnt/xxx:目前 Local 環境目錄

        • /mnt:Container 目錄

Docker 產生、操作 Volumes (volume)

    • docker volume create --name myvol # 建立 local volume

    • docker run -v myvol:/data # Container start 就 Mount 此 volume

    • docker volume rm myvol # 砍掉 volume

    • docker volume ls # 列出 volumes

Docker 列出 Container (ps)

    • docker ps # 還在執行中的 Container,可以看到詳細 hash id

    • docker ps -a # 執行、停止的 Container 都列出來

    • docker ps -l -q # 只列出 hash id,常用,可考慮加入 .bashrc:alias dl='docker ps -l -q'

Docker 進入(Attach) Container

    • docker attach hash-id # -d 模式後,attach hash id 會回到此 conatiner console,"ctrl-p, ctrl-q detach".

    • 註:attach 進去此 Container,若沒有用 detach 而是 exit 離開,此 Container 也會跟著離開結束

Docker 列出 Logs

    • docker logs hash-id

    • docker logs -f hash-id

Docker 刪除 Container (rm)

    • docker rm hash-id # CONTAINER ID

    • docker rm -f hash-id # 強置刪除

    • docker rm $(docker ps --filter status=exited -q) # 砍掉所有停止的 Container

    • docker rm $(docker ps -a -q) # 移除所有 Containers

    • docker ps --filter "status=exited" | grep 'weeks ago' | awk '{print $1}' | xargs --no-run-if-empty docker rm # 一次砍掉狀態是 exited,而且是幾週前的 container

    • docker ps -a | awk '{print $1}' | xargs --no-run-if-empty docker rm # ps -a 砍掉全部 stop 的 container

Docker 刪除 Images (rmi)

    • docker rmi image-id # docker images 可以看到 image-id

    • docker rmi -f image-id # 強置刪除

    • docker rmi $(docker images -q) # 移除所有 docker images

    • docker rmi docker images -qa # 移除所有 docker images

    • docker rmi $(docker images -f "dangling=true" -q) # 砍所有沒有 tag 的 image

Docker 查看 Container 詳細資訊 (inspect)

    • docker inspect mysql

    • docker inspect mysql | grep IPAddre # 想抓取 ip

Dockfile 產生 Image(build)、由 Container 產生 Image (commit)

    • docker build -t myimage . # build image,需要 Dockerfile

    • docker build -t user-name/v1.0.0 .

    • docker commit hash-id myimage # 由 Container 產生 Image

    • docker commit -m 'commit-message' hash-id tsung/myimage:tag-name # 用此 hash-id 現在的內容包成 Image (tsung/myimage),同時設定 Tag tag-name

Docker 將 Container 重新命名 (rename)

    • docker rename hash-id new-name

Docker 從 Container 複製檔案出來 (cp)

    • docker cp hash-id:/etc/group /tmp # Container-id:path local-storage

Docker 儲存當下環境的 Image 到 tar - (save)

    • docker save image-name > image-name.tar # 存 Image

    • docker save -o debian.tar debian:jessie

    • docker save -o ubuntu.tar ubuntu:lucid ubuntu:saucy

    • 註:save 儲存當下 Image 變動部份,與原始 Image 是分開的 (存映像檔,包成 Image)

Docker 由 tar 還原回 Image (load)

    • docker load < image-name.tar # save tar

    • 註:Load an image from a tar archive or STDIN

Docker 儲存當下環境的 Image(含原始 Image) 到 tar (export)

    • docker export image-name > image-name.tar

    • docker export --output="image-name.tar" image-name

    • 註:只要有此 tar 檔,到其它機器都可以直接立刻使用 (把現在的環境打包,當下的 container)

Docker 由 tar 還原回 Container (import)

    • docker import < image-name.tar # 直接建立一個新的 Container

    • cat image-name.tar | docker import - local/image-name # image-name.tar = export tar

    • 註:Import the contents from a tarball to create a filesystem image

Docker 查看 Container Ports (port)

    • docker port hash-id # 80/tcp -> 0.0.0.0:80

Docker 查看 Container Process (top)

    • docker top hash-id # 秀出 Container 正在執行的 process

Docker 砍掉正在跑得 Container (kill)

    • docker kill hash-id

    • docker kill $(docker ps -q) # 停止所有 Containers

執行 Docker 不需 sudo 的設定方式

    1. vim /etc/group # 將帳號加入 docker group 就不會每次都需要 sudo

    2. docker:x:999:username

    3. 或 sudo gpasswd -a ${USER} docker # 將自己此帳號加入 docker group

    4. sudo service docker restart

**************************************************************************************************************************************************************

Install Docker into Fedora : https://computingforgeeks.com/how-to-install-docker-on-fedora-29-fedora-28/

Step 1: Update your system

We always start our installations by updating and upgrading OS packages. On Fedora, this can be easily done by running the command:

sudo dnf -y update

It is recommended to reboot your system after an upgrade

sudo reboot

Step 2: Add the Docker repository to Fedora 29/28

After upgrading system packages and rebooting the server, proceed to add Fedora repository to your system

sudo dnf -y install dnf-plugins-core

Add the repository:

cat >/etc/yum.repos.d/docker-ce.repo<<EOF [docker-ce-stable] name=Docker CE Stable baseurl=https://download.docker.com/linux/fedora/28/x86_64/stable enabled=1 gpgcheck=1 gpgkey=https://download.docker.com/linux/fedora/gpg EOF

This command will set up the stable Docker repository.

Step 3: Install the latest Docker Engine on Fedora 29 / 28

Now that you have your repository ready, install the latest stable release of Docker on your machine by running:

sudo dnf -y install docker-ce

Docker will be installed but not started. To start the docker service, run:

sudo systemctl start docker

Enable it to start on boot:

sudo systemctl enable docker

The docker group is created, but no users are added to the group. Add your user to this group to run docker commands without sudo.

sudo usermod -aG docker $(whoami)

IF ERROR : sss_cache missing : # sss_cache -E

You can verify the version of Docker installed by running:

$ docker version Client: Version: 18.06.1-ce API version: 1.38 Go version: go1.10.3 Git commit: e68fc7a Built: Tue Aug 21 17:25:02 2018 OS/Arch: linux/amd64 Experimental: false Server: Engine: Version: 18.06.1-ce API version: 1.38 (minimum version 1.12) Go version: go1.10.3 Git commit: e68fc7a Built: Tue Aug 21 17:26:30 2018 OS/Arch: linux/amd64 Experimental: false

Step 4: Pull Test docker image

The last step is to test your installation by downloading a test docker container.

$ docker pull alpine Using default tag: latest latest: Pulling from library/alpine 4fe2ade4980c: Pull complete Digest: sha256:621c2f39f8133acb8e64023a94dbdf0d5ca81896102b9e57c0dc184cadaf5528 Status: Downloaded newer image for alpine:latest

Verify that Docker CE is installed correctly by running the alpine image.

$ docker run -it --rm alpine /bin/sh / # apk update fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/APKINDEX.tar.gz fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/x86_64/APKINDEX.tar.gz v3.8.1-58-gb11ab10a64 [http://dl-cdn.alpinelinux.org/alpine/v3.8/main] v3.8.1-42-ge6bc061baf [http://dl-cdn.alpinelinux.org/alpine/v3.8/community] OK: 9546 distinct packages available / # exit

That’s all. You now have Docker running on your Fedora 29 / Fedora 28. Please check our guide on managing Docker containers through a web interface:

Install Docker UI manager – Portainer

What Portainer can do

    • Manage Docker images – pull, delete, Build

    • Quickly deploy applications from app templates

    • Manage containers – start, stop, kill, restart, pause, resume, remove, create

    • Manage networks – add, remove, edit

    • Manage Volumes – add, remove, manage permissions

    • Check docker engine events

    • Add custom docker registry and add authentication for docker hub

    • Create endpoints

    • Add users to manage Docker

    • Manage Docker swarm

    • Create custom container templates

Deploy Docker Web UI Administrator – Portainer

General Command

## List Docker CLI commands docker docker container --help## Display Docker version and info docker --version docker version docker info ## Execute Docker image docker run hello-world ## List Docker images docker image ls## List Docker containers (running, all, all in quiet mode) docker container ls docker container ls --all docker container ls -aq

PART 2 Containers : https://docs.docker.com/get-started/part2/

FileName : Dockerfile

# Use an official Python runtime as a parent imageFROM python:2.7-slim# Set the working directory to /appWORKDIR /app# Copy the current directory contents into the container at /appCOPY . /app# Install any needed packages specified in requirements.txtRUN pip install --trusted-host pypi.python.org -r requirements.txt # Make port 80 available to the world outside this containerEXPOSE 80# Define environment variableENV NAME World# Run app.py when the container launchesCMD ["python", "app.py"]

FileName : requirements.txt

Flask Redis

FileName : app.py

from flask import Flaskfrom redis import Redis, RedisErrorimport osimport socket# Connect to Redisredis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)app = Flask(__name__)@app.route("/")def hello(): try: visits = redis.incr("counter") except RedisError: visits = "<i>cannot connect to Redis, counter disabled</i>" html = "<h3>Hello {name}!</h3>" \ "<b>Hostname:</b> {hostname}<br/>" \ "<b>Visits:</b> {visits}" return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)if __name__ == "__main__": app.run(host='0.0.0.0', port=80)

docker build -t friendlyhello . # Create image using this directory's Dockerfile docker run -p 4000:80 friendlyhello # Run "friendlyname" mapping port 4000 to 80 docker run -d -p 4000:80 friendlyhello # Same thing, but in detached mode docker container ls # List all running containers docker container ls -a # List all containers, even those not running docker container stop <hash> # Gracefully stop the specified container docker container kill <hash> # Force shutdown of the specified container docker container rm <hash> # Remove specified container from this machine docker container rm $(docker container ls -a -q) # Remove all containers docker image ls -a # List all images on this machine docker image rm <image id> # Remove specified image from this machine docker image rm $(docker image ls -a -q) # Remove all images from this machine docker login # Log in this CLI session using your Docker credentials docker tag <image> username/repository:tag # Tag <image> for upload to registry docker push username/repository:tag # Upload tagged image to registry docker run username/repository:tag # Run image from a registry

Part 3 - Services : https://docs.docker.com/get-started/part3/#run-your-new-load-balanced-app

Create docker-compose.yml

version: "3"services: web: # replace username/repo:tag with your name and image details image: username/repo:tag deploy: replicas: 5 resources: limits: cpus: "0.1" memory: 50M restart_policy: condition: on-failure ports: - "80:80" networks: - webnetnetworks: webnet:

This docker-compose.yml file tells Docker to do the following:

    • Pull the image we uploaded in step 2 from the registry.

    • Run 5 instances of that image as a service called web, limiting each one to use, at most, 10% of the CPU (across all cores), and 50MB of RAM.

    • Immediately restart containers if one fails.

    • Map port 4000 on the host to web’s port 80.

    • Instruct web’s containers to share port 80 via a load-balanced network called webnet. (Internally, the containers themselves publish to web’s port 80 at an ephemeral port.)

    • Define the webnet network with the default settings (which is a load-balanced overlay network).

docker swarm init # Once Only

docker stack ls # List stacks or apps docker stack deploy -c <composefile> <appname> # Run the specified Compose file

e.g. docker stack deploy -c docker-compose.yml getstartedlab

docker service ls # List running services associated with an app docker service ps <service> # List tasks associated with an app

e.g. docker service ps getstartedlab_web

docker inspect <task or container> # Inspect task or container docker container ls -q # List container IDs e.g. Test on Terminal : curl -4 http://localhost:4000 docker stack rm <appname> # Tear down an application docker swarm leave --force # Take down a single node swarm from the manager