乐趣区

关于前端:手摸手带你-Docker-从入门到实践

在下最近遇到要在服务器上安装 Mysql、Nginx、EasyMock 等工具的场景,这里记录一下我应用 Docker 装置的过程,心愿也能在相似的场景中帮忙到大家~

本文前备常识须要一些 Linux 的一些根本命令,推介先看一下 < 半小时搞会 CentOS 入门必备基础知识 > 这篇文章。

CentOS 版本:7.6

Nginx 版本:1.16.1

Docker 版本:19.03.12

你多学一样本事,就少说一句求人的话

1. 介绍

1.1 呈现的起因

前后端开发到测试到生产的过程中,常常会遇到一个问题,明明我在本地跑没问题,为什么到测试环境或者生产环境就报错了了呢,经常这是因为开发、测试、生产的环境与配置不同导致的。

折腾过环境配置的人都明确其中麻烦,换一台零碎、虚拟机、机器,就又要重来一次,费劲费时。因为环境和配置的起因,各种奇奇怪怪因为环境和配置的 Bug,总是像打地鼠游戏外面的地鼠一样一直冒出来 ????

Docker 对这个问题给出了一个很好的解决方案,通过镜像将除了零碎之外所须要的零碎环境由下而上打包,达到服务跨平台的无缝运作。也就是说,装置的时候,把特定的环境截然不同地搬过去,从而解决「在我的电脑上能跑,在 xx 环境就跑不了」的状况。

另外一个重要的起因,就是轻量,基于容器的虚拟化,Docker 的镜像仅蕴含业务运行所需的 runtime 环境,一个 CentOS/Ubuntu 根底镜像仅 170M,因为轻量一个宿主机能够轻松装置数百个容器。

1.2 是什么

Docker 是基于 Go 语言实现的云开源我的项目,从 2013 年公布到当初始终广受关注。Docker 能够让你像应用集装箱一样疾速的组合成利用,并且能够像运输规范集装箱一样,尽可能的屏蔽代码层面的差别。它将应用程序与该程序的依赖,打包在一个文件外面。运行这个文件,就会生成一个虚构容器。

程序在这个虚构容器里运行,就如同在实在的物理机上运行一样。有了 Docker,就不必放心环境问题。

本文就不比照虚拟机跟 Docker 的区别和优劣了,每个文章都有,说烂了,想理解的话能够百度一下 ????,我这里就不多说了,上面间接看看怎么装置怎么用起来吧。

2. 装置 & 配置

2.1 Mac 下装置

在下间接应用 Homebrew Cask 来装置,Mac 下:

# Homebrew 装置
$ braw cask install docker

即可,装置完输出命令,间接报错!

➜  ~ docker
zsh: command not found: docker  # 报错

遇到这个报错别放心,装置完之后要在利用列表外面双击 Docker 利用,输出明码之后就能够应用这个命令了 ????。

2.2 CentOS 下装置

Docker 要求 CentOS 版本必须在 6.5 及以上才能够装置。

# 装置
$ sudo yum install yum-utils device-mapper-persistent-data lvm2
$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
$ sudo yum install docker-ce

# 开启 Docker
$ sudo systemctl start docker

在 Windows 上能够间接下载安装包来装置,或者 Mac 上不应用 Homebrew 也能够去官网间接下载安装包来装置,百度一下到处都是装置办法,其余的就不必多说。

3. 简略配置并跑起来

3.1 配置镜像减速

在 MacOS 的 Docker 配置 Perferences -> Docker Engine 或者 Windows 的 Settings -> Deamon 中的 JSON 中减少一项 registry-mirrors 如下

配置完之后在命令行中 docker info 就能够查看到咱们配置的镜像减速地址了。

➜  ~ sudo docker info
...
 Registry Mirrors:
  https://reg-mirror.qiniu.com/
  http://hub-mirror.c.163.com/
  https://registry.docker-cn.com/
...

如果你的零碎的 Docker 没有客户端,比方 CentOS 中,能够间接批改 deamon 配置文件:

# 批改 / 创立 docker 的 deamon 配置文件
$ sudo vi /etc/docker/daemon.json

# 批改为如下配置
{
  "experimental": false,
  "debug": true,
  "registry-mirrors": [
    "https://reg-mirror.qiniu.com",
    "http://hub-mirror.c.163.com",
    "https://registry.docker-cn.com"
  ]
}

# 批改完 :wq 重启
$ sudo systemctl restart docker

3.2 Hello World!

而后就能够高兴跑起来咱们第一个 Docker 指令 Hello World 了

Good start!????

4. 镜像 & 容器 & 仓库

镜像和容器的关系就像类和类的实例,一个镜像能够同时跑多个容器,单个容器实例又能够创立新的镜像。如下图:

上面解释一下这个图外面呈现的元素

概念 阐明
Docker 镜像 Images 用于创立 Docker 容器的只读 模板,比方 Ubuntu 16.04 零碎、Nginx 1.16.0 等,是一个非凡的文件系统,包含容器运行时须要的程序、库、资源、参数等,但不蕴含任何动态数据,内容在构建后也不会被扭转,一个镜像能够创立多个容器
Docker 容器 Container 容器是独立运行、互相隔离的一个或一组利用,是镜像创立的运行实例,本质是过程,能够看作为一个 简易版的 Linux 环境 + 运行在其中的应用程序
Docker 客户端 Client 客户端通过命令行或者其余工具应用 Docker SDK (https://docs.docker.com/devel… 与 Docker 的守护过程通信
Docker 主机 Host 一个物理或者虚构的机器用于执行 Docker 守护过程和容器
Docker 仓库 Repository 集中寄存镜像文件的中央,分为私有仓库和公有仓库。
Docker 注册服务器 Registry 是一个集中存储、散发镜像的服务,官网的叫 Docker Hub。一个 Docker Registry 中可蕴含多个仓库,每个仓库能够蕴含多个标签 Tag 的镜像,不同的标签对应不同的版本
Docker Machine Docker Machine 是一个简化 Docker 装置的命令行工具,通过一个简略的命令行即可在相应的平台上装置 Docker,比方 VirtualBox、Digital Ocean、Microsoft Azure

容器的生命周期图示

容器的五个外围状态,也就是图中色块示意的:Created、Running、Paused、Stopped、Deleted:

  1. Created:容器曾经被创立,容器所需的相干资源曾经准备就绪,但容器中的程序还未处于运行状态。
  2. Running:容器正在运行,也就是容器中的利用正在运行。
  3. Paused:容器已暂停,示意容器中的所有程序都处于暂停 (不是进行) 状态。
  4. Stopped:容器处于进行状态,占用的资源和沙盒环境都仍然存在,只是容器中的应用程序均已进行。
  5. Deleted:容器已删除,相干占用的资源及存储在 Docker 中的治理信息也都已开释和移除。

本文次要关注于应用,就不太赘述这些状态的切换等,上面间接上手。

5. 根本应用

5.1 操作命令

# 开启 Docker 开机自启动
$ sudo systemctl enable docker

# 敞开 Docker 开机自启动
$ sudo systemctl disable docker

5.2 镜像命令

# 去下载镜像,先从本地找,没有去镜像,最初没有去 hub,标签不写默认为 lastest
$ docker pull [镜像名]:[标签 Tag]

# 列出本机的所有 image 文件,-a 显示本地所有镜像(包含两头镜像),-q 只显示镜像 ID,--digests 显示镜像的摘要信息
$ docker image ls
$ docker images

# 删除 image 文件, -f 强制删除镜像
$ docker rmi [镜像名][: 标签 Tag]
$ docker rmi [镜像名 1][: 标签 Tag] [镜像名 2][: 标签 Tag]    # 删多个
$ docker rmi $(docker ps -a -q)    # 删全副,前面是子命令

# 查问镜像名称,--no-trunc 显示残缺的镜像形容,--filter=stars=30 列出 star 不少于指定值的镜像,--filter=is-automated=true 列出主动构建类型的镜像
$ docker search [关键字]

# 下载镜像,标签 tag 不写默认为 lastest,也能够本人加比方 :3.2.0
$ docker pull [镜像名][: 标签 Tag]

5.3 容器命令

# 列出本机正在运行的容器,-a 列出本机所有容器包含终止运行的容器,-q 静默模式只显示容器编号,-l 显示最近创立的容器
$ docker container ls     # 等价于上面这个命令
$ docker ps

# 新建并启动容器
$ docker run [option] [容器名] 

# 启动容器
$ docker start [容器 ID]/[容器 Names]

# 重启容器
$ docker restart [容器 ID]/[容器 Names]

# 终止容器运行
$ docker kill [容器 ID]  # 强行终止,相当于向容器外面的主过程收回 SIGKILL 信号,那些正在进行中的操作会全副失落
$ docker kill $(docker ps -a -q) # 强行终止所有容器
$ docker stop [容器 ID]  # 从容终止,相当于向容器外面的主过程收回 SIGTERM 信号,而后过一段时间再收回 SIGKILL 信号
$ docker stop $(docker ps -a -q) # 终止所有容器

# 终止运行的容器文件,仍然会占据硬盘空间,能够应用 docker container rm 命令删除,-f 强制删除能够删除正在运行的容器
$ docker rm [容器 ID]
$ docker rm `docker ps -aq`    # 删除所有曾经进行的容器,因为没进行的 rm 删不了须要加 -f

# 查看容器的输入,- t 退出工夫戳,- f 追随最新日志打印,--tail 数字显示最初多少条,如果 docker run 时,没有应用 -it,就要用这个命令查看输入
$ docker logs [容器 ID]

# 查看容器过程信息
$ docker top [容器 ID]/[容器 Names]
$ docker port [容器 ID]/[容器 Names]

# 退出容器
$ exit           # 容器退出
ctrl + p + q     # 容器退出,快捷键

# 进入容器
$ docker attach [容器 ID]      # 退出容器时会让容器进行,本机的输出间接输到容器中
$ docker exec -it [容器 ID]    # 退出容器时不会让容器进行,在已运行的容器中执行命令,不创立和启动新的容器

# 设置容器在 docker 启动时主动启动
$ docker container update --restart=always [容器名字]

这里要特地说一下 docker runoption,因为最罕用:

  1. --name 为容器指定一个名称;
  2. -d 容器启动后进入后盾,并返回容器 ID,即启动守护式容器;
  3. -P 随机端口映射;
  4. -p 80:8080 将本地 80 端口映射到容器的 8080 端口;
  5. bash 容器启动当前,外部第一个执行的命令。这里启动 bash,保障用户能够应用 Shell;
  6. -i 以交互模式运行容器,通常与 -t 同时应用;
  7. -t 为容器重新分配一个伪输出终端,容器的 Shell 会映射到以后的 Shell,而后在本机窗口输出的命令,就会传入容器,通常与 -i 同时应用;
  8. --rm 在容器终止运行后主动删除容器文件;
  9. --restart=always 设置容器自启动;
  10. -v /xxx:/yyy 映射命令,把本机的 xxx 目录映射到容器中的 yyy 目录,也就是说扭转本机的 xxx 目录下的内容,容器 yyy 目录中的内容也会扭转;

比方我在 CentOS 下跑起来一个 CentOS 的 Docker 容器:

# 下载
$ docker pull centos

# 在下面下载的 centos 镜像根底上,新建一个容器名为 mycentos0901 的 centos 实例,并进入这个容器的 bash
$ docker run -it --name mycentos0901 0d120b6ccaa8

[root@169c9fffeecd /]   # 进入容器,上面输出命令,留神这里 root 前面的一串 ID
$ ls       # 能够看到 centos 的根目录文件列表
$ docker   # bash: docker: command not found 这个容器没有装置 docker

是不是很神奇,咱们能够在一开始的 CentOS 上面执行 docker ps 来查看容器列表:

你会发现下面那个 ID,正是上面列表中跑起来的这个容器的 ID,镜像的 ID 也是咱们后面 pull 下来的 CentOS 镜像 ID,名字也是咱们起的 mycentos0901

如果 docker run 之后报 Conflict. The container name "xxxx" is already in use by container 就间接运行 docker rm $(docker ps -a -q) 删除已进行的容器,或者准确删除 docker rm [containerID] 也能够,就能够了。

5.4 几个常见场景的命令应用

守护式启动容器

应用 centos 当前台模式启动一个容器 docker run -d --name mycentos0903 0d120b6ccaa8,启动之后 docker ps -a 查看,发现容器并不在运行中,这是因为 Docker 的运行机制:Docker 容器后盾运行,必须有一个前台过程

容器运行的命令如果不是那些始终挂起的命令,比方 toptail,运行完结会主动退出。所以为了让容器继续在后盾运行,那么须要将运行的程序以前台过程的模式运行。

比方这里在后盾运行一个命令,这个命令始终在打印 docker run -d centos /bin/sh -c "while true; do echo hello zzyy; sleep 2; done",而后咱们 logs 查看一下:

退出容器后对容器操作

退出容器后能够通过 exec 办法对正在运行的容器进行操作:

在容器中拷贝文件到内部

拷贝文件应用 cp 命令

$ docker cp [容器 ID]/[容器 Names]:[要拷贝的文件目录] [本机目录]   # 容器文件拷贝到本机
$ docker cp [本机目录] [容器 ID]/[容器 Names]:[要拷贝的文件目录]   # 本机文件拷贝到容器

cp 不仅能把容器中的文件 / 文件夹拷贝到本机,也能够把本机中的文件 / 文件夹拷贝到容器。

演示一下,这里先到容器外面创立一个无聊的文件 xixi.txt,而后拷贝到本机:

实用的时候,咱们能够拷贝配置、日志等文件到本地。

6. 装置 MySQL

# 查问镜像
$ docker search mysql

# 下载镜像,实测没配置镜像减速的时候会比较慢,配置了就好一些
$ docker pull mysql

# 查看镜像
$ docker images

# 创立并运行容器
$ docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=888888 -v /Users/sherlocked93/Personal/configs/mysql.d:/etc/mysql/conf.d --name localhost-mysql mysql

略微解释一下下面的参数:

  1. -p 3307:3306 将本机的 3307 端口映射到 mysql 容器的 3306 端口,依据须要自行更改;
  2. -e MYSQL_ROOT_PASSWORD=<string> 设置近程登录的 root 用户明码;
  3. --name <string> 可选,设置容器别名;
  4. -v xxx/mysql.d:/etc/mysql/conf.d 将本地目录下设置文件夹映射到容器的 /etc/mysql/conf.d
  5. -v xxx/logs:/logs 将本机指定目录下的 logs 目录挂载到容器的 /logs
  6. -v xxx/data:/var/lib/mysql 将主机制订目录下的 data 目录挂载到容器的 /var/lib/mysql

运行截图:

而后去 Navicat 中就能够连贯到 MySQL 了。

这也太爽了!真的是几行命令就装好了啊,比之前真是高兴多了 ????

7. 装置 Nginx

Nginx 的装置和其余的相似,如果你还不太理解 Nginx 如何应用,能够参看 <Nginx 从入门到实际,万字详解 > 这篇文章,看完根本就理解如何应用和配置了。

# 查问 / 下载镜像
$ docker search nginx
$ docker pull nginx

而后创立一个长期的容器,目标是把默认配置拷贝到本机,我这里把配置文件放到 /mnt 目录下,次要是三个配置文件夹:

  1. /etc/nginx 搁置 Nginx 配置文件;
  2. /var/log/nginx/ 搁置 Nginx 日志文件;
  3. /usr/share/nginx/html/ 搁置 Nginx 前端动态文件都放在这个文件夹;

别离把这几个目录都拷贝到本机的 /mnt 文件夹下的 nginxnginx_logshtml 文件夹。

刚刚创立的长期容器没用了 docker rm -f [长期容器 ID] 把长期容器干掉,而后 docker run 从新创立 Nginx 容器:

$ docker run -d --name localhost-nginx -p 8082:80 \
-v /mnt/nginx:/etc/nginx \
-v /mnt/nginx_logs:/var/log/nginx \
-v /mnt/html:/usr/share/nginx/html \
--privileged=true nginx

--privileged=true 示意容器外部对挂载的目录领有读写等特权。

其余配置刚刚下面之前曾经讲过,应该不必讲了。

而后在你本人浏览器上就能够拜访了,如果是云服务器,记得凋谢对应端口。

8. 装置 Easy Mock

因为 Easy Mock 依赖 Redis 和 MongoDB,因而本地环境应用 docker-compose 来搭建 Easy Mock 应该算是最佳实际了。

装置 docker-compose

官网文档:https://docs.docker.com/compose/install/

首先你得确定领有 docker 环境,如果你是 Windows / Mac 用户,那么装置客户端,就会自带 docker-compose 了。

因为本次咱们是在云服务器 CentOS7.6 上搭建,所以咱们须要自行装置 docker-compose,运行如下命令,下载以后稳固版本的 docker-compose

$ sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

批改文件权限为可执行文件

$ sudo chmod +x /usr/local/bin/docker-compose

验证是否装置胜利

$ docker-compose version

编写 docker-compose.yml 配置文件

能够参考官网文档给出的部署文档,也能够参考我上面的配置过程。

首先新建文件 docker-compose.yml 并将上面 docker-compose 文件内容复制进入 docker-compose.yml,而后将内容中正文地位替换为本人须要的本地地址

version: '3'

services:
  mongodb:
    image: mongo:3.4.1
    volumes:
      #  /apps/easy-mock/data/db 是数据库文件寄存地址,依据须要批改为本地地址
      - '/apps/easy-mock/data/db:/data/db'
    networks:
      - easy-mock
    restart: always

  redis:
    image: redis:4.0.6
    command: redis-server --appendonly yes
    volumes:
      #  /apps/easy-mock/data/redis 是 redis 数据文件寄存地址,依据须要批改为本地地址
      - '/apps/easy-mock/data/redis:/data'
    networks:
      - easy-mock
    restart: always

  web:
    image: easymock/easymock:1.6.0
    # easy-mock 官网给出的文件,这里是 npm start,这里批改为 npm run dev
    command: /bin/bash -c "npm run dev:server"
    ports:
      - 7300:7300  # 改为你本人冀望的映射
    volumes:
      # 日志地址,依据须要批改为本地地址
      - '/apps/easy-mock/logs:/home/easy-mock/easy-mock/logs'
    networks:
      - easy-mock
    restart: always

networks:
  easy-mock:

启动 Easy Mock

在 docker-compose 文件目录下,运行如下命令:

$ docker-compose up -d

如果遇到 easymock docker 实例报文件权限谬误

Error: EACCES: permission denied....

要在我的项目根目录执行以下命令

$ chmod 777 /yourfile/logs

而后就能够通过浏览器上的 你的域名.com:7300 拜访到 easy-mock 了!

如果你感觉域名前面跟着端口号挺难看的,你能够通过配置 Nginx 的二级域名来拜访你部署的 easy-mock,配置二级域名的办法参见 这篇文章

9. 可视化治理

对于可视化查问工具,这里就简略推介一个 LazyDocker,因为是在终端运行的,而且反对键盘操作和鼠标点击,就挺骚气的,有了这个一些查问语句能够少打几次了。

装置比较简单,运行上面的命令:

$ docker run --rm -it -v \
/var/run/docker.sock:/var/run/docker.sock \
-v ~/.config/lazydocker:/.config/jesseduffield/lazydocker \
lazyteam/lazydocker

能够设置一个终端的 alias

$ alias lzd='docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock -v ~/.config/lazydocker:/.config/jesseduffield/lazydocker lazyteam/lazydocker'

而后你在终端输出 lzd 就能够浏览你的镜像、容器、日志、配置、状态等等内容了。

10. 结语

因为在下目前应用 Docker 的次要场景是 MySQL、Nginx 之类工具的装置,所以本文所介绍的内容也大多属于这个场景。

篇幅起因 Docker 还有一些内容本文没有介绍,但下面的内容已根本满足日常的应用,其余 Docker 的内容能够关注一下在下的后续文章~


网上的帖子大多深浅不一,甚至有些前后矛盾,在下的文章都是学习过程中的总结,如果发现错误,欢送留言指出~

参考文档:

  1. Empowering App Development for Developers | Docker 官方网站
  2. Docker 核心技术(根底篇)
  3. Docker 装置 mysql
  4. Docker 文档
  5. Docker-compose 文档
  6. 应用 docker 运行 easy-mock – 知乎
  7. docker-compose easy-mock – 简书
  8. 应用 docker 运行 easy-mock | CodingDiary
  9. easymock 官网 docker 仓库:easy-mock/easy-mock-docker
  10. 应用 docker 装置 nginx

作者其余高赞文章:

  1. JS 中能够晋升幸福度的小技巧
  2. Vue 应用中的小技巧
  3. Nginx 从入门到实际,万字详解!
  4. 半小时搞会 CentOS 入门必备基础知识
  5. 手摸手 Webpack 多入口配置实际
  6. 前端路由跳转基本原理

PS:自己博客地址 Github – SHERlocked93/blog,也欢送大家关注我的公众号【前端下午茶】,一起加油吧~

退出移动版