【学习笔记】Docker 常用命令
前言
记录 Docker 的常用操作命令,主要目的在于巩固学习,同时也希望对初学者起到一此借鉴作用。
PS:本次演练的系统环境为 CentOS 7,Docker 版本为 20.10.12, build e91ed57。
本文内容参考:Docker 教程 | 菜鸟教程 (runoob.com)
Docker 镜像加速
国内从 DockerHub 拉取镜像有时会比较困难,可以配置镜像加速器。Docker 官方和国内很多云服务商都提供了国内加速器服务,例如:
- 阿里云:https://tia33io9.mirror.aliyuncs.com
- 科大镜像:https://docker.mirrors.ustc.edu.cn/
- 道客云:http://f1361db2.m.daocloud.io
- 网易:https://hub-mirror.c.163.com/
- 七牛云:https://reg-mirror.qiniu.com
Docker 官方加速器 https://registry.docker-cn.com ,现在好像已经不能使用了,我们可以多添加几个国内的镜像,如果有不能使用的,会切换到可以使用个的镜像来拉取。
当配置某一个加速器地址之后,若发现拉取不到镜像,请切换到另一个加速器地址。国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务。
打开终端,使用 vim 打开 /etc/docker/daemon.json 文件,写入以下内容(如果文件不存在请新建该文件):
# 打开/etc/docker/daemon.json文件
vim /etc/docker/daemon.json
{
"registry-mirrors": [
"https://tia33io9.mirror.aliyuncs.com",
"https://docker.mirrors.ustc.edu.cn",
"http://f1361db2.m.daocloud.io",
"https://hub-mirror.c.163.com",
"https://reg-mirror.qiniu.com",
"https://registry.docker-cn.com"
]
}
之后重新启动服务:
sudo systemctl daemon-reload
sudo systemctl restart docker
Docker 简单示例
Docker 允许你在容器内运行应用程序, 使用 docker run 命令来在容器内运行一个应用程序。此处以 Nginx 服务部署做一个演练。
docker run --name my-nginx -d -p 8888:80 -e TZ=Asia/Shanghai nginx
执行结果见下图:
PS:由于之前没有拉取过 Nginx 的镜像,所以会先自动下载 Nginx 镜像。拉取后自动运行容器。通过
docker ps命令可以查看运行中的容器列表。
各个参数解析:
- docker: Docker 的二进制执行文件。
- run: 与前面的 docker 组合来运行一个容器。
- --name my-nginx:指定运行的容器名称为
my-nginx。 - -d :后台运行。在大部分的场景下,我们希望 docker 的服务是在后台运行的,我们可以过
-d指定容器的运行模式。注:加了 -d 参数默认不会进入容器,想要进入容器需要使用指令docker exec(下面会介绍到)。 - -p 8888:80:映射端口。开放主机 8888 端口,映射到容器的 80 端口。
- -e TZ=Asia/Shanghai:环境变量。设置容器中运行程序的时区为 亚洲-上海。(我个人感觉这个设置有时很有必要,如果服务器时区与访问客户端不一致时,会出问题的)
- nginx:指定要运行的镜像,Docker 首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像。
执行 docker ps 命令,会把当前运行的容器给列出来。结果如上图所示。
| 字段 | 名称 | 结果 |
|---|---|---|
| CONTAINER ID | 容器ID | b7498b9d4ba1 |
| IMAGE | 镜像名称 | nginx |
| COMMAND | 执行命令 | "/docker-entrypoint.…" |
| CREATED | 创建时间 | 2 minutes ago |
| STATUS | 运行状态 | Up 2 minutes |
| PORTS | 端口映射 | 0.0.0.0:8888->80/tcp, :::8888->80/tcp |
| NAMES | 容器名称 | my-nginx |
CentOS虚拟机的 局域网 IP为 192.168.1.30,通过浏览器访问 http://192.168.1.30:8888 ,出现以下画面,说明 nginx 服务器已正常运行。
Docker 镜像使用
当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载。
1、列出镜像
我们可以使用 docker images 来列出本地主机上的镜像。
docker images
# docker images 命令默认不显示中间镜像,如需查看全部镜像,请添加 -a 参数,使用 docker images -a 命令进行查询。
各列字段说明:
- REPOSITORY:表示镜像的仓库源
- TAG:镜像的标签
- IMAGE ID:镜像ID
- CREATED:镜像创建时间
- SIZE:镜像大小
同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,如 ubuntu 仓库源里,有 15.10、14.04 等多个不同的版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。
所以,我们如果要使用版本为15.10的ubuntu系统镜像来运行容器时,命令如下:
docker run -it ubuntu:15.10 /bin/bash
如果你不指定一个镜像的版本标签,例如你只使用 ubuntu,docker 将默认使用 ubuntu:latest 镜像。
PS:如果想要查询某个镜像之前的版本(Tag),需要到 Docker Hub 官网 https://hub.docker.com/ 进行查询获取。
2、查找镜像
我们可以从 Docker Hub 网站来搜索镜像,Docker Hub 网址为: https://hub.docker.com/
我们也可以使用 docker search 命令来搜索镜像。比如我们需要一个 httpd 的镜像来作为我们的 web 服务。我们可以通过 docker search 命令搜索 httpd 来寻找适合我们的镜像。
[root@localhost ~]# docker search nginx
NAME: 镜像仓库源的名称
DESCRIPTION: 镜像的描述
OFFICIAL: 是否 docker 官方发布
STARS: 类似 Github 里面的 star,表示点赞、喜欢的意思。
AUTOMATED: 自动构建。
3、拖取镜像
当我们在本地主机上使用一个不存在的镜像时 Docker 就会自动下载这个镜像。如果我们想预先下载这个镜像,我们可以使用 docker pull 命令来下载它。
# 下载 ubuntu 镜像到本机
docker run ubuntu
输出内容如下所示:
[root@localhost ~]# docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
7b1a6ab2e44d: Pull complete
Digest: sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
[root@localhost ~]#
下载完成后,我们就可以使用这个镜像了。
# 运行并进入容器,执行相应命令
docker run -it ubuntu /bin/bash
PS:我运行到这里竟然失败了!出现以下提示:
WARNING: IPv4 forwarding is disabled. Networking will not work.网上搜索了一下,通过以下办法解决 “IPv4 forwarding is disabled” 的问题。
第一步:在宿主机上执行
echo "net.ipv4.ip_forward = 1" >>/usr/lib/sysctl.d/00-system.conf# 执行命令 echo "net.ipv4.ip_forward = 1" >>/usr/lib/sysctl.d/00-system.conf # 查看文件 cat /usr/lib/sysctl.d/00-system.conf # 以下为文件内容,可以看到 net.ipv4.ip_forward = 1 的设置已追加到文件末尾。 # Kernel sysctl configuration file # # For binary values, 0 is disabled, 1 is enabled. See sysctl(8) and # sysctl.conf(5) for more details. # Disable netfilter on bridges. net.bridge.bridge-nf-call-ip6tables = 0 net.bridge.bridge-nf-call-iptables = 0 net.bridge.bridge-nf-call-arptables = 0 net.ipv4.ip_forward = 1第二步:重启network和docker服务
systemctl restart network && systemctl restart docker第三步:验证是否成功
docker run -it ubuntu /bin/bash完美解决。
4、删除镜像
镜像删除使用 **docker rmi ** 或 docker image rm 命令:
docker rmi ubuntu:14.04
删除指定镜像,也可以使用镜像ID:
[root@localhost ~]# docker image rm 9b9cb95443b5
Untagged: ubuntu:15.10
Untagged: ubuntu@sha256:02521a2d079595241c6793b2044f02eecf294034f31d6e235ac4b2b54ffc41f3
Deleted: sha256:9b9cb95443b5f846cd3c8cfa3f64e63b6ba68de2618a08875a119c81a8f96698
Deleted: sha256:b616585738eaf78ff7d86c7526caf7c91a35bc4028ef63204e5bfee82f7494b5
Deleted: sha256:dee1316f97acc7e1a5088b02fbc2b3078e0bfa038dd904b8072e2de5656e7bb8
Deleted: sha256:e7d9ae1a69c53c9fefa1aef34348be5a5dbf2fe79e7dd647b3d4f4e927587ebc
Deleted: sha256:f121afdbbd5dd49d4a88c402b1a1a4dca39c9ae75ed7f80a29ffd9739fc680a7
[root@localhost ~]# #这里再列表所有镜像,可以看到 ubuntu:15.10 已不见了。
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 8 days ago 141MB
ubuntu latest ba6acccedd29 2 months ago 72.8MB
[root@localhost ~]#
5、创建镜像
当我们从 docker 镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。
- 1、从已经创建的容器中更新镜像,并且提交这个镜像
- 2、使用 Dockerfile 指令来创建一个新的镜像
5.1 更新镜像
更新镜像之前,我们需要使用镜像来创建一个容器。
[root@localhost ~]# docker run -t -i ubuntu:latest /bin/bash
root@dd88dacb1af7:/#
# 注意哦,通过前面显示的登录账号名称,可以看出,目前已是进入了 ubuntu 容器中了。
在运行的容器内使用 apt-get update 命令进行更新。
在完成操作之后,输入 exit 命令来退出这个容器。
此时 ID 为 dd88dacb1af7 的容器,是按我们的需求更改的容器。我们可以通过命令 docker commit 来提交容器副本。
[root@localhost ~]# docker commit -m="This has been updated." -a="jack" dd88dacb1af7 jack/ubuntu:v2
sha256:d1c2e19bdcdcb5f3ffb4c5b1c795e938defa9c316588ec49603a817c472f303b
[root@localhost ~]#
各个参数说明:
- -m: 提交的描述信息
- -a: 指定镜像作者
- dd88dacb1af7:容器 ID
- jack/ubuntu:v2: 指定要创建的目标镜像名
我们可以使用 docker images 命令来查看我们的新镜像 jack/ubuntu:v2:
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jack/ubuntu v2 d1c2e19bdcdc About a minute ago 105MB
nginx latest 605c77e624dd 8 days ago 141MB
ubuntu latest ba6acccedd29 2 months ago 72.8MB
5.2 构建镜像
使用VS2022,基于.NET 6 ,创建一个控制台程序进行镜像发布。最简单的 Hello World 输出。
- 选择项目模板
- 设置项目名称,就叫 HelloWorldDemo 吧。(选择将解决方案和项目放在同一目录)
- 选择运行时版本为 .NET 6.0 (长期支持),然后点击“创建”按钮。
项目创建完成,整个程序目前仅一句代码:
Console.WriteLine("Hello, World!");
- 点击右侧解决方案资源管理器,在项目名称上面右键,选择 “添加” -- “Docker 支持 …”,会弹出一个“Docker 文件选项”窗口,选择 “Linux” 。
- 点击确定后,会在项目下生成一个 Dockerfile 文件。
Dockerfile 文件代码如下:
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["HelloWorldDemo.csproj", "."]
RUN dotnet restore "./HelloWorldDemo.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "HelloWorldDemo.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "HelloWorldDemo.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "HelloWorldDemo.dll"]
每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。
第一条FROM,指定使用哪个镜像源
RUN 指令告诉docker 在镜像内执行命令,安装了什么。。。
后面,我们会使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像。
- 选择控制台输出方式,本地运行调试。输出 “Hello World” ,说明程序运行正常。
OK ,到了这一步,我们的程序已准备好了。下面就选择把项目整体打包到 Linux,在服务器上进行编辑打包,镜像构建。
- 打开项目所在文件夹,把一些无用的文件删除掉。
- 清理掉无用文件夹,直接把项目文件夹上传服务器。如下图所示,关键点就在于本次上传的文件中包含了 Dockerfile 文件。
- 执行镜像打包 docker build 命令: ( 注意哦,命令最后面有一个 “.” 符号 )
docker build -t my-hello-world .
参数说明:
- -t :指定要创建的目标镜像名
- . :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径
- 开台下载中间镜像,并进行编辑。
最终完整输出如下:
[root@localhost HelloWorldDemo]# docker build -t my-hello-world .
Sending build context to Docker daemon 7.168kB
Step 1/15 : FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base
6.0: Pulling from dotnet/runtime
a2abf6c4d29d: Pull complete
08af7dd3c640: Pull complete
742307799914: Pull complete
a260dbcd03fc: Pull complete
Digest: sha256:315b0ab91f3abf2b29bc91963d86be6dd69abce3fe272306ed4ef8a5a7a190c0
Status: Downloaded newer image for mcr.microsoft.com/dotnet/runtime:6.0
---> 8a2ce7cb4b01
Step 2/15 : WORKDIR /app
---> Running in 9c79c4e71115
Removing intermediate container 9c79c4e71115
---> f6738ccc8759
Step 3/15 : FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
6.0: Pulling from dotnet/sdk
a2abf6c4d29d: Already exists
08af7dd3c640: Already exists
742307799914: Already exists
a260dbcd03fc: Already exists
96c3c696f47e: Pull complete
d81364490ceb: Pull complete
3e56f7c4d95f: Pull complete
9939dbdaf4a7: Pull complete
Digest: sha256:a7af03bdead8976d4e3715452fc985164db56840691941996202cea411953452
Status: Downloaded newer image for mcr.microsoft.com/dotnet/sdk:6.0
---> e86d68dca8c7
Step 4/15 : WORKDIR /src
---> Running in 2442842227a1
Removing intermediate container 2442842227a1
---> d11c08ee15dd
Step 5/15 : COPY ["HelloWorldDemo.csproj", "."]
---> cf0d49961aad
Step 6/15 : RUN dotnet restore "./HelloWorldDemo.csproj"
---> Running in b3962d0da619
Determining projects to restore...
Restored /src/HelloWorldDemo.csproj (in 2.16 sec).
Removing intermediate container b3962d0da619
---> 649ed5b1ae54
Step 7/15 : COPY . .
---> e43f4a0cc84f
Step 8/15 : WORKDIR "/src/."
---> Running in 95ee5b391f75
Removing intermediate container 95ee5b391f75
---> dd6909ce462f
Step 9/15 : RUN dotnet build "HelloWorldDemo.csproj" -c Release -o /app/build
---> Running in e05f29a6ca5b
Microsoft (R) Build Engine version 17.0.0+c9eb9dd64 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
All projects are up-to-date for restore.
HelloWorldDemo -> /app/build/HelloWorldDemo.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:06.11
Removing intermediate container e05f29a6ca5b
---> 266ccf4a1f98
Step 10/15 : FROM build AS publish
---> 266ccf4a1f98
Step 11/15 : RUN dotnet publish "HelloWorldDemo.csproj" -c Release -o /app/publish
---> Running in 1e914748682c
Microsoft (R) Build Engine version 17.0.0+c9eb9dd64 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
All projects are up-to-date for restore.
HelloWorldDemo -> /src/bin/Release/net6.0/HelloWorldDemo.dll
HelloWorldDemo -> /app/publish/
Removing intermediate container 1e914748682c
---> 018f9624857c
Step 12/15 : FROM base AS final
---> f6738ccc8759
Step 13/15 : WORKDIR /app
---> Running in 8764e2145751
Removing intermediate container 8764e2145751
---> d7ec7560e4f9
Step 14/15 : COPY --from=publish /app/publish .
---> 637fe040bfdc
Step 15/15 : ENTRYPOINT ["dotnet", "HelloWorldDemo.dll"]
---> Running in be3764a6bee1
Removing intermediate container be3764a6bee1
---> 1add28a21d49
Successfully built 1add28a21d49
Successfully tagged my-hello-world:latest
[root@localhost HelloWorldDemo]#
- 使用docker images 查看创建的镜像已经在列表中存在,镜像ID为1add28a21d49,名称为 my-hello-world 。
- 最后,我们可以使用容器来运行镜像。可以看出,Hello,World !已正常输出。( ?? ω ?? )?
docker run my-hello-world
6、设置标签
我们可以使用 docker tag 命令,为镜像添加一个新的标签。
docker tag 1add28a21d49 my-hello-world:V1.0
# 参数说明:
# docker tag <镜像ID> <镜像源名> <新的标签名>
使用 docker images 命令可以看到,ID为 1add28a21d49 的镜像多一个标签 V1.0。
[root@localhost HelloWorldDemo]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-hello-world V1.0 1add28a21d49 15 minutes ago 188MB
my-hello-world latest 1add28a21d49 15 minutes ago 188MB
018f9624857c 15 minutes ago 726MB
mcr.microsoft.com/dotnet/sdk 6.0 e86d68dca8c7 2 weeks ago 716MB
mcr.microsoft.com/dotnet/runtime 6.0 8a2ce7cb4b01 2 weeks ago 188MB
[root@localhost HelloWorldDemo]#
PS:我个人理解,打标签就是把原甩的镜像复制一份,加个标签显示而已。
Docker 容器使用
1、帮助手册
docker 客户端非常简单 ,我们可以直接输入 docker 命令来查看到 Docker 客户端的所有命令选项。
[root@localhost ~]# docker
这个就不放图了,可以自己去试一下。可以通过命令 docker command --help 更深入的了解指定的 Docker 命令使用方法。
例如我们要查看 docker run 指令的具体使用方法:
[root@localhost ~]# docker run --help
2、获取镜像
如果我们本地没有镜像,我们可以使用 docker pull 命令来载入镜像:
docker pull nginx
2、启动容器
[root@localhost HelloWorldDemo]# docker run -d -p 9999:80 --name my-nginx nginx
24054bd26a66522c9b3b6fc067d2a24d2bb9153b5be38f8dc3d658ba6a3a9e04
参数说明:(见前面简单示例内容)
3、启动已停止运行的容器
查看所有的容器命令如下:
docker ps -a
使用 docker start 启动一个已停止的容器:
docker start 70994ac442fa
4、后台运行
在大部分的场景下,我们希望 docker 的服务是在后台运行的,我们可以过 -d 指定容器的运行模式。
docker run -d -p 9999:80 --name my-nginx nginx
注:加了 -d 参数默认不会进入容器,想要进入容器需要使用指令 docker exec。
5、停止容器
停止容器的命令如下:
docker stop <容器 ID>
停止的容器可以通过 docker restart 重启:
docker restart <容器 ID>
6、进入容器
在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:
- docker attach
- docker exec:推荐大家使用 docker exec 命令,因为此退出容器终端,不会导致容器的停止。
# 进入容器
[root@localhost HelloWorldDemo]# docker exec -it 24054bd26a66 /bin/bash
# 查看当前目录
root@24054bd26a66:/# ls
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint.d etc lib media opt root sbin sys usr
# 退出容器
root@24054bd26a66:/# exit
exit
[root@localhost HelloWorldDemo]#
7、删除容器
删除容器使用 docker rm 命令:
# 正常情况下,我们只能删除已停止的容器,添加 -f 参数,强制执行,不再考虑容器是否正在运行。
[root@localhost HelloWorldDemo]# docker rm -f 70994ac442fa
70994ac442fa
[root@localhost HelloWorldDemo]#
8、查看日志
docker logs [ID或者名字] 可以查看容器内部的标准输出。
[root@localhost HelloWorldDemo]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
24054bd26a66 nginx "/docker-entrypoint.…" 18 minutes ago Up 18 minutes 0.0.0.0:9999->80/tcp, :::9999->80/tcp my-nginx
[root@localhost HelloWorldDemo]# docker logs 24054bd26a66
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2022/01/09 07:29:48 [notice] 1#1: using the "epoll" event method
2022/01/09 07:29:48 [notice] 1#1: nginx/1.21.5
2022/01/09 07:29:48 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2022/01/09 07:29:48 [notice] 1#1: OS: Linux 3.10.0-1160.49.1.el7.x86_64
2022/01/09 07:29:48 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2022/01/09 07:29:48 [notice] 1#1: start worker processes
2022/01/09 07:29:48 [notice] 1#1: start worker process 32
2022/01/09 07:29:48 [notice] 1#1: start worker process 33
2022/01/09 07:29:48 [notice] 1#1: start worker process 34
2022/01/09 07:29:48 [notice] 1#1: start worker process 35
[root@localhost HelloWorldDemo]#
9、运行状态
通过 docker stats <容器名称|ID> 命令可以查看容器的运行状态(会一直监控)。
[root@localhost HelloWorldDemo]# docker stats my-nginx
#================================
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
24054bd26a66 my-nginx 0.01% 3.074MiB / 1.777GiB 0.17% 656B / 0B 0B / 14.3kB 5
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
24054bd26a66 my-nginx 0.01% 3.074MiB / 1.777GiB 0.17% 656B / 0B 0B / 14.3kB 5
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
24054bd26a66 my-nginx 0.00% 3.074MiB / 1.777GiB 0.17% 656B / 0B 0B / 14.3kB 5
…… ……
10、查看配置
使用 docker inspect 来查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。
[root@localhost HelloWorldDemo]# docker inspect my-nginx
[
{
"Id": "24054bd26a66522c9b3b6fc067d2a24d2bb9153b5be38f8dc3d658ba6a3a9e04",
"Created": "2022-01-09T07:29:47.729484247Z",
"Path": "/docker-entrypoint.sh",
"Args": [
"nginx",
"-g",
"daemon off;"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 20677,
"ExitCode": 0,
"Error": "",
"StartedAt": "2022-01-09T07:29:48.345380918Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85",
"ResolvConfPath": "/var/lib/docker/containers/24054bd26a66522c9b3b6fc067d2a24d2bb9153b5be38f8dc3d658ba6a3a9e04/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/24054bd26a66522c9b3b6fc067d2a24d2bb9153b5be38f8dc3d658ba6a3a9e04/hostname",
"HostsPath": "/var/lib/docker/containers/24054bd26a66522c9b3b6fc067d2a24d2bb9153b5be38f8dc3d658ba6a3a9e04/hosts",
"LogPath": "/var/lib/docker/containers/24054bd26a66522c9b3b6fc067d2a24d2bb9153b5be38f8dc3d658ba6a3a9e04/24054bd26a66522c9b3b6fc067d2a24d2bb9153b5be38f8dc3d658ba6a3a9e04-json.log",
"Name": "/my-nginx",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {
"80/tcp": [
{
"HostIp": "",
"HostPort": "9999"
}
]
},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "host",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/4a3a739f9a9119beba2e538df7337fea5f168341dc42c9bc65ce36be7a528718-init/diff:/var/lib/docker/overlay2/88d844c8acf8fbfec44d5f4c7327504bdca4e1873113199ade6260d4da46c623/diff:/var/lib/docker/overlay2/b69d39d9431945be58d6a8924dd234c0007243113890853cea9fe0c77a0b5586/diff:/var/lib/docker/overlay2/81a4e929367676ac2cdf41efbcc243f6d5ccb086f37bc68d0bc479126cfd4ec7/diff:/var/lib/docker/overlay2/9b1e65f53f3fdefeb5691bd2311fe667bdc235090b88044ccca7c1ae14d975ed/diff:/var/lib/docker/overlay2/f4eed501c804e0d20564b21c8168e6ad11cca0d39fbf540343a90cdcffed0977/diff:/var/lib/docker/overlay2/f551faa359b34434e21a0ab26f5bed102c84318472f73412e0e2c5adcb5fe968/diff",
"MergedDir": "/var/lib/docker/overlay2/4a3a739f9a9119beba2e538df7337fea5f168341dc42c9bc65ce36be7a528718/merged",
"UpperDir": "/var/lib/docker/overlay2/4a3a739f9a9119beba2e538df7337fea5f168341dc42c9bc65ce36be7a528718/diff",
"WorkDir": "/var/lib/docker/overlay2/4a3a739f9a9119beba2e538df7337fea5f168341dc42c9bc65ce36be7a528718/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "24054bd26a66",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.21.5",
"NJS_VERSION=0.7.1",
"PKG_RELEASE=1~bullseye"
],
"Cmd": [
"nginx",
"-g",
"daemon off;"
],
"Image": "nginx",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers "
},
"StopSignal": "SIGQUIT"
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "248e77ef721f2e006d6e200c746f6844beb190ec15ad229d17080e4ae644cada",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"80/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "9999"
},
{
"HostIp": "::",
"HostPort": "9999"
}
]
},
"SandboxKey": "/var/run/docker/netns/248e77ef721f",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "ab9dd37591919447479f7a12c54fde1b45e39083a7906f6200092896d33b481b",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "94f59e18e4d854c6dc8fa1848d791f91905e675619c9ddd2d6a46f880882c3bc",
"EndpointID": "ab9dd37591919447479f7a12c54fde1b45e39083a7906f6200092896d33b481b",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
}
}
]
小结
以上内容,已把 Docker 容器的一些常用操作命令进行了演示,掌握之后,正常操作入门已是没有太大问题。
在进行本次演练的过程中,我也是踩了不少的坑。比如自己构建镜像的那一块,我就是由于对 Dockerfile 的配置没有写正确,导致镜像打包过程中总是报错。后面还是向社区的朋友请教了之后才磕磕碰碰的发布成功。
^ _ ^ ,感谢 橙子! 这是他搞的一个开源项目,ccnetcore/Yi: Yi.Framework-基于.NET5+Vue快速开发框架 (github.com),大家感兴趣的可以去瞅瞅!顺便点个星星。