Docker一小时快速上手(附报错解决方式)

(以下内容全部来自上述课程以及课件)

课件地址:https://docker.easydoc.net/



1. Docker简介和安装

1.1 Docker 是什么

Docker 是一个应用打包、分发、部署的工具

你也可以把它理解为一个轻量的虚拟机,它只虚拟你软件需要的运行环境,多余的一点都不要,

而普通虚拟机则是一个完整而庞大的系统,包含各种不管你要不要的软件。

1.2 跟普通虚拟机的对比

1.3 打包、分发、部署

打包 :就是把你软件运行所需的依赖、第三方库、软件打包到一起,变成一个安装包
分发 :你可以把你打包好的"安装包"上传到一个镜像仓库,其他人可以非常方便的获取和安装
部署:拿着"安装包"就可以一个命令运行起来你的应用,自动模拟出一摸一样的运行环境,不管是在 Windows/Mac/Linux。

1.4 Docker 部署的优势

常规应用开发部署方式:自己在 Windows 上开发、测试 --> 到 Linux 服务器配置运行环境部署。

问题:我机器上跑都没问题,怎么到服务器就各种问题了

用 Docker 开发部署流程:自己在 Windows 上开发、测试 --> 打包为 Docker 镜像(可以理解为软件安装包) --> 各种服务器上只需要一个命令部署好

优点:确保了不同机器上跑都是一致的运行环境,不会出现我机器上跑正常,你机器跑就有问题的情况。

例如 易文档,SVNBucket 的私有化部署就是用 Docker,轻松应对客户的各种服务器。

1.5 Docker 通常用来做什么

  • 应用分发、部署,方便传播给他人安装。特别是开源软件和提供私有部署的应用
  • 快速安装测试/学习软件,用完就丢(类似小程序),不把时间浪费在安装软件上。例如 Redis / MongoDB / ElasticSearch / ELK
  • 多个版本软件共存,不污染系统,例如 Python2、Python3,Redis4.0,Redis5.0
  • Windows 上体验/学习各种 Linux 系统

1.6 重要概念:镜像、容器

镜像 :可以理解为软件安装包,可以方便的进行传播和安装。
容器:软件安装后的状态,每个软件运行环境都是独立的、隔离的,称之为容器。

1.7 安装

桌面版:https://www.docker.com/products/docker-desktop

服务器版:https://docs.docker.com/engine/install/#server

1.8 启动报错解决

docker desktop启动失败解决记录提示Virtual Machine Platform is not enabled. Enable it using the following...

如果上一个链接里的都设置好了还是报错,那就试下一个链接(我是用的下一个搞好的)
Windows电脑 打开 Docker Desktop 提示的"Virtual Machine Platform not enabled"的问题解决

1.8.1 命令行安装 Linux 内核

powershell 复制代码
wsl.exe --install -d Ubuntu

你也可以打开微软商店 Microsoft Store 搜索 Linux 进行安装,选择一个最新版本的 Ubuntu 或者 Debian 都可以

上面命令很可能你安装不了,微软商店你也可能打不开,如果遇到这个问题,参考:
Microsoft Store微软应用商店打不开怎么办?完美解决方案!

1.8.2 设置开机启动 Hypervisor

powershell 复制代码
bcdedit /set hypervisorlaunchtype auto

注意要用管理员权限打开 PowerShell

1.8.3 设置默认使用版本2

powershell 复制代码
wsl.exe --set-default-version 2

1.8.4 查看 WSL 是否安装正确

powershell 复制代码
wsl.exe --list --verbose

应该如下图,可以看到一个 Linux 系统,名字你的不一定跟我的一样,看你安装的是什么版本。

并且 VERSION 是 2

1.8.5 确保 BIOS 已开启虚拟化,下图检查是否已开启好

如果是已禁用,请在开机时按 F2 进入 BIOS 开启一下,不会设置的可以网上搜索下自己主板的设置方法,Intel 和 AMD 的设置可能稍有不同

出现下图错误,点击链接安装最新版本的 WSL2
https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi

1.9 镜像加速源

重置不了的解决方法:【docker】docker desktop换国内源时 apply按钮为灰色or换源失败 解决方法

镜像加速器 镜像加速器地址

Docker 中国官方镜像 https://registry.docker-cn.com

DaoCloud 镜像站 http://f1361db2.m.daocloud.io

Azure 中国镜像 https://dockerhub.azk8s.cn

科大镜像站 https://docker.mirrors.ustc.edu.cn

阿里云 https://ud6340vz.mirror.aliyuncs.com

七牛云 https://reg-mirror.qiniu.com

网易云 https://hub-mirror.c.163.com

腾讯云 https://mirror.ccs.tencentyun.com

powershell 复制代码
"registry-mirrors": ["https://registry.docker-cn.com","https://docker.mirrors.ustc.edu.cn"],

2. Docker 快速安装软件

2.1 直接安装的缺点

  • 安装麻烦,可能有各种依赖,运行报错。例如:WordPress,ElasticSearch,Redis,ELK
  • 可能对 Windows 并不友好,运行有各种兼容问题,软件只支持 Linux 上跑
  • 不方便安装多版本软件,不能共存。
  • 电脑安装了一堆软件,拖慢电脑速度。
  • 不同系统和硬件,安装方式不一样

2.2 Docker 安装的优点

  • 一个命令就可以安装好,快速方便
  • 有大量的镜像,可直接使用
  • 没有系统兼容问题,Linux 专享软件也照样跑
  • 支持软件多版本共存
  • 用完就丢,不拖慢电脑速度
  • 不同系统和硬件,只要安装好 Docker 其他都一样了,一个命令搞定所有
  • 演示 Docker 安装 Redis

2.3 演示 Docker 安装 Redis

Redis 官网:https://redis.io/

官网下载安装教程只有源码安装方式,没有 Windows 版本。想要自己安装 windows 版本需要去找别人编译好的安装包。

Docker 官方镜像仓库查找 Redis :https://hub.docker.com/

一个命令跑起来:

powershell 复制代码
docker run -d -p 6379:6379 --name redis redis:latest

命令参考:https://docs.docker.com/engine/reference/commandline/run/

2.4 安装 Wordpress

在docker文件夹下新建文档:docker-compose.yml,内容如下:

text 复制代码
version: '3.1'

services:

  wordpress:
    image: wordpress
    restart: always
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - wordpress:/var/www/html

  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - db:/var/lib/mysql

volumes:
  wordpress:
  db:




3. 构建自己的Docker镜像

3.1 为自己的 Web 项目构建镜像

下载这个项目

示例项目代码:https://github.com/gzyunke/test-docker

这是一个 Nodejs + Koa2 写的 Web 项目,提供了简单的两个演示页面。

软件依赖:nodejs

项目依赖库:koa、log4js、koa-router

3.2 编写 Dockerfile

项目中直接有,可跳过

text 复制代码
FROM node:11
MAINTAINER easydoc.net

# 复制代码
ADD . /app

# 设置容器启动后的默认运行目录
WORKDIR /app

# 运行命令,安装依赖
# RUN 命令可以有多个,但是可以用 && 连接多个命令来减少层级。
# 例如 RUN npm install && cd /app && mkdir logs
RUN npm install --registry=https://registry.npm.taobao.org

# CMD 指令只能一个,是容器启动后执行的命令,算是程序的入口。
# 如果还需要运行其他命令可以用 && 连接,也可以写成一个shell脚本去执行。
# 例如 CMD cd /app && ./start.sh
CMD node app.js

Dockerfile文档

实用技巧:

如果你写 Dockerfile 时经常遇到一些运行错误,依赖错误等,你可以直接运行一个依赖的底,然后进入终端进行配置环境,成功后再把做过的步骤命令写道 Dockerfile 文件中,这样编写调试会快很多。

例如上面的底是node:11,我们可以运行docker run -it -d node:11 bash,跑起来后进入容器终端配置依赖的软件,然后尝试跑起来自己的软件,最后把所有做过的步骤写入到 Dockerfile 就好了。

掌握好这个技巧,你的 Dockerfile 文件编写起来就非常的得心应手了。

3.3 Build 为镜像(安装包)和运行

项目下的文件夹,直接鼠标右键打开powershell

编译

powershell 复制代码
docker build -t test:v1 .
powershell 复制代码
docker run -p 8080:8080 --name test-hello test:v1

3.4 更多相关命令

  • docker ps 查看当前运行中的容器
  • docker images 查看镜像列表
  • docker rm container-id 删除指定 id 的容器
  • docker stop/start container-id 停止/启动指定 id 的容器
  • docker rmi image-id 删除指定 id 的镜像
  • docker volume ls 查看 volume 列表
  • docker network ls 查看网络列表

4. 目录挂载

4.1 现存问题

  • 使用 Docker 运行后,我们改了项目代码不会立刻生效,需要重新build和run,很是麻烦。
  • 容器里面产生的数据,例如 log 文件,数据库备份文件,容器删除后就丢失了。

4.2 几种挂载方式

  • bind mount 直接把宿主机目录映射到容器内,适合挂代码目录和配置文件。可挂到多个容器上
  • volume 由容器创建和管理,创建在宿主机,所以删除容器不会丢失,官方推荐,更高效,Linux 文件系统,适合存储数据库数据。可挂到多个容器上
  • tmpfs mount 适合存储临时文件,存宿主机内存中。不可多容器共享。
    文档参考:https://docs.docker.com/storage/

4.3 挂载演示

ind mount 方式用绝对路径 -v D:/code:/app

volume 方式,只需要一个名字 -v db-data:/app

示例:

还是在项目文件夹下鼠标右击打开powershell,记得改路径

powershell 复制代码
docker run -p 8080:8080 --name test-hello -v D:/code:/app -d test:v1

注意!

因为挂载后,容器里的代码就会替换为你本机的代码了,如果你代码目录没有node_modules目录,你需要在代码目录执行下npm install --registry=https://registry.npm.taobao.org确保依赖库都已经安装,否则可能会提示"Error: Cannot find module 'koa'"

如果你的电脑没有安装 nodejs,你需要安装一下才能执行上面的命令。

5. 多容器通信

5.1 学习目标

项目往往都不是独立运行的,需要数据库、缓存这些东西配合运作。

这节我们把前面的 Web 项目增加一个 Redis 依赖,多跑一个 Redis 容器,演示如何多容器之间的通信。

5.2 创建虚拟网络

要想多容器之间互通,从 Web 容器访问 Redis 容器,我们只需要把他们放到同个网络中就可以了。

文档参考:https://docs.docker.com/engine/reference/commandline/network/

5.3 演示

创建一个名为test-net的网络:

powershell 复制代码
docker network create test-net

运行 Redis 在 test-net 网络中,别名redis

powershell 复制代码
docker run -d --name redis --network test-net --network-alias redis redis:latest

修改代码中访问redis的地址为网络别名

运行 Web 项目,使用同个网络

powershell 复制代码
docker run -p 8080:8080 --name test -v D:/test:/app --network test-net -d test:v1

查看数据

text 复制代码
http://localhost:8080/redis

容器终端查看数据是否一致

6. Docker-Compose

6.1 现存问题

在上节,我们运行了两个容器:Web 项目 + Redis

如果项目依赖更多的第三方软件,我们需要管理的容器就更加多,每个都要单独配置运行,指定网络。

这节,我们使用 docker-compose 把项目的多个服务集合到一起,一键运行。

6.2 安装 Docker Compose

  • 如果你是安装的桌面版 Docker,不需要额外安装,已经包含了。
  • 如果是没图形界面的服务器版 Docker,你需要单独安装 安装文档
  • 运行docker-compose检查是否安装成功

6.3 编写脚本

ps:还是之前的项目里直接带了这个文档,可跳过。

要把项目依赖的多个服务集合到一起,我们需要编写一个docker-compose.yml文件,描述依赖哪些服务

参考文档:https://docs.docker.com/compose/

text 复制代码
version: "3.7"

services:
  app:
    build: ./
    ports:
      - 80:8080
    volumes:
      - ./:/app
    environment:
      - TZ=Asia/Shanghai
  redis:
    image: redis:5.0.13
    volumes:
      - redis:/data
    environment:
      - TZ=Asia/Shanghai

volumes:
  redis:

6.4 跑起来

在docker-compose.yml 文件所在目录,执行:docker-compose up就可以跑起来了。

命令参考:https://docs.docker.com/compose/reference/up/

6.5 其他命令

在后台运行只需要加一个 -d 参数docker-compose up -d

查看运行状态:docker-compose ps

停止运行:docker-compose stop

重启:docker-compose restart

重启单个服务:docker-compose restart service-name

进入容器命令行:docker-compose exec service-name sh

查看容器运行log:docker-compose logs [service-name]

7. 发布和部署

7.1 镜像仓库介绍

镜像仓库用来存储我们 build 出来的"安装包",Docker 官方提供了一个 镜像库,里面包含了大量镜像,基本各种软件所需依赖都有,要什么直接上去搜索。

我们也可以把自己 build 出来的镜像上传到 docker 提供的镜像库中,方便传播。

当然你也可以搭建自己的私有镜像库,或者使用国内各种大厂提供的镜像托管服务,例如:阿里云、腾讯云

7.2 上传我们的镜像

powershell 复制代码
docker login -u username
  • 新建一个tag,名字必须跟你注册账号一样
powershell 复制代码
docker tag test:v1 username/test:v1
  • 推上去
powershell 复制代码
docker push username/test:v1
  • 部署试下
powershell 复制代码
docker run -dp 8080:8080 username/test:v1

docker-compose 中也可以直接用这个镜像了

powershell 复制代码
version: "3.7"

services:
  app:
#    build: ./
    image: helloguguji/test:v1
    ports:
      - 80:8080
    volumes:
      - ./:/app
    environment:
      - TZ=Asia/Shanghai
  redis:
    image: redis:5.0.13
    volumes:
      - redis:/data
    environment:
      - TZ=Asia/Shanghai

volumes:
  redis:

7.3 阿里云容器托管

docker 官方的镜像托管有时候上传和下载都太慢了,如果你想要更快的速度,可以使用阿里云的免费镜像托管

登录 阿里云

8. 备份和迁移数据

8.1 迁移方式介绍

容器中的数据,如果没有用挂载目录,删除容器后就会丢失数据。

前面我们已经讲解了如何 挂载目录

如果你是用bind mount直接把宿主机的目录挂进去容器,那迁移数据很方便,直接复制目录就好了

如果你是用volume方式挂载的,由于数据是由容器创建和管理的,需要用特殊的方式把数据弄出来。

8.2 备份和导入 Volume 的流程

备份:

  • 运行一个 ubuntu 的容器,挂载需要备份的 volume 到容器,并且挂载宿主机目录到容器里的备份目录。
  • 运行 tar 命令把数据压缩为一个文件
  • 把备份文件复制到需要导入的机器

导入:

  • 运行 ubuntu 容器,挂载容器的 volume,并且挂载宿主机备份文件所在目录到容器里
  • 运行 tar 命令解压备份文件到指定目录

8.3 备份 MongoDB 数据演示

  • 运行一个 mongodb,创建一个名叫mongo-data的 volume 指向容器的 /data 目录
powershell 复制代码
docker run -p 27018:27017 --name mongo -v mongo-data:/data -d mongo:4.4
  • 运行一个 Ubuntu 的容器,挂载mongo容器的所有 volume,映射宿主机的 backup 目录到容器里面的 /backup 目录,然后运行 tar 命令把数据压缩打包
powershell 复制代码
docker run --rm --volumes-from mongo -v d:/backup:/backup ubuntu tar cvf /backup/backup.tar /data/

最后你就可以拿着这个 backup.tar 文件去其他地方导入了。

8.4 恢复 Volume 数据演示

运行一个 ubuntu 容器,挂载 mongo 容器的所有 volumes,然后读取 /backup 目录中的备份文件,解压到 /data/ 目录

powershell 复制代码
docker run --rm --volumes-from mongo -v d:/backup:/backup ubuntu bash -c "cd /data/ && tar xvf /backup/backup.tar --strip 1"