Docker 学习笔记
date
Apr 20, 2025
slug
Study-Notes-02
status
Published
tags
Docker
学习笔记
summary
Develop faster. Run anywhere.
type
Post
为什么用Docker
一种新兴的虚拟化方式。
传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而Docker容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。
Docker
对系统资源的利用率更高,不需要进行硬件虚拟以及运行完整操作系统等额外开销Docker
容器应用直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间Docker
的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性Docker
可以通过定制应用镜像来实现持续集成、持续交付、部署Docker
可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的,可以更轻松的迁移一些概念:
- 镜像(Image):可以将镜像视为软件打包的模板。
功能:镜像是一个只读的文件,其中包含了运行应用程序所需的一切,包括代码、运行时环境、依赖项和配置。
- 容器(Container):容器是基于镜像创建的一个运行实例。
工能:可以将容器视为镜像的运行时进程,它是一个隔离的环境,其中可以运行应用程序和服务。
镜像和容器关系的例子:
1. 莎士比亚心中的哈姆雷特就像是一个镜像,观众在看了这个戏剧之后,在自己心中就有了一个哈姆雷特,观众心中的哈姆雷特就是容器。
2. Python 中类和实例的关系,类是一个模板,实例是类的具体实现。
- 仓库(Repository):仓库是用于存储和组织镜像的地方。Docker Registry服务器专门用来存放仓库,一个 Docker Registry 中可以包含多个 仓库;每个仓库可以包含多个 标签;每个标签对应一个镜像。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。可以通过
<仓库名>:<标签>
的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest
作为默认标签。特性:每个容器都具有自己的文件系统、网络和进程空间,可以独立运行应用程序。

Docker安装
Linux安装教程(官方文档):https://docs.docker.com/engine/install/ubuntu/
版本选择
Docker Desktop 和 Docker Engine怎么选:
- 在有图形界面的系统中(Windows 或 macOS等),推荐使用:Docker Desktop;它集成 Docker Engine、Docker CLI、Docker Compose、Kubernetes(可选),以及一个图形化界面,适合 Windows 和 macOS 用户。
- 在没有图形界面的系统中(Linux),推荐使用:Docker Engine;
- Docker CE(Community Edition,社区版):开源免费
- Docker EE(Enterprise Edition,企业版,现已并入 Mirantis):商业付费
仓库安装(Ubuntu)
卸载旧的可能有冲突的包
存储在
/var/lib/docker/
中的映像、容器、卷和网络不会自动删除。如果您想从全新安装开始,并希望清理任何现有数据如果希望彻底卸载Docker Engine重新开始安装,则可以执行:
仓库配置
安装Docker
验证Docker
安装包安装
实操查找版本
以Ubuntu系统为例:
- 进入:https://download.docker.com/linux/ubuntu/ 这个网址,包含目录如下:
dists/
:- 这是 Docker APT 存储库的核心目录,包含了不同的 Ubuntu 版本和架构的文件包。
- 进入
dists/
目录后,你会看到各个 Ubuntu 发行版的名称,如bionic/
(Ubuntu 18.04)、focal/
(Ubuntu 20.04)、jammy/
(Ubuntu 22.04)等。 - 进一步进入每个发行版的目录,可以看到
stable/
、test/
等子目录,这些目录中包含了对应版本的 Docker Engine 及其相关组件的安装包。 gpg
:- 包含 Docker APT 仓库的 GPG 密钥,用于验证从这个仓库下载的软件包的真实性和完整性。安装 Docker 时,通常需要添加这个 GPG 密钥到系统中。
- 进入对应的系统(我的是
jammy/
(Ubuntu 22.04)),进入:https://download.docker.com/linux/ubuntu/dists/jammy/ 之后,目录包含如下 stable/
、test/
、nightly/
:- 这些是 Docker 的不同发布渠道(release channel)。每个目录中包含不同类型的 Docker 软件包。
stable/
:包含稳定版本的 Docker 软件包,适合生产环境使用。test/
:包含测试版的 Docker 软件包,用于开发者在发布正式版本之前测试新功能。nightly/
:包含每日构建版本,提供最新的功能和更新,但可能不稳定,仅用于实验和测试。- 通常,建议使用
stable/
版本,因为它是经过充分测试和验证的。 Release
、InRelease
、Release.gpg
:Release
:描述该发行版中可用软件包的元数据文件,包含每个软件包的版本信息、依赖关系等。InRelease
:包含了Release
文件的内容以及其 GPG 签名,提供了一种验证文件完整性和真实性的方式。Release.gpg
:是对Release
文件的独立 GPG 签名,用于确认文件的完整性和来源。pool/
:- 该目录包含了所有 Docker 包文件的实际存放位置,按软件包的名称进行组织。
- 包括
docker-ce
(Docker 社区版)、containerd.io
(容器运行时)等。 - 这些
.deb
文件可以直接下载,用于在没有网络连接的情况下进行离线安装。
- 进入
pool/
目录,选择稳定版stable/
, 然后选择系统架构类型 amd64/
:用于 64 位架构的包文件(也称为 x86_64 架构)。arm64/
:用于 ARM 架构的包文件。s390x/
:用于 IBM 系统 z 架构的包文件。
- 我Ubuntu是安装在Mac M1电脑上的,所以选择
arm64/
架构,进去之后包含以下类型文件: containerd.io
(必须):容器运行时,这是 Docker 引擎所依赖的组件。docker-ce
(必须):Docker 社区版的核心包,即 Docker 引擎。docker-ce-cli
(必须):Docker 命令行工具。docker-compose-plugin
(可选-推荐) ::用于多容器管理的插件。docker-buildx-plugin
(可选-推荐):用于多平台构建的插件。docker-ce-rootless-extras
(可选):用于支持 无特权(rootless)模式 的 Docker 运行。
选择合适的版本
- 推荐版本:20.10…
- 兼容性:选择与其他软件包兼容的版本。例如,
docker-ce
、docker-ce-cli
和containerd.io
通常需要保持版本兼容。如果选择docker-ce
的最新版本,也要选择与之匹配的docker-ce-cli
和containerd.io
版本。
开始安装(Ubuntu)
下载必需的 .deb 包
安装依赖包:将所有下载的 .deb 文件一起安装,以确保正确处理包的依赖关系:
如果在安装过程中遇到依赖问题,可以使用以下命令来解决:
然后重新运行
dpkg
命令:启动 Docker 并验证安装
遇到问题(Ubuntu)
- 运行测试镜像:
sudo docker run hello-world
- 报错:
- 原因:网络不能访问docker 的镜像源
- 方案1:配置国内镜像源
- 更改或新增配置文件:
vim /etc/docker/daemon.json
- 重启服务:
service docker restart
- 检查镜像源:
docker info|grep Mirrors -A 5
——匹配到"Mirrors"
的行后,再额外显示匹配行后面的 5 行内容(A
表示 "After")
- 方案2:去阿里云官方申请了镜像地址也加速失败
- 结果:更新完之后发现还是不行,网上一搜才知道是很多镜像源已经停止服务了(放弃)
开始安装(CentOS 7.9)
在这里下载的最新版的 docker 安装包,如果只下载几个会提示依赖问题
以上安装遇到 GPG 验证问题
- 手动下载 gpg 文件:https://download.docker.com/linux/centos/gpg
- 导入 gpg 密钥:
sudo rpm --import gpg
- 验证 gpg 密钥:
rpm -qa gpg-pubkey*
- 重新执行安装命令即可安装成功
启动设置
快速制作Python环境镜像
详细镜像制作过程见下文【镜像制作】
1、创建 Dockerfile 文件
2、构建镜像
3、导出与导入
4、从镜像创建容器
Python 镜像对比
版本名称 | 版本示例 | 版本大小 | 版本特点 | 适用场景 |
标准版 | python:3.9 | ~900MB | 基于 Debian Buster,包含完整的 Python 环境和常用工具(如 pip 、setuptools ),功能最全。 | 开发环境、测试环境,需要完整工具链的场景。 |
Slim 版 | python:3.9-slim | ~120MB | 基于 Debian Buster,仅包含 Python 运行所需的最小依赖,去除了非必要工具和文档,体积小。 | 生产环境,对镜像大小敏感的场景。 |
Alpine 版 | python:3.9-alpine | ~50MB | 基于 Alpine Linux,体积最小,但可能存在兼容性问题(如缺少 glibc)。 | 对镜像大小极度敏感的场景,且能接受潜在的兼容性调整。 |
Buster 版 | python:3.9-buster | ~900MB | 基于 Debian Buster,包含完整的系统工具链,适合需要兼容 Debian 的场景。 | 需要与 Debian 系统兼容的开发或生产环境。 |
Bullseye 版 | python:3.9-bullseye | ~900MB | 基于 Debian Bullseye,较新的 Debian 版本,包含更新的系统工具链。 | 需要较新 Debian 系统支持的场景。 |
Windowsservercore | python:3.9-windowsservercore | ~4GB | 基于 Windows Server Core,适用于 Windows 容器环境。 | 需要在 Windows 容器中运行 Python 的场景。 |
Nano Server | python:3.9-nanoserver | ~1GB | 基于 Windows Nano Server,体积较小,适用于轻量级 Windows 容器环境。 | ㅤ |
镜像操作
容器操作
创建容器
一个镜像可以用来创建多个容器,每个容器都是镜像的一个独立运行实例。
使用
docker run
创建并启动一个新容器时,所有指定的参数(如端口映射、卷挂载、环境变量等)都会被保存到该容器的配置中。在之后在使用 docker start
命令启动已经创建的容器时,不需要再次指定当利用
docker run
来创建容器时,Docker 在后台运行的标准操作包括:- 检查本地是否存在指定的镜像,不存在就从 registry 下载
- 利用镜像创建并启动一个容器
- 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
- 从地址池配置一个 ip 地址给容器
- 执行用户指定的应用程序
- 执行完毕后容器被终止
运行镜像生成容器后,通常有两种方式来操作容器内的内容:
- 容器开放一个访问端口,从浏览器访问
- 在容器内打开一个 bash shll,进行命令行操作
容器状态与启停
打包传输
文件形式
线上形式
Docker存储
数据存储在容器内部:
- 修改数据需要先进入容器内部,操作繁琐
- 容器崩溃后数据丢失
一般用来操作存储配置文件和数据
目录挂载
卷映射
卷映射其实也是一种挂载,只是在挂载的时候自动将 容器内需要挂载的文件夹中的内容 同步到服务器上的卷中。
只有在首次使用卷映射时,如果卷为空且容器目录中有数据,Docker 才会将容器目录中的数据复制到卷中。之后,卷中的数据就是独立存在的,挂载到任何容器都不会被初始目录覆盖。
Docker 网络
容器之间的网络数据访问
每个容器启动时会自动加入docker的自动网络docker0(在服务器的ip配置中能看到docker0网卡),这样在这些容器之间就组建了一个局域网,使用容器IP+容器端口就能互相访问了
但是docker0不支持容器主机域名,所以我们需要自己创建一个自定义网络,并将容器加入到这个网络中,这个网络能够支持容器主机域名(这样容器的名字就可以当成主机域名作为稳定的访问地址)
Docker Compose
容器批量管理工具,针对项目服务较多的工作;
命令式启动
以一个博客项目为例
Compose启动
compose主要通过操作
compose.yaml
文件来实现批量操作compose.yaml
配置文件的编写
语法规范详见:官方文档;
compose.yaml
文件配置
compose批量启动

制作镜像
Dockerfile文件
docker builder通过dockerfile文件的内容来制作镜像,所以制作镜像最主要的就是编写Dockerfile文件。
通常,
Dockerfile
的第一行是 FROM
指令,它定义了镜像的基础环境。然而,如果你的机器不能联网,那么不能直接从官方 Docker Hub 或其他在线仓库拉取基础镜像。解决这个问题的办法有以下几种:方法 1: 使用已有的本地基础镜像
方法 2: 离线获取基础镜像
- 在可联网的机器上拉取镜像
- 在联网机器上将镜像保存为
.tar
文件
- 将镜像传输到离线机器
- 在离线机器上加载镜像
方法 3:配置一个可用镜像源,阿里云主机可以参考这里配置
Dockerfile 中的指令是按顺序执行的,某些指令依赖于之前的指令的结果,所以编写时需要按照顺序编写。

Dockerfile文件配置参考
构建镜像
实操
官方前端案例:get started guide
- 克隆案例项目
- 创建项目镜像
- 创建Dockerfile文件
- 向文件内添加内容
# syntax=docker/dockerfile:1
:指定 docker 语法版本FROM node:18-alpine
:基于基础镜像node:18-alpine
WORKDIR /app
:设置了容器内的工作目录为/app
COPY . .
:将当前目录下的所有文件和文件夹复制到容器的工作目录/app
中RUN yarn install --production
:在工作路径下运行yarn install --production
安装依赖,根据package.json
文件安装CMD ["node", "src/index.js"]
:指定了容器启动时要执行的默认命令,将运行 Node.js,并执行src/index.js
文件。EXPOSE 3000
:将容器内的 3000 端口暴露给外部网络- 在终端创建镜像
- 由于指定了基础镜像,可能会下载一些依赖镜像层
t
表示指定镜像的名称和标签的组合,默认使用 "latest" 标签.
表示告诉Docker在当前目录下查找Dockerfile文件
内容解释
指令解读
创建时指定平台
- 运行镜像创建容器
docker run
:这是运行 Docker 容器的命令。dp 127.0.0.1:3000:3000
:这是用于设置容器的运行选项的部分。d
表示以后台(detached)模式运行容器,p
127.0.0.1:3000:3000 表示将主机的 127.0.0.1 的 3000 端口映射到容器的 3000 端口。getting-started
:这是指定要运行的 Docker 镜像的名称。
指令解读
查看运行结果:http://localhost:3000/
停止容器运行
- 更新项目内容,并重新制作镜像
- 修改项目文件:
src/static/js/app.js
第 56 行 - 重新构建镜像并实例化容器
删除旧容器
- 在 DockerHub 上分享镜像
- 在DockerHub上创建一个和项目文件夹同名仓库
getting-started
,并记住仓库名称前面的 Namespace 内容; - 为本地镜像添加一个标签,便签为
Namespace/getting-started
; - 将镜像推送到DockerHub仓库,推送用新添加的标签名
官方Python 案例:Containerize a Python application
- 克隆案例项目
- 初始化 Docker
会新增一些文件
- 构建并启动容器(在项目文件夹下运行)
- Docker Compose 是一个用于定义和管理多个 Docker 容器的工具;通过执行
docker compose up
,可以启动和管理定义在docker-compose.yml
文件中的一组容器。 - 指令将会读取当前目录下的
docker-compose.yml
文件,并根据其中定义的服务配置来启动容器。如果镜像不存在或具有更新,它将会在启动之前构建所需的镜像。 up
表示启动容器,-build
表示在启动之前构建镜像
指令解读
Python 案例 1 —— 强化学习(井字棋)
- 井字棋代码——from 刘建平
- 将文件放入一个空文件夹,并用pipreqs生成项目依赖文件
- 新建Dockerfile文件,文件内容如下
如果直接用python:3.11.3,则体积 900+M;Python官方镜像地址
- 构建镜像
- 运行镜像生成容器
程序会先训练模型 10 万次,然后会出现提示框,可以人机对弈;九宫格对应的按键位置为 qwe asd zxc
