关于 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,输完文件名一路回车[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>ssh -i test ip172-18-0-10-catfl8433d5g00cfsd10@direct.labs.play-with-docker.com -
成功连接!
镜像
拉取镜像
docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
具体的选项可以通过 docker pull --help 命令看到,这里我们说一下镜像名称的格式。
- Docker 镜像仓库地址:地址的格式一般是
<域名/IP>[:端口号]。默认地址是 Docker Hub(docker.io)。 - 仓库名:如之前所说,这里的仓库名是两段式名称,即
<用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为library,也就是官方镜像。
如:我想把我在 Docker Hub 上的一个打包好的镜像拉下来:
$ docker pull hsunnyc/code-generator-server:1.0.0
1.0.0: Pulling from hsunnyc/code-generator-server
e7c96db7181b: Pull complete
f910a506b6cb: Pull complete
c2274a1a0e27: Pull complete
793ba85783f1: Pull complete
71c649eb535e: Pull complete
c8874db75fe6: Pull complete
94fd546d83cd: Pull complete
Digest: sha256:4ac93c777e8c9ce1531e4f5aae6c9b8ca93ddde0d752d6f66563dd6b06e8c0c3
Status: Downloaded newer image for hsunnyc/code-generator-server:1.0.0
docker.io/hsunnyc/code-generator-server:1.0.0
通过 <用户名>/<软件名>[:标签] 来定位,不写 Dcoker 镜像仓库地址就是默认 Docker Hub
列出镜像
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hsunnyc/code-generator-ui 1.0.0 5f8c36545d4b 12 hours ago 143MB
hsunnyc/code-generator-server 1.0.0 51ff06c51802 52 years ago 142MB
列出镜像摘要:
docker image ls --digests
还可能会出现标签和名称都是 <none> 的镜像,这种叫做虚悬镜像,也就是没啥意义了,出现这种镜像是因为原来有个叫 a:1.0 的镜像,然后又仓库里面的 a:1.0 镜像更新了,但是标签还是这个标签,docker pull 下来之后,原来的 a:1.0 就是 <none> 了,删掉这种镜像的命令:
docker image prune
删除本地镜像
$ docker image rm [选项] <镜像1> [<镜像2> ...]
这个里面的 <镜像> 可以是镜像短 ID(IMAGE_ID 前几位)、镜像长 ID(IMAGE_ID 全部)、镜像名(REPOSITORY 列内容)或者镜像摘要(不常用)
保存镜像为文件
docker save [镜像名] > test.tar
加载镜像文件
docker load -i test.tar
构建镜像
构建镜像基于一个 Dockerfile 文件,在 Dockerfile 文件所在目录执行
docker build . -t <用户名>/<软件名>:<标签>
容器
启动容器
比如说启动个 nginx 容器
docker run -d -p 8090:80 nginx
- 起手式:docker run
- -d:后台启动
- -p:端口映射,规则为 <宿主机端口>:<容器端口>
- -v:目录挂载,规则为 <宿主机目录>:<容器内目录>,如果宿主机目录不存在会自动创建
- nginx:镜像名
如果后面的镜像不存在的话,docker 会去镜像仓库下载然后再启动
启动已终止容器
如果一个容器跑着跑着挂了,我们如何再把这个容器启动起来呢
docker container start [容器id]
重启容器
docker container restart [容器id]
停止容器
docker container stop [容器id]
列出容器
-
列出正在运行的容器
docker ps -
列出所有容器
docker ps -a docker container ls -a
进入容器
docker exec -it [容器id] bash
# 退出 (退出不会导致容器停止运行)
exit;
导出容器快照
这个不同于 docker save,只是导出快照,不保存镜像的历史数据和元数据
docker export [容器id] > test.tar
导入容器快照到本地镜像库
cat test.tar | docker import - test:1.0
# 然后 docker image ls 会出现一个 test 镜像
# 也可以从某个 URL 导入
docker import http://example.com/exampleimage.tgz example/imagerepo
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)项目之一,负责快速的部署分布式应用。
基本命令
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 如下:
# 基础镜像 node 环境 16.5.0
FROM node:16.5.0 as build-prod
# 把代码复制到镜像里
COPY ./ /app
# 切换到 /app 即复制过去的代码目录
WORKDIR /app
# 执行命令 安装依赖并打包
RUN npm install && npm run build:prod
# 第二阶段构建 基于 nginx 镜像构建
FROM nginx
# 把 build 好的 dist 放入 nginx 镜像这边的 /usr/share/nginx/html 目录
COPY --from=build-prod /app/dist /usr/share/nginx/html
# 其中 nginx.conf 中就配置了 80 端口的 根目录是 /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
打包发布远程仓库
# 在 Dockerfile 同级目录下
docker build . -t hsunnyc/code-generator-ui:1.0.0
# 发布
docker push hsunnyc/code-generator-ui:1.0.0
SpringBoot 项目打包镜像
参考:https://juejin.cn/post/6844903983392243720
本次使用的是 Maven + Jib 插件
文档:https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin
-
在 pom.xml 的
<plugins>标签 中添加如下内容<!-- 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 可以改成任意你喜欢的端口号,后续通过此端口号访问项目
version: "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 同级目录下
# 前台启动 docker-compose up # 后台启动 [推荐] docker-compose up -d # 停止 docker-compose down