Docker使用笔记

关于 Docker 的使用总结;包括基本介绍、常用命令和项目打包部署说明

基本介绍

什么是 Docker

Docker 使用 Google 公司推出的 Go 语言 (opens new window)进行开发实现,基于 Linux 内核的 cgroup (opens new window)namespace (opens new window),以及 OverlayFS (opens new window)类的 Union FS (opens new window)等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术 (opens new window)。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。

也可以说 docker 是一个方便我们对应用进行打包分发部署的工具,可以认为这就是一个轻量级的虚拟机,但是这个虚拟机里面只有你软件需要的环境。

为什么要用 Docker

  1. 更高效的利用系统资源:容器不需要进行硬件虚拟以及运行完整操作系统等额外开销
  2. 更快速的启动时间:由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间
  3. 一致的运行环境:Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题;
  4. 持续交付和部署:使用 Dockerfile 使镜像构建透明化,一次创建或配置,可以在任意地方正常运行
  5. 更轻松的迁移:Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的
  6. 更轻松的维护和扩展:Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单

如何安装

桌面版:https://www.docker.com/products/docker-desktop
服务器版:https://docs.docker.com/engine/install/#server

Windows 安装图文教程及配置镜像源:https://docker.easydoc.net/doc/81170005/cCewZWoN/lTKfePfP

常用命令

在线练习网站

  1. 使用 Docker Hub 账号登录网站:https://labs.play-with-docker.com/

  2. 点击左侧 ADD NEW INSTANCE(添加新实例)

  3. 网页上不方便操作,可以使用 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.

    1. Run ssh-keygen and fill out name of file and empty passphrase.
    2. 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
  4. 就是在终端执行 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.
    ...
  5. 然后执行命令 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
  6. 成功连接!

镜像

拉取镜像

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

  1. 在 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>
  2. 打开终端,先 docker login 上

  3. 然后执行插件

  4. jib:build:构建并推送远程仓库

  5. jib:buildTar:将镜像生成 tar 文件,保存在项目的 target 目录下,在任何 docker 环境执行 docker load –input xxx.tar 即可导入到本地镜像仓库

  6. jib:dockerBuild:将镜像存入当前镜像仓库,该仓库是当前 docker 客户端可以连接的 docker daemon,一般是指本地镜像仓库

使用 docker-compose 部署

  1. 创建 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
  2. 启动,在 docker-compose.yml 同级目录下

    # 前台启动
    docker-compose up
    # 后台启动 [推荐]
    docker-compose up -d
    # 停止
    docker-compose down

Docker使用笔记
https://www.powercheng.fun/articles/ccc46239/
作者
powercheng
发布于
2022年6月28日
许可协议