Docker入门最详细指北
什么是 Docker
Docker是一个开源的平台,用于开发、交付和运行应用程序。它能够在Windows,macOS,Linux计算机上运行,并将某一应用程序及其依赖项打包至一个容器中,这些容器可以在任何支持Docker的环境中运行。容器彼此隔离,但可以通过特定的通道相互传递信息。
Docker提供了一个轻量级的虚拟化解决方案。由于运行在同一计算机上的所有容器共享同一个操作系统内核,避免了启动与维护虚拟机的开销。因此相比于传统的虚拟机,Docker容器更加轻便、快速、容易部署。使用Docker,开发者可以避免在两台计算机上运行效果不一致的问题,容器提供了一致的行为,进而使得应用程序在不同环境的计算机上有相同的运行效果。
Docker 架构
Docker不是虚拟机,本质上是对一个Linux内核上的进行隔离,把多个运行环境以容器的形式隔离开来。每个容器的环境都是独立的,但是所有容器共用一个Linux内核,这避免了虚拟机技术启动多个Linux内核所带来的开销。

Docker 镜像
Docker镜像是容器的只读模板。每个镜像都包含了应用程序运行所需的操作系统、运行时、库、环境变量和应用代码等。镜像是静态的,用户可以根据镜像启动容器。
-
镜像是构建容器的基础,每个容器实例化时都会使用镜像。
-
镜像是只读的,不同容器使用同一个镜像时,容器中的文件系统层是独立的。
Docker 容器
Docker 容器是镜像的运行实例,是一个轻量级、可移植的执行环境。
- 隔离性:每个容器都有自己的文件系统、网络和进程空间
- 临时性:容器可以被创建、启动、停止、删除
- 可写层:容器在镜像基础上添加了一个可写层
- 进程级:容器内通常运行一个主进程
Docker 仓库
仓库是存储和分发镜像的地方,可以包含一个镜像的多个版本。
- 公共仓库:如
Docker Hub,任何人都可以使用 - 私有仓库:企业内部搭建,用于存储私有镜像
- 官方仓库:由软件官方维护的镜像仓库
镜像、容器、仓库的关系
容器是由镜像制作出来的,而镜像可以从仓库获取,或者通过DockerFile构建。
类比理解:
-
容器 = 糕点,镜像 = 制作糕点的模版,仓库 = 贩卖模具的摊贩
-
如果镜像是类,那么容器就是对象实例。一个镜像可以创建多个容器,就像一个类可以创建多个对象。

Docker网络
Bridge 桥接(默认)

可以给容器分配不同的子网,每个子网之间的容器可以互相访问,并且通过Docker的DNS服务,同一个子网的容器可以用类似http://<Contatiner Name>/的形式访问,即不用知道具体的IP。
创建子网的命令如下
|
|
Host 模式
容器直接使用宿主机网络(即服务直接开放到宿主机的端口上,使用宿主机的IP地址)。
Docker的安装
Docker本质基于Linux内核,所以在其它操作系统上运行本质都是虚拟运行Linux。下面以Ubuntu做演示。
下载并运行Docker安装脚本。
|
|
脚本提示完成即安装好了Docker。
Docker 常用命令
-
pull命令(下载镜像)Example:
1docker pull docker.io/library/nginx:latest可以看到
docker.io/library/nginx:latest由三部分组成:-
registry(仓库地址):docker.io代表官方仓库,官方仓库可以省略仓库地址 -
namespace(命名空间):library是官方仓库的命名空间,非官方的一般是上传者ID,官方仓库的命名空间可以省略。 -
tag(标签/版本):nginx:latest,latest可省去,也可指定版本。
三者合起来
docker.io/library/nginx写表示为镜像库。以上命令最后可简化为:
1docker pull nginx注意:国内可能需要配置镜像站。
1sudo nano /etc/docker/daemon.json输入:
1 2 3 4 5 6 7{ "registry-mirrors": [ "https://docker.m.daocloud.io", "https://docker.1panel.live", "https://hub.rat.dev" ] }现在只有很少的国内镜像站存活,不保证镜像齐全。
重启
Docker1sudo service docker restart参数表
--platform=XXX:表示拉取特定CPU架构的镜像(前提是存在这个架构的镜像)。 -
-
images、rmi命令(管理镜像)Example:
1sudo docker images这个命令可以列出所有下载的
Docker镜像。Example:
1sudo docker rmi <ID/NAME>可以删除指定镜像,其中
ID/NAME应当通过docker images查看。 -
volume命令(创建挂载卷)Example:
1sudo docker volume create nginx_html表示新建一个名为
nginx_html的挂载卷。实际位置通过下面这个命令查询:
1sudo docker volume inspect nginx_html注意:第一次使用的挂载卷的时候,
Docker会把容器里面对应目录的文件复制一份到挂载卷进行初始化(详细见下文)。命令 作用 docker volume list列出所有的挂载卷 docker volume rm <name>删除指定挂载卷 docker volume prune -a删除所有没有任何容器使用的挂载卷 -
run命令(使用镜像创建并运行容器)Example:
1sudo docker run nginx <Custom Contatiner Name>其中
nginx也可以换成镜像的ID,<Custom Contatiner Name>为自定义容器名。如果没有
pull镜像而使用run命令,那么会自动pull。参数表
参数 作用 -d分离模式,让容器在后台运行,避免卡住终端窗口。 -p格式为 -p 255:80表示把的255端口数据转发到容器的80端口-v绑定挂载:格式为 -v 主机目录:容器内目录
命名卷挂载:格式为-v 卷的名字:容器内目录
这会把容器内目录实际反应到主机上,称作挂载卷。
避免因为删除容器抹去该文件夹下面的数据,称作持久化保存。-e向容器里面传递环境变量,具体的环境变量应该在容器的介绍页面查看。
环境变量一般用于自定义容器内部服务的设置。-it让当前终端进入容器进行交互,该命令一般同 --rm一起使用。Ctrl+D退出。--rm表示当容器停止的时候就把容器删除掉。 --restart格式 --restart <always/unless-stopped>。always会自动重启停止的容器unless-stopped会自动重启停止的容器,但手动停止的不会。--network格式 --network <NetworkName>,指定容器加入子网。实战Example:
1sudo docker run -d -p 80:80 -v /website/html:/usr/share/nginx/html nginx注意:
run每次都会创建并且运行一个容器,如果要对已经存在的容器进行启停,则需要使用docker start/stop <Contatiner Name/ID>。 -
create命令(创建容器)用法同上,具体区别是创建容器后不会启动,需要额外使用
docker start。 -
exec命令(把Linux命令转到容器内)Example:
1docker exec <Contatiner Name/ID> <linux命令>特别的,使用
1docker exec <Contatiner Name/ID> /bin/sh 或 /bin/bash可以获得一个交互式的命令行环境,
Ctrl+D退出。注意:为了压缩镜像大小,容器内部的系统一般都是极简的,许多常用工具需要自行安装。
-
ps命令(查看进程状况)Example:
1sudo docker ps <-a>这会列出运行容器的详细信息。
存在
-a则会列出全部容器。如果需要查询某个容器的全部信息,可以使用:
1docker inspect <Contatiner ID> -
rm命令(删除容器)Example:
1sudo docker rm <-f> <Contatiner Name>其中
-f参数会强制删除运行中的容器。 -
logs(查看容器日志)Example:
1sudo docker logs <Contatiner Name/ID> <-f>其中
-f表示实时日志。
Dockerfile
Example:
|
|
这里贴一个HydroOJ的评测机的Dockerfile做参考:
|
|
构建镜像命令
|
|
其中.表示当前目录。
Docker Compose 技术
这是一个容器编排技术,可以方便的管理几个需要协同工作的容器,而不必使用繁琐的docker run命令。
Example:
|
|
这是一个Domjudge的compose文件:
|
|
Docker会给每个Compose文件中的容器自动新建一个子网,该文件中的所有容器会自动加入这个子网。
注意:文件名必须是
docker-compose.yaml,如果不是,构建命令需要一个额外参数。
构建命令
|
|
停止并删除容器
|
|
停止容器
|
|
启动容器
|
|
注意:以上命令都是对自动识别的
docker-compose.yaml文件中的容器进行的操作。