关于 Docker 的使用总结;包括基本介绍、常用命令和项目打包部署说明
基本介绍
什么是 Docker
Docker 使用
Linux内核的 cgroup (opens new window),namespace (opens new window),以及 OverlayFS (opens new window)类的 Union FS (opens new window)等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术 (opens new window)。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。
也可以说 docker 是一个方便我们对应用进行打包分发部署的工具,可以认为这就是一个轻量级的虚拟机,但是这个虚拟机里面只有你软件需要的环境。
为什么要用 Docker
- 更高效的利用系统资源:容器不需要进行硬件虚拟以及运行完整操作系统等额外开销
- 更快速的启动时间:由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间
- 一致的运行环境:
Docker的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题; - 持续交付和部署:使用
Dockerfile使镜像构建透明化,一次创建或配置,可以在任意地方正常运行 - 更轻松的迁移:
Docker可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的 - 更轻松的维护和扩展:
Docker使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单
如何安装
桌面版:https://www.docker.com/products/docker-desktop
服务器版:https://docs.docker.com/engine/install/#server
Windows 安装图文教程及配置镜像源:https://docker.easydoc.net/doc/81170005/cCewZWoN/lTKfePfP
常用命令
在线练习网站
使用 Docker Hub 账号登录网站:https://labs.play-with-docker.com/
点击左侧 ADD NEW INSTANCE(添加新实例)
网页上不方便操作,可以使用 ssh 连接
参考:https://github.com/play-with-docker/play-with-docker/issues/238
看 issue 里面这位大哥的评论:**ParampreetR**
To all those who are here for same issue.
Thanks @sidebo
#247 solved my problem.- Run
ssh-keygenand fill out name of file and empty passphrase. - Run
ssh -i <File name entered in first step> <docker ssh address>. Example:ssh -i ida_rsa ip172-18-0-9-bfe8s7iv9dig00cuhdsg@direct.labs.play-with-docker.com
- Run
就是在终端执行
ssh-keygen命令,文件名随便定义,我这里定义为 test,输完文件名一路回车1
2
3
4
5
6
7
8[hczs8.houcheng] ➤ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/mobaxterm/.ssh/id_rsa): test
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in test.
Your public key has been saved in test.pub.
...然后执行命令
ssh -i <File name entered in first step> <docker ssh address>1
ssh -i test ip172-18-0-10-catfl8433d5g00cfsd10@direct.labs.play-with-docker.com
成功连接!
镜像
拉取镜像
1 | docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签] |
具体的选项可以通过 docker pull --help 命令看到,这里我们说一下镜像名称的格式。
- Docker 镜像仓库地址:地址的格式一般是
<域名/IP>[:端口号]。默认地址是 Docker Hub(docker.io)。 - 仓库名:如之前所说,这里的仓库名是两段式名称,即
<用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为library,也就是官方镜像。
如:我想把我在 Docker Hub 上的一个打包好的镜像拉下来:
1 | docker pull hsunnyc/code-generator-server:1.0.0 |
通过 <用户名>/<软件名>[:标签] 来定位,不写 Dcoker 镜像仓库地址就是默认 Docker Hub
列出镜像
1 | docker image ls |
列出镜像摘要:
1 | docker image ls --digests |
还可能会出现标签和名称都是 <none> 的镜像,这种叫做虚悬镜像,也就是没啥意义了,出现这种镜像是因为原来有个叫 a:1.0 的镜像,然后又仓库里面的 a:1.0 镜像更新了,但是标签还是这个标签,docker pull 下来之后,原来的 a:1.0 就是 <none> 了,删掉这种镜像的命令:
1 | docker image prune |
删除本地镜像
1 | $ docker image rm [选项] <镜像1> [<镜像2> ...] |
这个里面的 <镜像> 可以是镜像短 ID(IMAGE_ID 前几位)、镜像长 ID(IMAGE_ID 全部)、镜像名(REPOSITORY 列内容)或者镜像摘要(不常用)
保存镜像为文件
1 | docker save [镜像名] > test.tar |
加载镜像文件
1 | docker load -i test.tar |
构建镜像
构建镜像基于一个 Dockerfile 文件,在 Dockerfile 文件所在目录执行
1 | docker build . -t <用户名>/<软件名>:<标签> |
容器
启动容器
比如说启动个 nginx 容器
1 | docker run -d -p 8090:80 nginx |
- 起手式:docker run
- -d:后台启动
- -p:端口映射,规则为 <宿主机端口>:<容器端口>
- -v:目录挂载,规则为 <宿主机目录>:<容器内目录>,如果宿主机目录不存在会自动创建
- nginx:镜像名
如果后面的镜像不存在的话,docker 会去镜像仓库下载然后再启动
启动已终止容器
如果一个容器跑着跑着挂了,我们如何再把这个容器启动起来呢
1 | docker container start [容器id] |
重启容器
1 | docker container restart [容器id] |
停止容器
1 | docker container stop [容器id] |
列出容器
列出正在运行的容器
1
docker ps
列出所有容器
1
2docker ps -a
docker container ls -a
进入容器
1 | docker exec -it [容器id] bash |
导出容器快照
这个不同于 docker save,只是导出快照,不保存镜像的历史数据和元数据
1 | docker export [容器id] > test.tar |
导入容器快照到本地镜像库
1 | cat test.tar | docker import - test:1.0 |
Docker 镜像仓库
仓库是集中存放镜像的地方
Docker Hub
Docker Hub 是 Docker 官方仓库:https://hub.docker.com/
- 登录 / 退出:
docker login / docker logout - 搜索镜像:
docker search [关键字] - 推送镜像(先登录):
docker push <用户名>/<软件名>:<标签>
私有仓库
https://vuepress.mirror.docker-practice.com/repository/registry/
Docker Compose
Docker Compose 是 Docker 官方编排(Orchestration)项目之一,负责快速的部署分布式应用。
基本命令
1 | docker compose [-f=<arg>...] [options] [COMMAND] [ARGS...] |
命令选项
-f, --file FILE指定使用的 Compose 模板文件,默认为docker-compose.yml,可以多次指定。-p, --project-name NAME指定项目名称,默认将使用所在目录名称作为项目名。--verbose输出更多调试信息。-v, --version打印版本并退出
项目打包部署
项目打包部署基于一个 SpringBoot + Vue 的前后端分离的应用
Vue 项目打包镜像
教程:https://cli.vuejs.org/zh/guide/deployment.html#docker-nginx
参考:https://github.com/hczs/code-generator/blob/master/code-generator-ui/Dockerfile
Dockerfile 如下:
1 | # 基础镜像 node 环境 16.5.0 |
打包发布远程仓库
1 | # 在 Dockerfile 同级目录下 |
SpringBoot 项目打包镜像
参考:https://juejin.cn/post/6844903983392243720
本次使用的是 Maven + Jib 插件
文档:https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin
在 pom.xml 的
<plugins>标签 中添加如下内容1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23<!-- jib docker 打包插件 -->
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<from>
<image>openjdk:8-jdk-alpine</image>
</from>
<to>
<image>docker.io/hsunnyc/${project.name}:${project.version}</image>
</to>
</configuration>
<!--绑定到maven lifecicle-->
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>打开终端,先 docker login 上
然后执行插件

jib:build:构建并推送远程仓库
jib:buildTar:将镜像生成 tar 文件,保存在项目的 target 目录下,在任何 docker 环境执行 docker load –input xxx.tar 即可导入到本地镜像仓库
jib:dockerBuild:将镜像存入当前镜像仓库,该仓库是当前 docker 客户端可以连接的 docker daemon,一般是指本地镜像仓库
使用 docker-compose 部署
创建 docker-compose.yml 文件,21345 可以改成任意你喜欢的端口号,后续通过此端口号访问项目
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19version: "3"
services:
api:
image: hsunnyc/code-generator-server:1.0.0
restart: always
volumes:
- ./templates:/opt/service/code-generator/templates
- ./deleted:/opt/service/code-generator/deleted
environment:
TZ: Asia/Shanghai
web:
image: hsunnyc/code-generator-ui:1.0.0
restart: always
environment:
TZ: Asia/Shanghai
ports:
- "21345:80"
depends_on:
- api启动,在 docker-compose.yml 同级目录下
1
2
3
4
5
6前台启动
docker-compose up
后台启动 [推荐]
docker-compose up -d
停止
docker-compose down