Image/镜像: 系统镜像 CentOS.iso
Container/容器: 虚拟机 VM
Docker Hub: 镜像中心 GitHub
查看 container ID / Get the ID of the container by using the docker ps command.
停止 container / Use the docker stop command to stop the container.
1 2 docker stop <the-container-id>
删除 container,-f
强删 / Once the container has stopped, you can remove it by using the docker rm command.
1 docker rm <the-container-id>
CentOS 8 新用户
root
帐号添加新用户
1 2 adduser iosdevlog visudo
添加 iosdevlog
那一行
1 2 3 root ALL=(ALL) ALL iosdevlog ALL=(ALL) ALL
切换到 iosdevlog
1 2 su - iosdevlog echo $USER
安装 Docker
Get Started with Docker
设置仓库
1 2 3 sudo yum install -y yum-utils \ device-mapper-persistent-data \ lvm2
1 2 3 sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
安装 Docker Engine-Community
1 sudo yum install docker-ce docker-ce-cli containerd.io --nobest
启动 Docker
1 sudo systemctl start docker
通过运行 hello-world 映像来验证是否正确安装了 Docker Engine-Community
1 sudo docker run hello-world
非 root 用户运行
1 2 3 4 5 6 sudo cat /etc/group | grep docker sudo gpasswd -a $USER docker newgrp docker sudo systemctl restart docker docker version
1 docker run -d -p 80:80 docker/getting-started
You'll notice a few flags being used. Here's some more info on them:
-d
- run the container in detached mode (in the background)
-p 80:80
- map port 80 of the host to port 80 in the container
docker/getting-started
- the image to use
查看 container
remove container
1 docker rm -f <the-container-id>
dev 开发
Dockerfile
1 2 3 4 5 FROM node:12 -alpineWORKDIR /app COPY . . RUN yarn install --production CMD ["node" , "/app/src/index.js" ]
创建 image
-t tag
1 docker build -t getting-started .
运行刚才创建的 getting-started
1 docker run -dp 3000:3000 getting-started
1 2 - <p className="text-center">No items yet! Add one above!</p> + <p className="text-center">You have no todo items yet! Add one above!</p>
1 2 3 docker login -u iosdevlog docker tag getting-started iosdevlog/getting-started docker push iosdevlog/getting-started
1 docker run -dp 3000:3000 iosdevlog/getting-started
打开 3000 按钮
持久化 Persisting our Todo Data¶
1 2 docker volume create todo-db docker run -dp 3000:3000 -v todo-db:/etc/todos iosdevlog/getting-started
数据保存位置
1 2 3 4 5 6 7 8 9 10 11 12 docker volume inspect todo-db [ { "CreatedAt" : "2020-03-27T12:28:25Z" , "Driver" : "local" , "Labels" : {}, "Mountpoint" : "/var/lib/docker/volumes/todo-db/_data" , "Name" : "todo-db" , "Options" : {}, "Scope" : "local" } ]
绑定挂载 Using Bind Mounts
Host Location
Docker chooses
You control
Mount Example (using -v)
my-volume:/usr/local/data
/path/to/data:/usr/local/data
Populates new volume with container contents
Yes
No
Supports Volume Drivers
Yes
No
1 2 3 4 docker run -dp 3000:3000 \ -w /app -v $PWD :/app \ node:12-alpine \ sh -c "yarn install && yarn run dev"
查看 logs
1 2 3 4 5 6 7 8 docker logs -f <container-id> $ nodemon src/index.js [nodemon] 1.19.2 [nodemon] to restart at any time, enter `rs` [nodemon] watching dir(s): *.* [nodemon] starting `node src/index.js` Using sqlite database at /etc/todos/todo.db Listening on port 3000
src/static/js/app.js
1 2 - {submitting ? 'Adding...' : 'Add Item'} + {submitting ? 'Adding...' : 'Add'}
Using bind mounts is very common for local development setups.
在本地开发设置中,使用绑定挂载很常见。
开发完成后就可以创建自己的 image
。
1 docker build -t getting-started .
多个容器 Multi-Container Apps
Create the network.
1 docker network create todo-app
Start a MySQL container and attach it the network.
1 2 3 4 5 6 docker run -d \ --network todo-app --network-alias mysql \ -v todo-mysql-data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=secret \ -e MYSQL_DATABASE=todos \ mysql:5.7
connect to the database
1 2 docker exec -it <mysql-container-id> mysql -p Enter password: secret
1 2 3 4 5 6 7 8 9 10 11 mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | todos | +--------------------+ 5 rows in set (0.05 sec)
Connecting to MySQL
1 2 3 4 5 6 7 8 9 10 docker run -it --network todo-app nicolaka/netshoot Status: Downloaded newer image for nicolaka/netshoot:latest dP dP dP 88 88 88 88d888b. .d8888b. d8888P .d8888b. 88d888b. .d8888b. .d8888b. d8888P 88' `88 88ooood8 88 Y8ooooo. 88' `88 88' `88 88' `88 88 88 88 88. ... 88 88 88 88 88. .88 88. .88 88 dP dP `88888P' dP `88888P' dP dP `88888P' `88888P' dP Welcome to Netshoot! (github.com/nicolaka/netshoot)
dig
output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; <<>> DiG 9.14 .8 <<>> mysql ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61687 ;; flags: qr rd ra; QUERY: 1 , ANSWER: 1 , AUTHORITY: 0 , ADDITIONAL: 0 ;; QUESTION SECTION: ;mysql. IN A ;; ANSWER SECTION: mysql. 600 IN A 172.18 .0 .2 ;; Query time: 7 msec ;; SERVER: 127.0 .0 .11 #53(127.0.0.11) ;; WHEN : Fri Mar 27 16 :00 :31 UTC 2020 ;; MSG SIZE rcvd: 44
MYSQL_HOST - the hostname for the running MySQL server
MYSQL_USER - the username to use for the connection
MYSQL_PASSWORD - the password to use for the connection
MYSQL_DB - the database to use once connected
1 2 3 4 5 6 7 8 9 docker run -dp 3000:3000 \ -w /app -v $PWD :/app \ --network todo-app \ -e MYSQL_HOST=mysql \ -e MYSQL_USER=root \ -e MYSQL_PASSWORD=secret \ -e MYSQL_DB=todos \ node:12-alpine \ sh -c "yarn install && yarn run dev"
docker logs <container-id>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 yarn install v1.22.0 [1/4] Resolving packages... success Already up-to-date. Done in 0.54s. yarn run v1.22.0 $ nodemon src/index.js [nodemon] 1.19.2 [nodemon] to restart at any time, enter `rs` [nodemon] watching dir(s): *.* [nodemon] starting `node src/index.js` Waiting for mysql:3306. Connected! Connected to mysql db at host mysql Listening on port 3000
docker exec -ti <mysql-container-id> mysql -p todos
1 2 3 4 5 6 7 8 mysql> select * from todo_items; +--------------------------------------+---------------------------------------+-----------+ | id | name | completed | +--------------------------------------+---------------------------------------+-----------+ | 9b3dc86c-2ec9-4413-8a71-28b3c3515358 | DevOps | 0 | | 9428c285-e5e1-4f50-bf11-ee854cc8554f | Hello, I'm AIDevLog. Welcome to 2020! | 0 | +--------------------------------------+---------------------------------------+-----------+ 2 rows in set (0.00 sec)
docker-compose
https://docs.docker.com/compose/install/
Compose 使用的三个步骤:
使用 Dockerfile 定义应用程序的环境。
使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
最后,执行 docker-compose up 命令来启动并运行整个应用程序。
1 2 3 sudo curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s) -$(uname -m) " -o /usr/local /bin/docker-compose sudo chmod +x /usr/local /bin/docker-compose docker-compose --version
output
docker-compose version 1.25.4, build 8d51620a
Creating our Compose File
1 2 # pwd: app cat docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 version: "3.7" services: app: image: node:12-alpine command: sh -c "yarn install && yarn run dev" ports: - 3000 :3000 working_dir: /app volumes: - ./:/app environment: MYSQL_HOST: mysql MYSQL_USER: root MYSQL_PASSWORD: secret MYSQL_DB: todos
Running our Application Stack
1 docker rm -f <container-id>
docker-compose up
output
Creating network "app_default" with the default driver
Creating volume "app_todo-mysql-data" with default driver
Creating app_mysql_1 ... done
Creating app_app_1 ... done
log
output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 Attaching to app_mysql_1, app_app_1 app_1 | yarn install v1.22.0 app_1 | [1/4] Resolving packages... ... app_1 | Waiting for mysql:3306............... app_1 | Connected! app_1 | Connected to mysql db at host mysql app_1 | Listening on port 3000 mysql_1 | 2020-03-27 16:37:47+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.29-1debian10 started. ... mysql_1 | 2020-03-27T16:38:06.309134Z 0 [Note] Event Scheduler: Loaded 0 events mysql_1 | 2020-03-27T16:38:06.309309Z 0 [Note] mysqld: ready for connections. mysql_1 | Version: '5.7.29' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL) mysql_1 | 2020-03-27T16:38:06.365195Z 2 [Note] Got an error reading communication packets
Tearing it All Down
Image Building Best Practices
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 $ docker image history getting-started IMAGE CREATED CREATED BY SIZE COMMENT 7e58c32dc1b5 5 hours ago /bin/sh -c ebe4a0dcca7e 5 hours ago /bin/sh -c yarn install --production 83.2MB 3fd0eef12d70 5 hours ago /bin/sh -c c164b9c205a1 5 hours ago /bin/sh -c f77abbe89ac1 3 days ago /bin/sh -c <missing> 3 days ago /bin/sh -c <missing> 3 days ago /bin/sh -c <missing> 3 days ago /bin/sh -c apk add --no-cache --virtual .bui… 7.62MB <missing> 3 days ago /bin/sh -c <missing> 3 days ago /bin/sh -c addgroup -g 1000 node && addu… 74.9MB <missing> 3 days ago /bin/sh -c <missing> 3 days ago /bin/sh -c <missing> 3 days ago /bin/sh -c
Layer Caching¶
Update the Dockerfile to copy in the package.json
1 2 3 4 5 6 FROM node:12 -alpineWORKDIR /app COPY package.json yarn.lock ./ RUN yarn install --production COPY . . CMD ["node" , "/app/src/index.js" ]
Build a new image using docker build
1 docker build -t getting-started .
更改 src/static/index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 diff --git a/src/static/index.html b/src/static/index.html index a606bf1..19cfb57 100644 @@ -8,7 +8,7 @@ <link rel="stylesheet" href="css/font-awesome/all.min.css" crossorigin="anonymous" /> <link href="https://fonts.googleapis.com/css?family=Lato&display=swap" rel="stylesheet" /> <link rel="stylesheet" href="css/styles.css" /> - <title>Todo App</title> + <title>AIDevLog Todo App</title> </head> <body> <div id="root"></div>
docker build
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 $ docker build -t getting-started . Sending build context to Docker daemon 65.73MB Step 1/6 : FROM node:12-alpine ---> f77abbe89ac1 Step 2/6 : WORKDIR /app ---> Using cache ---> c164b9c205a1 Step 3/6 : COPY package.json yarn.lock ./ ---> Using cache ---> 77446d8145bc Step 4/6 : RUN yarn install --production ---> Using cache ---> f0323073e6ce Step 5/6 : COPY . . ---> 0e1288f88991 Step 6/6 : CMD ["node" , "/app/src/index.js" ] ---> Running in f3a0bd941311 Removing intermediate container f3a0bd941311 ---> 2abff2421550 Successfully built 2abff2421550 Successfully tagged getting-started:latest
Clean all
1 2 3 4 docker stop `docker ps -a -q` docker rm `docker ps -a -q` docker rmi -f `sudo docker images -q` docker volume rm $(docker volume ls -f dangling=true -q)
Clean image
1 docker images --no-trunc | grep none | awk '{print $3}' | xargs docker rmi -f
Change docker image location
1 2 btrfs subvolume create /mnt/disk/@docker rsync -aqxP /var/lib/docker/* /mnt/disk/@docker
1 sudo vi /etc/docker/daemon.json
1 2 3 4 5 6 7 { "registry-mirrors" :["https://cache-docker.hopebaytech.com" ], "insecure-registries" :["docker:5000" ], "dns" :["172.16.1.254" , "8.8.8.8" ], "graph" : "/mnt/disk/docker" , "storage-driver" : "btrfs" }
重新啟動服務
1 2 3 sudo systemctl stop docker sudo systemctl daemon-reload sudo systemctl start docker
啟動設定檔位置
1 2 3 /etc/docker/daemon.json /etc/default/docker /etc/systemd/system/docker.service.d/docker.conf
Attach a running container
1 2 3 4 5 6 7 8 docker ps -a docker attach [CONTAINER ID] docker exec -i -t arkease-pro-web bash