Docker 快速上手
参考 B 站视频:Docker 1小时快速上手教程,无废话纯干货
参考文档:https://docker.easydoc.net
Docker 简介
Docker 是一个应用打包、分发、部署的工具。
- 打包:就是把软件运行所需的依赖、第三方库、软件打包成一个安装包。
- 分发:把打包好的 “安装包” 上传到一个镜像仓库,其他人可以非常方便的获取和安装。
- 部署:下载 “安装包” 后就可以一个命令运行起应用,自动模拟出一模一样的运行环境,不管是在 Windows / Mac / Linux。
特性 | 普通虚拟机 | Docker |
---|---|---|
跨平台 | 通常只能在桌面级系统运行,例如 Windows/Mac,无法在不带图形界面的服务器上运行 | 支持的系统非常多,各类 windows 和 Linux 都支持 |
性能 | 性能损耗大,内存占用高,因为是把整个完整系统都虚拟出来了 | 性能好,只虚拟软件所需运行环境,最大化减少没用的配置 |
自动化 | 需要手动安装所有东西 | 一个命令就可以自动部署好所需环境 |
稳定性 | 稳定性不高,不同系统差异大 | 稳定性好,不同系统部署方式一样 |
重要概念:
- 镜像:可以理解为软件安装包,可以方便的进行传播和安装。
- 容器:软件安装后的状态,每个软件运行环境都是独立的、隔离的,称之为容器。
Docker 的优势
常规应用开发部署方式:本机开发、测试 --> 到服务器配置运行环境部署。
用 Docker 开发部署流程:本机开发、测试 --> 打包成 Docker 镜像 --> 在服务器上一个命令即可部署。
Docker 的应用场景
-
应用分发、部署,方便传播给他人安装。特别是开源软件和提供私有部署的应用
-
快速安装测试/学习软件,用完就丢(类似小程序),不把时间浪费在安装软件上。
例如 Redis / MongoDB / ElasticSearch / ELK
-
多个版本软件共存,不污染系统,例如 Python2、Python3,Redis4.0,Redis5.0
-
Windows 上体验 / 学习各种 Linux 系统
Dodcker 安装
参考官方文档,或者网上教程。
镜像加速器 | 镜像加速器地址 |
---|---|
Docker 中国官方镜像 | https://registry.docker-cn.com |
DaoCloud 镜像站 | http://f1361db2.m.daocloud.io |
Azure 中国镜像 | https://dockerhub.azk8s.cn |
科大镜像站 | https://docker.mirrors.ustc.edu.cn |
阿里云 | https://<your_code>.mirror.aliyuncs.com |
七牛云 | https://reg-mirror.qiniu.com |
网易云 | https://hub-mirror.c.163.com |
腾讯云 | https://mirror.ccs.tencentyun.com |
Docker 快速安装软件
直接安装的缺点:
- 安装麻烦,可能有各种依赖,运行报错。例如:WordPress,ElasticSearch,Redis,ELK。
- 可能对 Windows 并不友好,运行有各种兼容问题,软件只支持 Linux 上跑。
- 不方便安装多版本软件,不能共存。
- 电脑安装了一堆软件,拖慢电脑速度。
- 不同系统和硬件,安装方式不一样。
Docker 安装的优点:
- 一个命令就可以安装好,快速方便。
- 有大量的镜像,可直接使用。
- 没有系统兼容问题,Linux 专享软件也照样跑。
- 支持软件多版本共存。
- 用完就丢,不拖慢电脑速度。
- 不同系统和硬件,只要安装好 Docker 其他都一样了,一个命令搞定所有。
Docker 安装 Redis
Redis 官网:https://redis.io/
Docker 官方镜像仓库查找 Redis :https://hub.docker.com/
一个命令跑起来:docker run -d -p 6379:6379 --name redis redis:latest
Docker 安装 Wordpress
DockerHub 上给出的 docker-compose 文件,docker-compose.yml
:
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:
运行:docker compose -up
,运行成功
相关命令
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
查看网络列表
制作 Docker 镜像
示例项目代码:https://github.com/gzyunke/test-docker
这是一个 Nodejs + Koa2 写的 Web 项目,提供了简单的两个演示页面。
软件依赖:nodejs
项目依赖库:koa、log4js、koa-router
编写 Dockfile
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
Build 为镜像
docker build -t test:v1 .
运行
运行刚刚 build 好的镜像:
docker run -p 8080:8080 --name test-hello -d test:v1
目录挂载
现存问题:
- 使用 Docker 运行后,修改了项目代码不会立刻生效,需要重新
build
和run
,很麻烦。 - 容器里面产生的数据,例如 log 文件,数据库备份文件,容器删除后就丢失了。
目录挂载可以解决以上问题。
挂载方式
bind mount
直接把宿主机目录映射到容器内,适合挂代码目录和配置文件。可挂到多个容器上。volume
由容器创建和管理,创建在宿主机,所以删除容器不会丢失,Linux 文件系统,适合存储数据库数据。可挂到多个容器上。(官方推荐,更高效)tmpfs mount
适合存储临时文件,存宿主机内存中。不可多容器共享。(比较少用)
挂载示例
挂载是基于 docker run
的,在后面跟上 -v
参数
- bind mount 方式,需要用绝对路径
-v D:/code:/app
- volume 方式,只需要一个名字
-v db-data:/app
示例:
# windows
docker run -p 8080:8080 --name test-hello -v D:/code:/app -d test:v1
# mac
docker run -p 8080:8080 --name test-hello -v /Users/yusael/code/mygit/test-docker-main:/app -d test:v1
多容器通信
项目往往都不是独立运行的,需要数据库、缓存这些东西配合运作。
这节我们把前面的 Web 项目增加一个 Redis 依赖,多跑一个 Redis 容器,演示如何多容器之间的通信。
创建虚拟网络
要想多容器之间互通,从 Web 容器访问 Redis 容器,只需要把他们放到同个网络中即可。
示例
创建一个名为 test-net
的网络:
docker network create test-net
运行 Redis 在 test-net
网络中,别名 redis
:
docker run -d --name redis --network test-net --network-alias redis redis:latest
修改代码中访问 redis
的地址为网络别名:
const redis = require('redis');
let rds = redis.createClient({url: "redis://redis:6379"}); // 使用别名访问
rds.on('connect', ()=> console.log('redis connect ok'))
rds.connect();
运行 Web 项目,使用同个网络 test-net
:
docker run -p 8080:8080 --name test -v /Users/yusael/code/mygit/test-docker-main:/app --network test-net -d test:v1
访问:http://localhost:8080/redis
,也可以从终端进入 redis-cli,查看存储的数据
Docker-Compose
如果项目依赖很多的第三方软件,需要管理的容器就会很多,每个都要单独配置运行,指定网络。
现在,使用 docker-compose 把项目的多个服务集合到一起,一键运行。
安装 Docker Compose
- 桌面版 Docker 不需要额外安装,已经包含。
- 服务器版 Docker 需要单独安装 安装文档。
- 运行
docker compose
检查是否安装成功
编写脚本
要把项目依赖的多个服务集合到一起,需要编写一个 docker-compose.yml
文件,描述依赖哪些服务。
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/Shanghaivolumes: redis:
运行脚本
在 docker-compose.yml
文件所在目录,执行 docker-compose up
就可以跑起来了。
常用命令
在后台运行只需要加一个 -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]
发布和部署
镜像仓库用来存储 build 出来的 “安装包”
Docker 官方提供了一个 镜像库,里面包含了大量镜像,基本各种软件所需依赖都有,要什么直接上去搜索。
上传镜像
前往 Docker Hub,注册一个账号,按以下步骤操作:
- 创建一个镜像库
- 命令行登录账号:(
yusael
是我的账号名)
docker login -u yusael
- 新建一个 tag,名字以账号名开头:
docker tag test:v1 yusael/test:v1
- 推到镜像仓库:
docker upsh yusael/test:v1
push 成功,仓库地址:https://hub.docker.com/r/yusael/test-docker
推到镜像仓库以后,任何人都可以使用这个镜像:
docker run -d -p 8080:8080 --name test-push yusael/test:v1
Docker Compose 中也可以直接使用这个镜像:
version: "3.7"services: app:# build: ./ image: yusael/test:v1 ports: - 80:8080 volumes: - ./:/app environment: - TZ=Asia/Shanghai redis: image: redis:5.0.13 volumes: - redis:/data environment: - TZ=Asia/Shanghaivolumes: redis:
备份和迁移数据
容器中的数据,如果没有用挂载目录,删除容器后就会丢失数据。
- 如果用 bind mount 直接把宿主机的目录挂进去容器,迁移数据很方便,直接复制目录即可。
- 如果用 volume 挂载的,由于数据是由容器创建和管理的,需要用特殊的方式把数据弄出来。
备份和导入 Volume 的流程
备份:
- 运行一个 ubuntu 的容器,挂载需要备份的 volume 到容器,并且挂载宿主机目录到容器里的备份目录。
- 运行 tar 命令把数据压缩为一个文件
- 把备份文件复制到需要导入的机器
导入:
- 运行 ubuntu 容器,挂载容器的 volume,并且挂载宿主机备份文件所在目录到容器里
- 运行 tar 命令解压备份文件到指定目录
具体演示略。。。网上查阅相关资料。