(二)Docker 官方教程实践

216 阅读4分钟

之前

因之前的部分已经在其他网站学过类似知识,故从如图所示出开始

Docker官方教程

image.png

Volume

Volumes provide the ability to connect specific filesystem paths of the container back to the host machine. If a directory in the container is mounted, changes in that directory are also seen on the host machine. If we mount that same directory across container restarts, we’d see the same files.

While named volumes and bind mounts (which we’ll talk about in a minute) are the two main types of volumes supported by a default Docker engine installation, there are many volume driver plugins available to support NFS, SFTP, NetApp, and more! This will be especially important once you start running containers on multiple hosts in a clustered environment with Swarm, Kubernetes, etc.

named volumes

  1. 创建named volumesDocker会维护该volumes的物理地址,我们只需要知道它的名字即可使用它

docker volume create todo-db

  1. 在运行的时候加上参数-v volumeName,所做的操作的术语叫mounting

docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started

  1. 之后,删除该container再运行全新的container,发现删除container之前的数据也存在

  2. 查看volumes详细信息

➜  docker volume inspect todo-db
[
    {
        "CreatedAt": "2021-11-25T01:32:03Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/todo-db/_data",
        "Name": "todo-db",
        "Options": {},
        "Scope": "local"
    }
]

Named volumes are great if we simply want to store data, as we don’t have to worry about where the data is stored

bind mounts

之前的named volumes,我们只需要记住名字就可以使用,Docker会自动帮助我们放置,我们无需指定位置

With bind mounts, we control the exact mountpoint on the host. We can use this to persist data, but it’s often used to provide additional data into containers.

bind mounts,我们显示地指定位置,Bind mount会覆盖容器中的文件,而volume mount则不会(如果容器中已有文件,则会将文件同步到主机的目录上)

➜  app git:(master) ✗ ls
Dockerfile   node_modules package.json spec         src          yarn.lock
➜  app git:(master) ✗ pwd
/Users/lizhenglin/Downloads/learn/getting-started/app
➜  app git:(master) ✗ docker run -dp 3000:3000 \
     -w /app -v "$(pwd):/app" \
     node:12-alpine \
     sh -c "yarn install && yarn run dev"
642770e112581fe067b051f63b24951c74cd449ab251c1ae1d56290c5e76a996
➜  app git:(master) ✗ docker logs -f 642770e112581fe067b051f63b24951c74cd449ab251c1ae1d56290c5e76a996
yarn install v1.22.15
[1/4] Resolving packages...
warning Resolution field "ansi-regex@5.0.1" is incompatible with requested version "ansi-regex@^2.0.0"
warning Resolution field "ansi-regex@5.0.1" is incompatible with requested version "ansi-regex@^3.0.0"
success Already up-to-date.
Done in 1.03s.
yarn run v1.22.15
$ nodemon src/index.js
[nodemon] 2.0.13
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node src/index.js`
Using sqlite database at /etc/todos/todo.db
Listening on port 3000

image.png

如果此时我们更改页面中的某些标签的文字,则可以立刻反映到container内部运行的程序中

Recap

At this point, we can persist our database and respond rapidly to the needs and demands of our investors and founders.

Multi container apps

each container should do one thing and do it well.

如果两个容器在同一个网络上,它们可以彼此通信。如果他们不是,他们就不能。

本节目标

To-do AppMySql结合

  • 创建一个网络

  • 让他们在一个网络中运行

  • 彼此通信

步骤

  1. 创建一个网络
docker network create todo-app
  1. 在该网络上创建MySql
➜  app git:(master) ✗ 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
  1. 在上面创建的容器中运行启动MySql的指令
docker exec -it <mysql-container-id> mysql -u root -p

docker exec --help
Run a command in a running container

docker run --help
Run a command in a new container

  1. 该网络下新建container运行To-do App
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"
  • -d:分离模式,运行在后台
  • -p:端口映射,第一个是物理机端口
  • -w:容器中的工作目录
  • -v:挂载哪个Volume
  • --network:运行在哪个网络下
  • -e:设置环境变量
  1. 我们发现,我们对数据的操作已经可以反映在MySql数据库中

Docker Compose

The big advantage of using Compose is you can define your application stack in a file

docker-compose.yml(位于app目录之外): 定义了两个容器,起始就是把之前命令行中的命令用特定语法写出来了

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

  mysql:
    image: mysql:5.7
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: todos

volumes:
  todo-mysql-data:
  • Docker Compose automatically creates a network specifically for the application stack
➜  getting-started git:(master) ✗ docker-compose up -d
Creating network "getting-started_default" with the default driver
Creating getting-started_app_1   ... done
Creating getting-started_mysql_1 ... done

image.png

Image-building

安全扫描

 docker scan getting-started

分层

使用 docker image history getting-started 来查看

Layer caching

Once a layer changes, all downstream layers have to be recreated as well