关于docker:docker-使用入门

7次阅读

共计 5926 个字符,预计需要花费 15 分钟才能阅读完成。

docker 应用入门

在公司应用微服务之后,因为各个服务之间有依赖关系,调试本人服务的时候每次都须要编译运行其余服务,原来应用一台开发机作为开发环境的形式就很麻烦,所以思考用 docker 部署一套能够复用的开发环境。首先理解下 docker 的根本应用。

装置

点击链接下载 docker-desktop,而后傻瓜式装置。

装置好之后能够在命令行执行 docker --version 命令,查看 docker 是否失常运行。

教程

官网必定有教程的,所以能够去官网找一下,我这边看的是 docker/getting-started 的教程。docker/getting-started 自身就是一个 dockerrepo。上面说一下怎么看这个教程。

在装置好 docker 之后,在命令行运行 docker run -d -p 80:80 docker/getting-started 命令,而后就启动了一个容器。

而后本地浏览器拜访 http://localhost/tutorial/ 能够看到教程。英文的,然而很好了解,有点英语根底都能够看懂。本篇教程也是依照这个教程来的,记录下不便当前本人用。

接下来只讲应用,不讲原理。

应用

创立第一个本人的 APP

教程提供了一个 Node.js 的利用让咱们间接应用,点击下载 Node.js APP,本地的连贯,上述步骤没做下载不下来。

将下载的 zip 文件解压,用编辑器关上,这边我用的是 vscode

创立该 APP 镜像

  1. 在下载的 APP 的跟目录下创立一个名称为 Dockerfile 的文件,文件内容如下:
FROM node:12-alpine
RUN apk add --no-cache python g++ make
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]
  1. APP 跟目录下运行如下命令:
docker build -t getting-started .

-t 是给镜像取个名字,名字是 getting-started。最初的 . 代表的是运行的是当前目录下的 Dockerfile 文件。

启动一个 APP 容器

  1. 应用 docker run 命令启动一个容器,启动的时候要指定应用方才构建的镜像。命令如下:
docker run -dp 3000:3000 getting-started
  1. 启动之后,在本地浏览器输出 http://localhost:3000。能够看到一个 todo list 利用。
  2. 你能够在利用中应用一下。如果是本人的利用根本就能够应用了。

你当初能够看下下载的 docker-desktop 面板,外面有两个容器,一个是用来看教程的,一个是新创建的本人的 APP

更新 APP 容器

启动容器后,容器内的利用代码必定不是变化无穷的,加个需要不是很失常的事件嘛,所以须要在更改代码之后,从新构建镜像,用新镜像重新启动容器。

  1. 批改代码,在 src/static/js/app.js 文件下更新第 56 行
-                <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. 从新构建镜像
docker build -t getting-started .
  1. 删除原有容器,不删除原有容器间接启动会因为 3000 端口占用启不起来。能够用命令删除,或者间接在 docker-desktop 面板上间接删除。上面介绍下命令删除。
  • 首先用命令 docker ps 找到所有启动的容器。如下图:
  • 图中第一列就是容器 id,而后还用 docker rm <the-container-id> 命令删除该容器。
  1. 依据新镜像重新启动容器,命令如下。
docker run -dp 3000:3000 getting-started
  1. 从新看下利用 http://localhost:3000。

长久化数据库

docker 中每个容器的文件系统都是独立的,一个容器无法访问到另一个容器的文件。同一个容器,再重启后旧容器中的文件就丢了。所以下面的 todo list APP 再容器更新后之前加的 todo 就没了。那怎么让容器更新后还能拜访到之前的数据呢?

这里引出容器的 volumes 概念。volumes 会将容器内的目录映射到宿主机的目录上,而后每次启动的时候都加载宿主机的目录,文件就不会丢了。

有两种类型的 volumes,一种是 named volumes,另一种是 bind mounts

named volumes

首先讲一下 named volumes :

  1. 应用 docker volume create 命令创立一个 volume。
docker volume create todo-db
  1. 删除曾经存在的 todo list APP 容器。步骤下面曾经说了。
  2. docker run 命令重新启动容器,这次启动要加 -v 参数,命令如下:
docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started

-v 就是指定 volumes 的意思。

  1. 刷新利用 http://localhost:3000,加几条新的 todo
  2. 而后删除 APP 容器,重新启动一个。
  3. 再次刷新利用,确认方才的几条 todo 没有丢。

注:查看 Valumes 信息命令:

docker volume inspect <valumes name>

bind mounts

而后再来说一下 bind mounts,它会将宿主机内的目录与容器内的目录绑定,而后扭转宿主机目录下的内容,容器内的也会扭转,这就能够实现在宿主机改代码,及时同步到容器内。应用流程:

  1. 敞开所有的 getting-started 容器。
  2. 运行以下命令:
docker run -dp 3000:3000 \
    -w /app -v "$(pwd):/app" \
    node:12-alpine \
    sh -c "yarn install && yarn run dev"

如果是 PowerShell,运行如下命令:

docker run -dp 3000:3000 `
    -w /app -v "$(pwd):/app" `
    node:12-alpine `
    sh -c "yarn install && yarn run dev"

命令解释如下:

  • -dp:是参数 -d ,-p 的缩写,-d代表后盾运行,-p 指定端口。
  • -w /app:容器内工作目录,程序运行的目录。
  • -v "$(pwd):/app":这里指定了 volumes,将宿主机的当前目录与容器的 /app 目录绑定。
  • node:12-alpine:应用的镜像
  • sh -c "yarn install && yarn run dev":运行 shell
  1. 用命令 docker logs -f <container-id> 查看日志,如果你看到以下内容代表启动胜利:
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
  1. 尝试着改代码,将 src/static/js/app.js 文件的 109 行 “Add Item” 改成 “Add”:
-                         {submitting ? 'Adding...' : 'Add Item'}
+                         {submitting ? 'Adding...' : 'Add'}
  1. 刷新网页看成果。

创立一个多容器的 APP

todo list APP 之前用的是 SQLite Database 来作为存储的。当初应用个更通用的,比方 MYSQL。当然能够间接把 MYSQLAPP 部署到同一台机器上,然而 docker 不倡议这么做。docker 心愿每个容器内的性能繁多。所以当初的部署计划是两个容器,一个部署 MYSQL,一个部署 APP。像这样:

这样两个容器之间须要通过网络连接。这样就引出 network 概念。同一个 network 上的容器能够互相通信。

创立启动 MYSQL 容器

  1. 创立一个 network :
docker network create todo-app
  1. 启动一个 MYSQL 容器,将该容器连贯到上一步创立的 network 下面。
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

如果用的 PowerShell

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

这里用到了 --network-alias,该属性的意思是:其余容器连贯 mysql 填写 host 的时候,间接填 --network-alias 的值 mysql 就行。相当于域名。

  1. 确认 mysql 容器是否失常运行
docker exec -it <mysql-container-id> mysql -p

连贯到 mysql 之后运行:

mysql> SHOW DATABASES;

能够看到 todos 库:

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| todos              |
+--------------------+
5 rows in set (0.00 sec)

启动 APP 容器连贯到 MYSQL

  1. 敞开所有的 getting-started 容器。
  2. 重新启动容器
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"

如果是 PowerShell:

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"

新增了 --network todo-app 来连贯到 todo-app 网络,确保跟 mysql 一个网络就好。

同时新增了几个 -e 参数,代表指定要连贯的 mysql 的环境变量。

  1. 查看日志 docker logs <container-id>,会看到如下内容:
# Previous log messages omitted
$ 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`
Connected to mysql db at host mysql
Listening on port 3000
  1. 关上网页 http://localhost:3000 新加几个 todo
  2. 运行命令连贯到 mysql :
docker exec -it <mysql-container-id> mysql -p todos

运行如下命令查看是否有新增的数据:

mysql> select * from todo_items;

Docker compose

启动了 todo listmysql 之后,在 docker-desktop 面板上看到的是两个容器,然而两个容器是有分割的,会同时启动和敞开,那该怎么让两个容器联动起来呢?

这里就要用到 docker compose,通过一个 YAML 文件,能够同时启动和敞开两个容器,或者叫一组相干容器。

  1. 在我的项目的根目录下创立一个 docker-compose.yml 文件,跟最开始的 Dockerfile 同一目录下。
  2. 文件内容如下:
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:
  1. 删除方才创立的 getting-startedmysql 两个容器。
  2. 在我的项目根目录下运行如下命令启动这组容器:
docker-compose up -d

运行的时候回看到如下输入:

Creating network "app_default" with the default driver
Creating volume "app_todo-mysql-data" with default driver
Creating app_app_1   ... done
Creating app_mysql_1 ... done

留神到 volumenetwork 都创立了,即便 network 没有指定。这是因为默认状况下,compose 会创立一个公共的 network

  1. 接着能够用 docker-compose logs -f 命令看下日志。
  2. 刷新下浏览器,当初能够失常应用了。而后能够察看下 docker-desktop 面板,能够看到两个容器放在了一起。
  3. 而后能够通过 docker-compose down 命令或者间接在面板上点击敞开这组容器。

总结

因为要搭建环境,将 docker 官网的内容整顿简化,记录出

正文完
 0