Docker 技巧

2 minute read

Published:

Docker 使用笔记:因为 Docker 有很多使用细节,这里只记录用于科研及基本工作的使用经验,长期更新。

详细使用手册:https://docker-practice.github.io/zh-cn/basic_concept/

1. 基本概念

Docker 可以方便复现项目,一个 Docker 仓库通常包括一个镜像和若干容器,镜像就像面向对象编程的类,容器就像类的方法。容器相当于固定了一个运行环境,也有一套项目代码,但是可以把本地(宿主机)的代码挂载到对应的容器代码上。这样容器跑本地代码,容器自己的代码不发生改变,就可以自己开发源码,容器不受影响。当然如果不采用挂载,也可以直接修改容器的代码。

2. 镜像基本操作

2.1. 下载镜像

国内网络问题无法直接连接官方 Docker 仓库。可以使用代理 hub.rat.dev/

  • 官方镜像

    # 原始命令
    docker pull nginx:latest
    
    # 使用代理
    docker pull hub.rat.dev/library/nginx:latest
    
  • 非官方镜像

    # 原始命令
    docker pull bitnami/redis:latest
    
    # 使用代理
    docker pull hub.rat.dev/bitnami/redis:latest
    

命令参考 https://www.yhnotes.com/blog/dockerhub-proxy/

可用镜像参考 https://cloud.tencent.com/developer/article/2485043

2.2. 列举、删除镜像

  • 列举镜像

    docker image ls
    

    ->

    REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
    centos                      latest              0584b3d2cf6d        3 weeks ago         196.5 MB
    redis                       alpine              501ad78535f0        3 weeks ago         21.03 MB
    docker                      latest              cf693ec9b5c7        3 weeks ago         105.1 MB
    nginx                       latest              e43d811ce2f4        5 weeks ago         181.5 MB
    
  • 删除镜像

    • 短id,可区分即可
      docker image rm 501
      
    • 完整id
      docker image rm 501ad78535f0
      
    • 镜像名:标签
      docker image rm redis:alpine
      

其他用法参考 https://docker-practice.github.io/zh-cn/image/rm.html

3. 容器

容器很轻量,一般是随时创建和删除的,启动的时候指定镜像,会先启动镜像然后启动容器,实际上跑的是容器。

3.1. 创建容器

docker run -t -i --rm ubuntu:18.04 /bin/bash

启动 ubuntu:18.04 的容器并且进入其 bash,其中,-t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i 则让容器的标准输入保持打开。如果没有这俩个参数,容器执行完命令直接关闭。--rm 要求容器关闭后删除,节省空间,否则容器文件保留。

-i -t 等价于 -it \

后台运行容器使用参数 -d,在后台运行容器,当前仍在宿主机。

docker run -t -i -d ubuntu:18.04 /bin/bash

3.2. 终止、重启容器

退出并且终止容器,在容器终端执行 exit 或者按键 Ctrl + d

退出但是维持容器运行 (detach),按键 Ctrl + p-Ctrl + q

所有容器通过 docker container ls -a 查看

终止正常运行的容器:docker container stop {ID}

终止异常运行的容器:docker container kill {ID}

启动终止的容器 docker container start {ID}

重启运行的容器 docker container restart {ID}

3.3. 进入运行的容器

查看所有容器 docker container ls -a

  1. 进入容器原本的终端
      docker attach {容器ID}
    
  2. 创建一个新的终端,不影响原本的终端
      docker exec -it {容器ID} bash
    

exec 相当于建一个新会话,不影响原会话,Docker 本身不提供会话管理功能,但是可以通过 tmux 实现。

3.4. 导出、导入容器

如果容器内容有修改,要分发容器。

$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                    PORTS               NAMES
7691a814370e        ubuntu:18.04        "/bin/bash"         36 hours ago        Exited (0) 21 hours ago                       test
$ docker export 7691a814370e > ubuntu.tar

这是和镜像一起压缩导出的,所以导入时会创建一个新的镜像:

$ cat ubuntu.tar | docker import - test/ubuntu:v1.0
$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED              VIRTUAL SIZE
test/ubuntu         v1.0                9d37a6082e97        About a minute ago   171.3 MB

3.5. 删除、清理容器

可以使用 docker container rm 来删除一个处于终止状态的容器。例如

$ docker container rm trusting_newton
trusting_newton

如果要删除一个运行中的容器,可以添加 -f 参数。Docker 会发送 SIGKILL 信号给容器。

清理所有处于终止状态的容器:用 docker container ls -a 命令可以查看所有已经创建的包括终止状态的容器,如果数量太多要一个个删除可能会很麻烦,用下面的命令可以清理掉所有处于终止状态的容器。

$ docker container prune

3.6. 数据管理

3.6.1. 挂载

把容器某个目录指定为其他路径,比如指定到本地的项目文件。这样本地就不需要配置环境,因为容器有环境,容器执行本地代码。本地代码可以修改,不影响容器代码。

-v {自定义路径}:{容器路径} \

或者

--mount source={自定义路径},target={容器路径} \

3.6.2. 挂载宿主机本地路径或文件

-v--mount 两种,一般情况直接 -v,容器终端具有读写权限。

$ docker run -d \
    --name web \
    # -v {本地路径名称}:/usr/share/nginx/html \
    --mount source={本地路径名称},target=/usr/share/nginx/html \
    nginx:alpine

其中 --name web 是指定容器名称为 web

也可以执行 docker inspect web 查看容器 web 的挂载情况。

3.6.3. 数据卷

数据卷由 Docker 管理,独立于容器,可以挂载到容器,挂载时只需要指定名称,不用管路径,这是与宿主机本地路径挂载的区别。

创建数据卷 $ docker volume create {数据卷名称}

查看数据卷 $ docker volume ls

查看数据卷信息

$ docker volume inspect {数据卷名称}
[
    {
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/{数据卷名称}/_data",
        "Name": "{数据卷名称}",
        "Options": {},
        "Scope": "local"
    }
]

可以挂载数据卷

$ docker run -d \
    --name web \
    # -v {数据卷名称}:/usr/share/nginx/html \
    --mount source={数据卷名称},target=/usr/share/nginx/html \
    nginx:alpine