docker命令行总结

-- TOC --

本文尝试总结docker命令行常用命令及参数。

为了减少输入提高效率,我喜欢定义一个alias,安装完后,再顺便看一下docker的版本:

$ sudo apt install docker.io
$ sudo dnf install docker-ce docker-ce-cli containerd.io
$ alias docker='sudo docker'
$ docker --version
$ docker -v

image

从image开始吧,它是container的基础。

下面是查看系统image的命令:

$ # belows are the same:
$ docker images
$ docker image ls

当我们在本地主机上使用一个不存在的镜像时 Docker 就会自动下载这个镜像。如果我们想预先下载这个镜像,我们可以使用 docker pull 命令来下载它。

$ docker pull hello-world
$ docker pull python

docker pull默认是从docker官方仓库(hub.docker.com)下载,这个官方的仓库里面,有很多制作精良的基础image可供我们直接使用,基本上常用的开源项目的镜像,这里仓库里面都有。docker pull不需要登录,可直接下载到本地使用。可以登录hub.docker.com去搜索image,也可以使用docker search命令来搜索:

$ docker search python
$ docker search python --filter 'is-official=true'
$ docker search python --filter=start=50  # more than 50 stars
$ docker search python --limit=5
$ docker search --help

我始终觉得docker search命令不好用,可能是我不太会用吧,不如直接到hub.docker.com上去查找。

image的导入和导出

在团队中传递docker image,可以使用仓库的方式,要么使用docker官方仓库,要么自己建一个私有仓库。或者,使用save和load的方式,以传递文件的方式传递image,小规模团队,这种方式应该更简单方便。

$ docker image save --help
$ docker image load --help

我们也可以直接把一个container的文件系统输出,同样也可以导入这种输出来获得image,这种方式得到的image,没有history。

$ docker export --help
$ docker image import --help

image的删除

只有所有基于image的container都删除了之后,此image才可以删除:

$ docker rmi --help
$ docker image rm --help

run

有了image,就可以开始 docker run 了,这个命令有点容易误解,实际上是create+run,除非加上 --rm 参数,在容器运行结束时,自动将其删除。

$ docker run --rm hello-world
$ ...
$ docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

看到hello-world的打印信息,说明你的docker安装成功,可以正常使用!上面的第2次docker run没有加别的参数,此时虽然容器退出,但是这个容器还在,还可以重新启动:

$ docker ps -a  # all
CONTAINER ID   IMAGE         COMMAND    CREATED              STATUS                      PORTS     NAMES
93f8ad02b047   hello-world   "/hello"   About a minute ago   Exited (0) 23 seconds ago             eager_leavitt
$ docker ps     # only running

docker ps用来显示正在运行的容器,如果加上 -a 就可以显示所有的容器了。

hello-world容器只是用来测试docker环境,现在可以删除了:

$ docker rm 93f8ad  # or eager_leavitt

基于image创建的容器,是一对多的关系,一个image可以创建多个容器,可以理解为相同的容器进程有多个在同时运行!

每个容器都有一个系统自动生成的ID,但是name是可以由用户指定的,使用--name参数指定:

$ docker run --name hw hello-world
$ docker ps -af name=hw
CONTAINER ID   IMAGE         COMMAND    CREATED              STATUS                          PORTS     NAMES
1825754b8e3b   hello-world   "/hello"   About a minute ago   Exited (0) About a minute ago             hw
$ docker run --name python3 python python3 -V  # create a container named python3 by checking it's version
3.10.0

交互式的运行容器,比如要运行容器内的bash,使用 -i -t 参数,如果不使用这两个参数,容器会立即退出。

$ docker run --rm -it centos:8.2.2004 bash
[root@36a28aefdbfd /]# whoami
root

centos:8.2.2004是我本地已经下载好的image,后面跟的bash是我想执行的命令。其实centos镜像默认的CMD就是bash,我们可以用 -d 来运行一个centos的容器:

$ docker run -itd centos:8.2.2004

我刚开始学docker的时候,一直没有使用 --rm 参数,后来导致我本地有非常多的已经停止运行的容器,用 docker rm 一个个删除太费劲了,有一个简单的方法,用来删除停止运行的容器:

$ docker rm $(docker ps -aq)  # delete all container, careful!! But except the runnings
$ docker rm $(docker ps -qf status=exited) # delete all exited
$ docker container prune  # remove all stopped containers

停止容器的运行: docker stop

开始容器的运行:

$ docker start  # background
$ docker start -i  # interactive

后台运行的容器,可以用 docker exec 命令,实现在容器中执行命令:

$ docker exec c021161f ping www.maixj.net
PING www.maixj.net (114.215.183.12) 56(84) bytes of data.
64 bytes from 114.215.183.12 (114.215.183.12): icmp_seq=1 ttl=52 time=24.4 ms
64 bytes from 114.215.183.12 (114.215.183.12): icmp_seq=2 ttl=52 time=18.3 ms
docker exec -it c021161f bash
[root@c021161f4734 /]# whoami
root
[root@c021161f4734 /]# exit
exit
[xinlin@localhost ~]$ docker ps
CONTAINER ID   IMAGE             COMMAND       CREATED       STATUS       PORTS     NAMES
c021161f4734   centos:8.2.2004   "/bin/bash"   2 hours ago   Up 2 hours             dazzling_curran

使用docker exec在容器中执行命令,不会导致容器退出,而使用 docker attach ,会将后台运行的容器,拉回到前台,退出就是容器退出。

$ docker attach dazzling_curran
[root@c021161f4734 /]# whoami
root
[root@c021161f4734 /]# exit
exit
$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
$  # container is exited...

运行container进程,一般都需要设置volumn,进程的输入和输出数据通过volumn映射到宿主机上,而不是在container内部直接操作,并且还需要指定工作路径,以便程序能够正常工作。比如运行python代码,代码在宿主机上,数据也在宿主机上,我们需要的只是用container来启动一个完美的python进程,并给这个进程提供输入和输出。这需要 docker run 命令的 -v-w 参数。

$ cat ptest.py
import os
print(os.getcwd())
$ docker run --rm -v $(realpath .):/py -w /py python python3 ptest.py
/py

将当前路径映射到/py,并设置工作路径也为/py,这样在container中执行python3 ptest.py的时候,就能够找到ptest.py这个文件了。

本文链接:https://cs.pynote.net/sf/docker/202110307/

-- EOF --

-- MORE --