一、Docker的简介和安装
-
Docker是什么?
Docker是一款针对程序开发人员和系统管理员来开发、部署、运行应用的一款虚拟化平台。Docker 可以让你像使用集装箱一样快速的组合成应用,并且可以像运输标准集装箱一样,尽可能的屏蔽代码层面的差异。Docker 会尽可能的缩短从代码测试到产品部署的时间。
简而言之,Docker就是一个应用打包、分发、部署的工具, 你可以将它看成轻量的虚拟机,它只虚拟你软件需要的运行环境,多余的一点都不要,而我们常见的普通虚拟机则是一个完整而庞大的系统,包含各种软件。 -
Docker相关重要概念
打包:将你软件运行所需的软件、依赖库、第三方库等打包到一起,变成一个安装包
分发:将你打包好的“安装包”上传到一个镜像仓库,供其他人方便获取和安装
部署:通过命令,运行起来你的应用,自动模拟出一摸一样的运行环境,不管在Mac/Linux/Windows
镜像(Image):可以理解是一个只读的静态模板,类似于我们在装系统的时候用到的.iso文件;从Linux角度,操作系统分为内核和用户空间。内核启动后,会挂载root文件系统为其提供用户空间支持。每开一个就有了一个独立的用户空间。而Docker镜像(Image),就相当于是一个root文件系统
容器(Container):容器类似于镜像的实例化,类似于面向对象程序设计中类和实例之间的关系。镜像可以看作是静态的类,而容器则是在镜像基础上动态创建的运行时实体。容器具有创建、启动、停止、删除、暂停等操作。虽然容器实质上是进程,但与直接在宿主系统上执行的进程不同,容器进程运行于自己独立的命名空间
仓库(Repository):Docker Registry是用于存储和管理Docker镜像的服务。它可以包含多个仓库(Repository),每个仓库可以包含多个标签,每个标签对应一个具体的镜像。通常情况下,一个仓库会包含同一个软件的不同版本的镜像,而标签则用于区分不同版本。通过 <仓库名>:<标签> 的格式,可以指定具体是哪个版本的镜像,如果不给出标签,默认会使用latest作为标签。在使用Docker时,常用的Registry公开服务是官方的Docker Hub。它拥有大量的高质量的官方镜像,是开发者常用的资源之一。其网址为:http://hub.docker.com/。通过访问该网址,用户可以查找、获取各种镜像,以及发布自己的镜像。
具体Docker技术的底层原理,这里就不展开讨论,有兴趣的小伙伴可以查阅相关资料进行阅读。 -
Docker优势
传统的应用开发部署方式通常涉及在Windows上进行开发和测试,然后将应用转移到Linux服务器上配置运行环境进行部署。然而,这种方式常常会引发一系列环境和依赖性问题:尽管在个人电脑上顺利运行,但在服务器上却可能出现各种问题,例如环境配置不一致、依赖项缺失等。
相比之下,采用Docker技术进行开发部署则能够有效解决这些问题:开发人员可以在Windows上进行开发和测试,然后将应用打包为Docker镜像。在部署到不同的服务器时,只需执行一个命令,即可轻松部署应用,而且可以确保在不同机器上运行的是相同的运行环境,避免了因环境差异导致的问题。
这种方式就像安装软件一样简便:传统的安装过程可能需要手动处理各种依赖库,耗费时间且容易出现兼容性问题。而使用Docker技术,只需执行一个命令即可完成安装,快速、方便,并且可以直接使用丰富的镜像资源,支持多个软件版本的共存,极大地提高了开发和部署的效率。 -
Docker安装
桌面版:Docker桌面版下载
服务器版:Docker服务器版下载
作者电脑是Win11,因此下载桌面版的window,直接运行安装包,安装后需要重启电脑。
这里重新启动后,进入docker界面如下,版本为v4.28.0
二、Docker安装软件
Docker安装软件前,可以先提前配置镜像加速源:
Docker镜像源 | 源地址 |
---|---|
Docker 中国官方镜像 | https://registry.docker-cn.com |
科大镜像站 | https://docker.mirrors.ustc.edu.cn |
腾讯云 | https://mirror.ccs.tencentyun.com |
Azure 中国镜像 | https://dockerhub.azk8s.cn |
网易云 | https://hub-mirror.c.163.com |
我们以安装redis为例,看看Docker如何简便快速安装的:
- Docker 官方镜像仓库查找 Redis:https://hub.docker.com/
- 可通过Docker命令进行安装:
docker run -d -p 6379:6379 --name redis redis:latest
Docker命令参考: https://docs.docker.com/reference/cli/docker/container/run/, 参考官方给出Docker相关命令和对应参数。
三、构建自己的Docker镜像
【Web项目制作镜像参考:Docker 快速入门笔记】
示例项目地址:https://github.com/gzyunke/test-docker
软件依赖:nodejs
依赖库:koa、log4js、koa-router
- 编写Dockerfile
【注意】需将Dockerfile文件放到Web项目根目录下
FROM node:11
# 将(当前路径的)项目代码复制到镜像的app目录上
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打包上述依赖库作为镜像
# 根目录下进入Windows PowerShell, 执行下面编译命令
docker build -t test:v1 .
参数:-t 设置镜像名字和版本号
命令参考文档:https://docs.docker.com/engine/reference/commandline/build/
完成编译后,在docker desktop中生成Tag为v1的test镜像。
- 镜像运行
docker run -p 8080:8080 --name test-hello test:v1
参数:-p 映射容器内端口到宿主机;–name 容器名字;-d 后台运行
命令参考文档:https://docs.docker.com/engine/reference/run/
四、目录挂载
- 为什么要目录挂载?
使用 Docker 运行后,我们改了项目代码不会立刻生效,需要重新build和run。而且,容器里面产生的数据,例如 log 文件,数据库备份文件等,容器删除后就丢失了。因此引入目录挂载方式解决上述问题。 - 几种挂载方式
bind mount
:直接把宿主机目录映射到容器内,适合挂代码目录和配置文件。可挂到多个容器上;使用方式:bind mount 方式用绝对路径-v D:/code:/app
其中-v是参数,D:/code为绝对路径:/app容器路径
volume
:由容器创建和管理,创建在宿主机,所以删除容器不会丢失,官方推荐,更高效,Linux 文件系统,适合存储数据库数据。可挂到多个容器上;使用方式:-v db-data:/app
其中-v是参数,db-data是名字:/app容器路径
tmpfs mount
:适合存储临时文件,存宿主机内存中。不可多容器共享。(少用)
文档参考:https://docs.docker.com/storage/
示例:docker run -p 8080:8080 --name test-hello -v 绝对路径:/app -d test:v1
这里已成功进行目录上的挂载。
五、多容器通信
项目之间往往不是独立的,通常需要数据库、缓存等进行配合运作,因此不同项目之间需要通信协作。要想多容器之间互通,我们只需要把他们放到同个网络中就可以了。
以上述Web项目为例,增加一个 Redis 依赖,多跑一个 Redis 容器。因此Web容器和Redis容器要相互通信,只需将他们放到通过网络即可。具体操作如下:
- 创建网络
docker network create test-net
创建一个别名为test-net的网络 - 运行 Redis 在 test-net 网络中,别名redis
docker run -d --name redis --network test-net --network-alias redis redis:latest
并修改app.js代码,将其注释去掉。
- 运行Web项目,同时运用在同个网络
docker run -p 8080:8080 --name test -v 项目绝对路径:/app --network test-net -d test:v1
- 查看数据
http://localhost:8080/redis
容器终端查看数据是否一致,刷新一次,count递增1
六、docker-compose
上一部分,我们使用了Redis和Web两个容器,但往往在公司项目中,可能需要依赖很大第三方库,依赖等,我们需要管理的容器也会很多,每个都要单独配置运行,指定网络,这会很麻烦。这里,我们引入docker-compose,把项目的多个服务集合到一起,一键运行。
【注意】如果是docker-desktop,默认有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/Shanghai
volumes:
redis:
- 运行docker-compose.yml文件
在docker-compose.yml 文件所在目录,执行:docker-compose up -d
就可以跑起来了
docker-compose相关命令参考:
查看运行状态: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]
七、发布和部署
发布和部署前,需要在https://hub.docker.com/注册一个账号
-
命令行登录账号
docker login -u username
【注意】如果出现Error saving credentials: error storing credentials - err: exit status 1, out: `status code not OK but 500…, 尝试删掉C:\Users\[用户名]\.docker\config.json
文件,再登陆就不会出现这种问题 -
新建一个tag,名字必须跟你注册账号一样
docker tag test:v1 username/test:v1 -
push上去
docker push username/test:v1
-
部署
docker run -d -p 8090:8080 username/test:v1
docker-compose 中也可以直接用这个镜像了
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:
【补充】对于Docker有时候上传和下载都太慢了,如果你想要更快的速度,可以使用阿里云的免费镜像托管镜像托管,这里就不具体操作了。阿里云官网
总结 :本篇博客记录了自己入门Dokcer技术的笔记,有什么问题可以在评论区一起讨论~