Docker快速入门

Docker快速入门

2026年9月29日·#编程学习/javaweb学习笔记JavaWeb/Docker/部署·9277 字 46 分钟
浏览量加载中...
AI 摘要- DeepSeek

从第 19 章"在 Linux 里装 MySQL"那一长串命令讲起,说清 Docker 是什么(快速构建、运行、管理应用的工具),再看同一条 docker run 怎么把 MySQL 装起来——镜像与容器、镜像仓库 Docker Hub、Client 到 daemon 的结构图、镜像命名规范 repository:tag,以及 -d/--name/-p/-e 四个参数与端口映射,最后把本机实测的 Docker 环境与"国内拉镜像"的坑记下来

封面图
Docker快速入门 - 封面图

109 篇把 Tlias 搬上了 Linux 服务器:前端静态资源进了 nginx 的 html 目录,后端 jar 用 nohup 跑起来。但回头看那台服务器上的东西是怎么来的——108 篇里 JDK、MySQL、Nginx 是一样一样手工装上去的:光 MySQL 就是”卸 mariadb → 解压改名 → 配环境变量 → 注册系统服务 → 初始化 → 启动 → 改密码授权”一长串,一步错了还得从头查。

这一篇(PPT 第 1~21 页)要介绍的 Docker,就是来解决”装环境太累”这件事的。它是第 20 章(项目部署 Docker)的快速入门——第 1 页封面写着这一章的名字”项目部署(Docker)“,PPT 第 12、21 页那张目录页上写着这一章的三个部分:快速入门 / Docker核心 / 项目部署,本篇点亮第一张卡片(第 13 页那张”快速入门 01”的标题页就是它),后两块分别在 111 篇、112 篇、113 篇里。

PPT 页内容本篇对应小节
1封面——“项目部署(Docker)”开篇
2什么是 Docker(一句话定义)Docker 是什么
3~7Linux 中安装 MySQL 回顾(六屏命令:卸载 → 解压 → 环境变量 → 注册服务 → 初始化 → 启动改密码)先回顾一下
8同一屏命令的尾巴 + 三条吐槽(命令太多 / 步骤太多 / 安装包找不到)三条痛点
9“如何解决?”Docker 是什么
10“如何解决?“——一行 docker run + 拉取日志一条命令装 MySQL
11“Docker:快速构建、运行、管理应用的工具”Docker 是什么
12章节目录页(快速入门 / Docker核心 / 项目部署)开篇
13小节标题页——“快速入门 01”开篇
14安装 MySQL——完整命令 + 前置条件一条命令装 MySQL
15镜像和容器(概念 + 镜像仓库)镜像与容器
16镜像和容器(结构图:Client / daemon / Server / Registry)一张结构图
17问答页——镜像 / 容器 / 镜像仓库分别是什么三个问答
18命令解读(-d / --name / -p / -e / 镜像名)+ 端口映射示意命令解读
19镜像命名规范 [repository]:[tag]镜像命名规范
20问答页——docker run 常见参数 + 镜像名称结构第二张问答页
21章节目录页(讲完”快速入门”回到这里)小结

先回顾一下:在 Linux 里装一个 MySQL 有多累(PPT 第 3~8 页)#

PPT 第 3~8 页是第 19 章的”安装 MySQL 回顾”:六屏终端,把 108 篇里那一整套命令原样滚了一遍。它不是在教新东西,而是在铺痛点——所以这一段要连着看,看的不是命令本身,而是”一共要敲多少东西”。

PPT 页这一段在干什么关键命令(PPT 原文)
3查看并卸载系统自带的 mariadbrpm -qa | grep mysql、rpm -qa | grep mariadb、rpm -e --nodeps mariadb-libs-5.5.60-1.el7_5.x86_64
4上传安装包、解压缩、移动并改名tar -xvf mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz、mv mysql-8.0.30-linux-glibc2.12-x86_64 /usr/local/mysql、cd /usr/local/mysql
5配置环境变量、刷新、注册成系统服务vim /etc/profile、source /etc/profile、cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql、chkconfig --add mysql
6建用户组和用户、初始化数据库groupadd mysql、useradd -r -g mysql -s /bin/false mysql、mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
7启动服务、用临时密码登录、改密码systemctl start mysql、mysql -uroot -pxxxxx、ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '1234';
8第 7 页的尾巴(“后续省略”)——然后给出三条吐槽见下面三条痛点

MySQL 官网的下载页
图:PPT 第 3~8 页配的这张图是 MySQL 官网的下载页(dev.mysql.com/downloads/mysql)——“General Availability (GA) Releases”里要选 Linux - Generic、Linux - Generic (glibc 2.12) (x86, 64-bit),再从三个压缩包里挑出那个 586.5M 的 mysql-8.0.33-linux-glibc2.12-x86_64.tar.xz。PPT 第 8 页那句”安装包哪里下载,找不到”说的就是这一步:光把页面找对、把平台和包名选对,就够劝退一批人

六屏命令滚完,PPT 第 8 页把这一整套的”代价”总结成三句话(原文):

  • 命令太太太多,记不住
  • 步骤太太太多,易出错
  • 安装包哪里下载,找不到

这三句不是抱怨,是三条需求——后面的 Docker 就是冲着它们来的:

PPT 的吐槽手工装的实际情况Docker 想怎么解决
命令太多,记不住上面那张表里 15 条命令,还只是”装 MySQL”一件小事只有一条 docker run
步骤太多,易出错顺序还有讲究(不卸 mariadb 装不上、不 source 敲不到命令、不注册服务没法 systemctl)镜像里环境已经装好了,没有”中间步骤”可错
安装包找不到要自己去官网翻版本、选平台、下几百 MB 的包再传上去从镜像仓库拉现成的,一条命令自动下载

Docker 是什么(PPT 第 2、9、11 页)#

PPT 第 2 页在封面之后第一页就给了定义,第 11 页又原样重复了一遍:

Docker 就是一款快速构建、运行、管理应用的工具。

第 9 页则只有两个字——“如何解决?“:前面刚铺完三条痛点,这一页就是转折点,答案在第 10、11 页。这句定义里的三个动词,正好对应三条痛点:

动词说的是什么对应哪条痛点
构建把”应用 + 它需要的运行环境、配置、函数库”打成一个包(镜像)安装包找不到——包由别人做好、放在仓库里
运行把这个包在机器上跑起来,变成一个容器步骤太多——没有解压、配环境变量、注册服务这些中间步骤
管理起停、看日志、进容器、删掉重来命令太多——一套统一的 docker xxx 命令,所有软件都长一个样

一句话记住区别:以前是”往机器上装软件”,现在是”把装好的软件搬过来跑”。

Tip

Docker 本身也要先装上:PPT 第 14 页的前提里写着”确保你的虚拟机已经安装 Docker,且网络开通”。Windows / macOS 上装的就是本篇实测用的 Docker Desktop(一个带界面的安装包,装完 docker 命令就有了),Linux 服务器上装的是 Docker Engine——两种装法都能得到同一套命令。本机这台 Docker Desktop 是早就装好的,本轮没有走安装流程(见后面的实测一节)。

一条命令装 MySQL(PPT 第 10、14 页)#

PPT 第 10 页把两条路并排放:左边是第 3~8 页那六屏命令,右边只有一行:

Terminal window
docker run -d --name mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123 mysql:8

第 14 页把这条命令写成更清楚的多行续行形式(\ 表示”这条命令还没完,下一行接着”),并给了前置条件:

先停掉虚拟机中的 MySQL,确保你的虚拟机已经安装 Docker,且网络开通的情况下,执行下面命令即可安装 MySQL:

Terminal window
docker run -d \
--name mysql \
-p 3307:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
mysql:8

为什么先停掉机器上原来那个 MySQL:这条命令把容器里的 3306 映射到了宿主机的 3307,端口上其实不冲突;课程让先停,是为了不搞混”现在连的到底是哪一个 MySQL”——原来的还开着,3306 上跑的是第 19 章手工装的那个,查问题时会分不清。停掉之后,这台机器上的 MySQL 就只剩容器里这一个了(本机实测的对应事实:容器和宿主机的端口是两套,下面”命令解读”一节细说)。

第 10 页还附了这条命令真正跑起来时的拉取日志(原文):

Unable to find image 'mysql:latest' locally
latest: Pulling from library/mysql
72a69066d2fe: Pull complete
93619dbc5b36: Pull complete
99da31dd6142: Pull complete
626033c43d70: Pull complete
Status: Downloaded newer image for mysql:latest
a6cec8ff4765ca0876d0453f3ccab205fca29b5dce74f8cfbad8d76571bf79be

这几行的意思,一行一行对:

日志行它在说什么
Unable to find image 'mysql:latest' locally本地没有这个镜像,准备去仓库拉
latest: Pulling from library/mysql正在从 library/mysql(Docker Hub 官方命名空间)拉取
72a69066d2fe: Pull complete …镜像分层下载,每层一行(“层”的概念在 112 篇细讲)
Status: Downloaded newer image for mysql:latest下载完成
a6cec8ff4765…最后这串十六进制是 docker run 打印的容器 ID——容器已经跑起来了
Note

日志里写的是 mysql:latest,而命令里写的是 mysql:8——因为这份日志是没带 tag 的那次运行留下的:不写版本号时默认就是 latest(PPT 第 19 页那句话的实例)。看到 latest 不用奇怪,它就是”最新版”的意思。

和 108 篇那套手工流程一比,差别是全方位的:

环节手工装(108 篇)Docker
找安装包去官网翻版本、选平台、下几百 MB 的包再上传不用找——镜像仓库里有现成的,docker run 时自动下载
安装解压 → 配环境变量 → 注册系统服务 → 建用户 → 初始化(十几条命令)一条 docker run
启动 / 停止systemctl start/stop mysqldocker start/stop mysql
卸载rpm -e + 删目录 + 清配置,还可能卸不干净docker rm 一条(111 篇)
换版本整套流程重来一遍把 mysql:8 换成别的 tag 再来一条
装第二个软件又是一套全新的步骤(nginx 是源码编译,JDK 是解压)还是 docker run,只是镜像名换掉

镜像与容器(PPT 第 15、16 页)#

第 15 页和第 16 页是同一段文字的两次出现(第 16 页多了结构图),原文把三个概念一次说清:

当我们利用 Docker 安装应用时,Docker 会自动搜索并下载应用镜像(image)。镜像不仅包含应用本身,还包含应用运行所需要的环境、配置、系统函数库。Docker 会在运行镜像时创建一个隔离环境,称为容器(container)。

镜像仓库:存储和管理镜像的平台,Docker 官方维护了一个公共仓库:Docker Hub。

先看”镜像里到底装了什么”——第 15 页把镜像拆成四块:

镜像里装的举例(还是拿 MySQL 说)为什么必须有
应用软件MySQL 本身这是我们要的东西
运行环境MySQL 依赖的 glibc 等系统库手工装时”平台选错、版本对不上”就出在这儿
配置文件MySQL 的默认配置装完能直接启动,不用先改配置
函数库各种依赖库手工装时”缺依赖”要自己补,镜像里已经齐了

再看”容器”:镜像是一份”死的”文件包,容器是它”跑起来”之后的那个隔离环境。同一个镜像可以跑出好几个容器(各自独立、互不干扰)。两个类比:

类比对应
安装包(.exe / .tar.gz)镜像
装好并正在运行的程序容器
下载站 / 应用商店镜像仓库

一张结构图(PPT 第 16 页)#

Docker 的整体结构
图:PPT 第 16 页的结构图——左边是 Client(我们敲命令的地方),中间是 DOCKER_HOST(里面跑着 docker daemon 守护进程,下面挂着 Containers 容器和 Images 本地镜像),右边是 Registry 镜像仓库(图上画着 Ubuntu、MySQL、NGINX 这些现成的镜像)。箭头就是数据流向:docker pull 把镜像从仓库拉到本地,docker run 拿本地镜像创建容器,docker build 则从 Dockerfile 造出一个新镜像(112 篇)

这张图按角色拆开看:

图上的框是什么我们和它的关系
ClientDocker 客户端——就是终端里那个 docker 命令我们敲的 docker run / docker pull / docker build 都是它在发指令
docker daemon(守护进程)真正干活的后台进程(装好 Docker 后一直在跑)我们看不见它,命令都发给它执行;docker info 里的 “Server” 就是它
Images(本地镜像)已经拉到这台机器上的镜像docker images 能列出来(111 篇)
Containers(容器)由镜像跑出来的隔离环境docker ps 看运行中的容器
Registry(镜像仓库)存镜像的地方,最大的是 Docker Hubdocker pull 从它下载、docker push 往它上传

三个问答(PPT 第 17 页)#

第 17 页是这一节的问答页,三个问题正好是上面三个概念的”考试版答案”,原文如下:

  1. 什么是镜像? 将应用所需的运行环境、配置文件、系统函数库等与应用一起打包得到的就是镜像
  2. 什么是容器? 为每个镜像的应用进程创建的隔离运行环境就是容器
  3. 什么是镜像仓库? 存储和管理镜像的平台就是镜像仓库 DockerHub 是目前最大的镜像仓库,其中包含各种常见的应用镜像

三个答案里最值得抠的是容器那一句的”每个……隔离”:一个镜像可以起多个容器,每个容器有自己独立的文件系统、进程、网络,互不干扰——所以同一台机器上可以同时跑两个 MySQL 容器(用不同端口映射出去),也可以一个容器坏了直接删掉重建,不影响别的。

命令解读:docker run 的四个参数(PPT 第 18 页)#

第 18 页把第 14 页那条命令拆开逐段解释,原文如下:

  • docker run:创建并运行一个容器,-d 是让容器在后台运行
  • --name mysql:给容器起个名字,必须唯一
  • -p 3307:3306:设置端口映射
  • -e KEY=VALUE:是设置环境变量
  • mysql:8:指定运行的镜像的名字,版本

逐条展开:

参数写法作用细节
docker rundocker run [参数] 镜像名创建并运行一个容器它 = 创建容器 + 启动容器 两步合一
-d-d让容器在后台运行(detached)不加它,容器会把终端”占住”、日志直接打在屏幕上,按 Ctrl+C 就退了
--name--name mysql给容器起个名字必须唯一——已经有一个叫 mysql 的容器时,再起同名会报冲突;有了名字后面才能用 docker stop mysql 这种”按名字操作”
-p-p 3307:3306端口映射:宿主机端口:容器端口左边是宿主机的、右边是容器里的,顺序不能反(下面细说)
-e-e TZ=Asia/Shanghai、-e MYSQL_ROOT_PASSWORD=123设置环境变量给容器里的程序传配置;能传哪些是镜像规定的(MySQL 镜像认 MYSQL_ROOT_PASSWORD,nginx 镜像就不认)
(镜像名)mysql:8指定运行的镜像名字 + 版本本地没有会自动去仓库拉(第 10 页那段日志)

端口映射是怎么回事(PPT 第 18 页的示意图)#

第 18 页右侧画了一张端口映射的示意图,信息量都在上面:

宿主机 192.168.100.128 容器(隔离环境)
┌──────────────────┐ ┌──────────────────┐
│ 端口 3307 │ ──── 映射 ────► │ 端口 3306 │
└──────────────────┘ │ (MySQL 在里面)│
└──────────────────┘
项目里连数据库写的是:
jdbc:mysql://192.168.100.128:3307 ← 宿主机 IP + 宿主机端口
  • 为什么要映射:容器是隔离的,它的 3306 只活在容器自己的网络里,外面的机器根本看不见。-p 3307:3306 就是在宿主机上开一个 3307 的口子,所有发给”宿主机 3307”的流量都转进容器的 3306。
  • 为什么左边写 3307:因为宿主机的 3306 通常留给”机器上原来那个 MySQL”(或者留给以后别的容器)——一个端口只能被一个东西占用,把容器映射到 3307 就互不打架了。
  • 连接串怎么写:PPT 第 18 页写得很清楚——jdbc:mysql://192.168.100.128:3307。写的是宿主机的 IP 和宿主机的端口,不是 3306、也不是容器的 IP。项目在宿主机上跑(或从 Windows 连服务器)时,走的就是这条映射通道。
  • 顺序记法:-p 宿主机:容器——“外面 : 里面”,和 109 篇 nginx 反向代理”外面 80 → 里面 8080”是同一个思路。

-e 的两条环境变量#

第 14 页的命令里给了两条 -e,一条是时区、一条是密码:

环境变量值为什么要有它
TZ=Asia/Shanghai上海时区容器默认是 UTC 时间,日志、now() 会差 8 小时——写库时间对不上时先想它
MYSQL_ROOT_PASSWORD=123root 的初始密码MySQL 镜像第一次启动时会用这个值设 root 密码;不给它,MySQL 8 镜像会拒绝启动

这也解释了 -e 的意义:镜像把”可配置的东西”留成了环境变量,用 -e 在启动时传进去——不传就用默认值(或者像 MYSQL_ROOT_PASSWORD 这样必须传)。想知道某个镜像支持哪些 -e,看它在 Docker Hub 上的说明页(PPT 第 32 页的 MySQL 案例就标注了”官方文档”)。

镜像命名规范(PPT 第 19 页)#

第 19 页只有一条规则:

镜像名称一般分两部分组成:[repository]:[tag]。 其中 repository 就是镜像名,tag 是镜像的版本。 在没有指定 tag 时,默认是 latest,代表最新版本的镜像。

拿 mysql:8 拆开看:

部分值含义
repositorymysql镜像名(官方镜像直接用软件名)
分隔符:名字和版本之间用冒号
tag8版本号——同一个镜像的不同版本用 tag 区分(mysql:5.7、mysql:8.0.30…)

三个要点:

  1. 不写 tag 就是 latest:docker run mysql 等价于 docker run mysql:latest——第 10 页那份日志里的 mysql:latest 就是这么来的。
  2. tag 决定”装哪个版本”:课程统一用 mysql:8(大版本 8)。换 tag 就是换版本,这是 Docker 比手工装省事的地方之一。
  3. 完整写法其实还能更长(前面带仓库地址、命名空间,比如本机实测里那些 docker.m.daocloud.io/library/alpine)——课程里只讲 [repository]:[tag] 两段,够用了。

第二张问答页(PPT 第 20 页)#

第 20 页是这一节的收尾问答,把前面所有知识点压成两行,原文如下:

docker run 命令中的常见参数: -d:让容器后台运行 --name:给容器命名,唯一 -e:环境变量 -p:宿主机端口映射到容器内端口

镜像名称结构:Repository:TAG 镜像名 / 版本号

这张页就是”这一节要背下来的两件事”:

要记住的内容用的时候
docker run 四个参数-d 后台、--name 命名(唯一)、-e 环境变量、-p 宿主机端口:容器端口起任何容器都是这套(111 篇的 nginx、113 篇的部署)
镜像名称结构Repository:TAG(镜像名 + 版本号),不写 TAG 默认 latest认镜像名、换版本

本机实测:Docker 环境与”拉镜像”的坑#

Important

这一节是本机实测(Docker Desktop 29.1.3)——本机装了 Docker Desktop(Windows 版),实验期间启动过它、跑过容器,实验完成后已经关掉并把实验产物清干净了。下面这些输出都是当时记下来的。

先看环境(docker --version / docker compose version / docker info):

$ docker --version
Docker version 29.1.3
$ docker compose version
Docker Compose version v2.40.3-desktop.1
$ docker info(关键字段)
Server: 29.1.3
产品: Docker Desktop
Docker Root Dir: /var/lib/docker
Registry Mirrors: [] ← 没配镜像加速

然后踩到了本篇最值得记的一个坑——用”裸名”去拉官方镜像会失败:

$ docker run -d --name demo alpine sleep 300
Unable to find image 'alpine:latest' locally
docker: Error response from daemon: failed to resolve reference "docker.io/library/alpine:latest":
failed to authorize: ... Get "https://auth.docker.io/token?...": EOF

报错的意思是:本地没有 alpine 这个镜像,于是去 docker.io(Docker Hub)拉,但连不上它的认证服务(auth.docker.io 请求直接 EOF)。docker info 里那句 Registry Mirrors: [] 就是原因——没配国内镜像加速,直连 Docker Hub 在我们这边经常是连不上的。

解决办法有两条(笔记里按课程写 docker pull mysql:8 这种标准写法,在国内环境要照下面改一下):

办法怎么做效果
① 配镜像加速在 Docker Desktop 的设置里加 Registry Mirror(或改 daemon 的 registry-mirrors),之后原来的命令原样可用Registry Mirrors 不再是空的,docker pull mysql:8 走加速站
② 用带国内源前缀的镜像名把 mysql:8 写成 docker.m.daocloud.io/library/mysql:8 这种形式不用改配置,命令里把镜像名换掉就行

本机当时走的是第 ② 条——docker images 里那些镜像名都带着前缀,就是这么来的(本机实测):

$ docker images
REPOSITORY TAG SIZE
docker.m.daocloud.io/library/alpine latest 13MB
docker.m.daocloud.io/library/mongo 7 1.18GB

注意这两个名字的结构:docker.m.daocloud.io(仓库地址)+ library(命名空间,官方镜像都在 library 下)+ alpine(镜像名)+ latest(tag)——正好是上面”镜像命名规范”那条规则的完整形态。本机的 alpine 镜像也正是 111 篇 里做容器、数据卷实验时用的”零下载”底座。

Warning

看到 failed to authorize ... EOF 这类报错,先别怀疑命令写错了——多半是网络到 Docker Hub 不通。判断方法:docker info 看 Registry Mirrors 是不是空的;验证方法:用带前缀的镜像名再拉一次(本机实测同一个 alpine 带前缀就能用)。课程 PPT 里的 docker run … mysql:8、docker pull nginx 都是”网络畅通时的标准写法”。

小结#

问题答案
Docker 是什么?一款快速构建、运行、管理应用的工具(PPT 第 2、11 页原话)
它解决什么痛点?手工装软件”命令太多记不住、步骤太多易出错、安装包找不到”(PPT 第 8 页)
镜像是什么?把应用和它的运行环境、配置、系统函数库一起打包得到的文件包(PPT 第 15、17 页)
容器是什么?运行镜像时创建的隔离运行环境,为每个镜像的应用进程各建一个(PPT 第 15、17 页)
镜像仓库是什么?存储和管理镜像的平台;Docker Hub 是目前最大的公共仓库(PPT 第 17 页)
结构图上都有谁?Client(敲命令)→ docker daemon(干活)→ 本地 Images / Containers,另一头是 Registry(PPT 第 16 页)
镜像名怎么写?[repository]:[tag],如 mysql:8;不写 tag 默认 latest(PPT 第 19 页)
docker run 四个参数?-d 后台运行、--name 命名(唯一)、-p 宿主机端口:容器端口、-e KEY=VALUE 环境变量(PPT 第 18、20 页)
-p 3307:3306 什么意思?把宿主机的 3307 映射到容器里的 3306;项目里连它写 jdbc:mysql://宿主机IP:3307(PPT 第 18 页)
一条命令装 MySQL 是什么?docker run -d --name mysql -p 3307:3306 -e TZ=Asia/Shanghai -e MYSQL_ROOT_PASSWORD=123 mysql:8(PPT 第 14 页)
为什么装之前要先停掉机器上的 MySQL?避免”连的到底是哪一个”搞混——容器那一个映射在 3307,和机器上原来的 3306 是两回事
本机实测记下了什么?Docker Desktop 29.1.3(Compose v2.40.3);没配镜像加速时裸名拉镜像报 failed to authorize ... EOF,带前缀的镜像名(docker.m.daocloud.io/library/xxx)可用

相关#

练习题#

一、知识回顾(读完直接做下面的实践题)#

  1. Docker 是什么:一款快速构建、运行、管理应用的工具(PPT 第 2、11 页)——构建是把应用和环境打成镜像、运行是把镜像跑成容器、管理是起停删看日志
  2. 它冲着哪三条痛点来的(PPT 第 8 页):命令太太太多记不住、步骤太太太多易出错、安装包哪里下载找不到——分别对应”一条 docker run”、“环境已在镜像里”、“从镜像仓库拉现成的”
  3. 镜像是什么:把应用本身 + 运行环境 + 配置 + 系统函数库一起打包得到的文件包(PPT 第 15、17 页)
  4. 容器是什么:运行镜像时创建的隔离运行环境,为每个镜像的应用进程各建一个——同一个镜像能起多个互不干扰的容器(PPT 第 15、17 页)
  5. 镜像仓库是什么:存储和管理镜像的平台;Docker Hub 是最大的公共仓库(PPT 第 17 页)
  6. 结构图上的四个角色:Client(敲 docker run/pull/build 的地方)→ docker daemon(守护进程,真正干活)→ 本地 Images 与 Containers;另一头 Registry 镜像仓库(PPT 第 16 页)
  7. 镜像命名规范:[repository]:[tag],如 mysql:8——repository 是镜像名、tag 是版本;不写 tag 默认 latest(PPT 第 19 页)
  8. docker run 四个参数:-d 让容器后台运行、--name 给容器命名(必须唯一)、-p 设置端口映射(宿主机端口:容器端口)、-e KEY=VALUE 设置环境变量(PPT 第 18、20 页)
  9. 端口映射怎么理解:容器是隔离的,外面看不见它的 3306;-p 3307:3306 把宿主机的 3307 转到容器的 3306,项目里连数据库写 jdbc:mysql://192.168.100.128:3307——宿主机 IP + 宿主机端口(PPT 第 18 页)
  10. 装 MySQL 的那条命令 + 前置条件:docker run -d --name mysql -p 3307:3306 -e TZ=Asia/Shanghai -e MYSQL_ROOT_PASSWORD=123 mysql:8;前置是”先停掉机器上原来的 MySQL、装好 Docker、网络开通”(PPT 第 14 页)。TZ 管时区,MYSQL_ROOT_PASSWORD 是 MySQL 镜像要求的初始 root 密码
  11. 本机实测(Docker Desktop 29.1.3):docker --version → 29.1.3、Compose → v2.40.3;docker info 里 Registry Mirrors: [](没配加速);裸名拉镜像报 failed to authorize ... EOF;带前缀的镜像名 docker.m.daocloud.io/library/xxx 可以正常用

二、裸写题#

  • 2-1 用一条命令把 MySQL 跑起来 需求:一台装好 Docker、能联网的 Linux 服务器(IP 192.168.100.128)。要求用一条命令起一个 MySQL 容器:后台运行、容器名叫 mysql、用 mysql:8 这个镜像、时区设成上海、root 初始密码设成 123,并且让服务器外面的机器能连上这个数据库(映射到宿主机的 3307)。 素材:容器里的 MySQL 监听 3306;服务器上原来装的 MySQL 要先停掉。

    提示(先自己想,实在想不出再点开)

    一级 · 思路:四个参数各管一件事——后台、名字、端口、环境变量,最后跟上镜像名;顺序是”命令 → 参数 → 镜像名” 二级 · 方法:docker run -d --name … -p 宿主机端口:容器端口 -e KEY=VALUE 镜像名:tag;端口映射左外右内(宿主机 3307 → 容器 3306);两条 -e 分别是 TZ=Asia/Shanghai 与 MYSQL_ROOT_PASSWORD=123 三级 · 骨架:docker run -____ --____ mysql -p ____:____ -e TZ=____ -e MYSQL_ROOT_PASSWORD=____ mysql:____

    参考答案(做完再点开)
    Terminal window
    docker run -d \
    --name mysql \
    -p 3307:3306 \
    -e TZ=Asia/Shanghai \
    -e MYSQL_ROOT_PASSWORD=123 \
    mysql:8

    逐段对号:-d 后台运行;--name mysql 容器名(唯一);-p 3307:3306 宿主机的 3307 映射到容器里的 3306;-e TZ=Asia/Shanghai 时区;-e MYSQL_ROOT_PASSWORD=123 root 初始密码;mysql:8 镜像名与版本。 验证:docker ps 能看到 mysql 容器在运行、PORTS 列显示 0.0.0.0:3307->3306/tcp;在别的机器上用客户端连 192.168.100.128:3307,用户名 root、密码 123。 注意:① 顺序是 宿主机:容器,写反了就连不上;② 名字重复会报冲突(先 docker ps -a 看看有没有同名容器);③ 不写 tag 就是 latest,课程统一用 mysql:8。

  • 2-2 读懂别人写的一条命令 需求:同事给了你一条命令,让你说清它干了什么: docker run -d --name nginx -p 80:80 -e TZ=Asia/Shanghai nginx:1.20.2 请回答:① 这条命令要起什么、起完之后容器叫什么名字;② -p 80:80 两边的 80 分别是谁的端口、为什么这次两边可以写成一样;③ -e TZ=Asia/Shanghai 有什么用;④ 如果本地没有 nginx:1.20.2 这个镜像,Docker 会做什么;⑤ 命令跑完之后,用哪条命令能确认容器在运行。

    提示(先自己想,实在想不出再点开)

    一级 · 思路:把命令拆成”命令本体 + 参数 + 镜像名”三块,参数一个一个对号;“本地没有镜像”这件事想一想第 10 页那份拉取日志 二级 · 方法:-d 后台、--name 名字、-p 宿主机:容器、-e 环境变量、镜像名:tag;本地没有镜像时 Docker 会自动去镜像仓库搜索并下载;查看运行中容器用 docker ps 三级 · 骨架:① 起的是 ____ 应用、容器名 ____;② 左边 80 是 ____ 的、右边 80 是 ____ 的,两边相同是因为 ____;③ -e 设置的是 ____;④ 本地没有镜像时 Docker 会去 ____ 下载;⑤ 确认命令是 docker ____

    参考答案(做完再点开)

    ① 起的是 nginx(Web 服务器);容器名字叫 nginx(--name nginx)。 ② -p 80:80 是”宿主机 80 : 容器 80”:左边是服务器对外开的端口,右边是容器里 nginx 真正监听的端口。两边都写 80 是因为宿主机的 80 正好空着(没有被别的程序占用)——如果宿主机 80 被占了(比如 109 篇里那个装在机器上的 nginx 还在跑),就要改成 -p 90:80 之类,左边随便换、右边不能动(右边由镜像里的程序决定)。 ③ -e TZ=Asia/Shanghai 把容器里的时区设成上海,避免日志时间差 8 小时。 ④ 本地没有这个镜像时,Docker 自动去镜像仓库(默认 Docker Hub)搜索并下载,下载完再创建容器——就像第 10 页日志里的 Unable to find image … locally → Pulling → Downloaded。 ⑤ docker ps(PORTS 列会显示 0.0.0.0:80->80/tcp)。 补充:这条命令里的容器名、镜像名、端口都是”起容器的人自己定的”,只有 -p 右边那个 80 是镜像里的 nginx 决定的。

  • 2-3 镜像名里每一段是什么意思 需求:说出下面三个镜像名各自的 repository 和 tag,并说明它们分别会装到哪个版本: ① mysql:8 ② mysql ③ docker.m.daocloud.io/library/alpine:latest 然后回答:本机(Registry Mirrors: [])里用第 ② 种写法拉镜像会报什么错、为什么,两条解决办法分别是什么。

    提示(先自己想,实在想不出再点开)

    一级 · 思路:先按 [repository]:[tag] 切两段;再想”不写 tag 会怎样”;最后把”拉不到镜像”归到网络到镜像仓库不通这件事上 二级 · 方法:[repository]:[tag],不写 tag 默认 latest;本机没配 Registry Mirror 时直连 auth.docker.io 会失败(failed to authorize ... EOF);办法是配镜像加速或用带国内源前缀的镜像名 三级 · 骨架:① mysql:8 → 镜像名 ____、版本 ;② mysql → 等价于 mysql:____;③ 完整形式是”仓库地址//镜像名”;④ 报错原文 failed to ____ ... EOF,原因是没配 ____

    参考答案(做完再点开)

    ① mysql:8:repository = mysql、tag = 8,装 MySQL 的 8.x 版本。 ② mysql:没写 tag,等价于 mysql:latest(最新版)——第 10 页日志里的 mysql:latest 就是这么来的。 ③ docker.m.daocloud.io/library/alpine:latest:这是完整形式——docker.m.daocloud.io 是仓库地址(国内源)、library 是命名空间(官方镜像都在它下面)、alpine 是镜像名、latest 是 tag。 拉不到镜像的部分:报错形如

    docker: Error response from daemon: failed to resolve reference "docker.io/library/alpine:latest":
    failed to authorize: ... Get "https://auth.docker.io/token?...": EOF

    原因是没配镜像加速(docker info 里 Registry Mirrors: []),直连 Docker Hub 的认证服务不通。 两条办法:① 配 Registry Mirror(Docker Desktop 设置里加镜像加速地址),之后命令原样可用;② 用带国内源前缀的镜像名(如 docker.m.daocloud.io/library/mysql:8),不改配置、只改镜像名。

  • 2-4 找出这条命令里的问题 需求:小明照着 PPT 敲了下面这条命令,结果容器没起来。请逐条指出问题并给出正确写法(一共 4 处): docker run --name mysql -d -p 3306:3307 -e MYSQL_ROOT_PASSWORD 123 mysql:8 (他想要的是:后台运行的 MySQL 容器、名字叫 mysql、外面的 3307 连到容器里的 3306、root 密码 123。)

    提示(先自己想,实在想不出再点开)

    一级 · 思路:一处一处对”他想要的”和”他写的”——名字、后台、端口方向、环境变量的写法 二级 · 方法:-p 是”宿主机:容器”;-e 是”KEY=VALUE”,等号不能少、中间不能有空格 三级 · 骨架:① 端口顺序应为 -p ____:____;② -e 要写成 -e MYSQL_ROOT_PASSWORD=____;③ 检查容器名是否与已有容器 ____;④ 别忘了镜像名后面的 ____

    参考答案(做完再点开)

    问题(对照”他想要的”): ① 端口映射写反了:-p 3306:3307 是”宿主机 3306 → 容器 3307”,而他要的是外面 3307 连到容器里的 3306,应写 -p 3307:3306(左外右内)。写反的后果:连 3307 连不上,而且宿主机 3306 上如果还跑着老 MySQL 会直接冲突。 ② -e 少写了等号:-e MYSQL_ROOT_PASSWORD 123 会被当成”环境变量 MYSQL_ROOT_PASSWORD(值为空)+ 一个多余的参数”,必须写 -e MYSQL_ROOT_PASSWORD=123。 ③ 名字可能冲突:--name 必须唯一,如果之前已经有个叫 mysql 的容器(哪怕是停止状态的),这条会报冲突——先 docker ps -a 查,有就先 docker rm 掉或者换个名字。 ④ mysql:8 只写了镜像名和 tag——这条本身没错(不写 tag 默认 latest),但课程统一写 mysql:8 更稳;真正容易漏的是镜像名必须放在最后(参数写完后跟镜像名),顺序写错 Docker 会把它当成参数。 正确写法:

    Terminal window
    docker run -d --name mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123 mysql:8

    起完验证:docker ps 看状态与 PORTS;再看一眼容器里 MySQL 的日志 docker logs mysql(111 篇)。

三、综合题#

  • 3-1 给新同事写一份”用 Docker 起 MySQL”的交接说明 需求:新同事的电脑上已经装好 Docker Desktop,现在要在一台 Linux 服务器(192.168.100.128)上把 MySQL 跑起来,给开发环境用。请写一份可以照着做的说明,要求包含:

    1. 先交代背景:为什么不用 108 篇那套手工装法(把 PPT 第 8 页的三条痛点写进去);
    2. 起容器:写出完整命令,并说明每个参数在干什么(后台、名字、端口、两条环境变量、镜像名);
    3. 说清端口:为什么映射到 3307 而不是 3306,以及连接串应该怎么写;
    4. 验证:至少写出两条”确认它真的起来了”的办法(一条看容器状态、一条看日志或连接);
    5. 万一拉不到镜像:把本机实测那个坑(报错原文 + 两条解决办法)写进去。
    6. 最后用一张小表把”手工装 vs Docker 装”的差别列出来(找包、安装、启停、卸载、换版本)。
    提示(先自己想,实在想不出再点开)

    一级 · 思路:这份说明要能”从零照着做通”——所以顺序是”为什么 → 怎么做(命令+参数)→ 怎么连(端口与连接串)→ 怎么确认 → 出问题怎么办” 二级 · 方法:命令用 docker run -d --name mysql -p 3307:3306 -e TZ=Asia/Shanghai -e MYSQL_ROOT_PASSWORD=123 mysql:8;验证用 docker ps 和 docker logs mysql(或在别的机器上用客户端连 192.168.100.128:3307);拉不到镜像时要么配 Registry Mirror、要么把镜像名换成带前缀的形式 三级 · 骨架:① 三条痛点:命令多 / 步骤多 / 包难找;② 命令五段(-d、--name、-p、-e×2、镜像名);③ 连接串 jdbc:mysql://____:____;④ 验证 docker ____ + docker ____ mysql;⑤ 报错 failed to ____ ... EOF → 配加速或换 ____ 名

    参考答案(做完再点开)
    【用 Docker 起一个 MySQL(开发环境)】
    一、为什么不用手工装
    第 19 章那套手工装法的三条代价(PPT 第 8 页):
    · 命令太太太多,记不住(卸载→解压→环境变量→注册服务→初始化→授权,十几条)
    · 步骤太太太多,易出错(顺序还有讲究,漏一步就卡住)
    · 安装包哪里下载,找不到(官网翻版本、选平台、几百 MB)
    Docker 的做法:环境已经装在镜像里,一条命令起容器。
    二、起容器(服务器上执行,先确认机器上原来的 MySQL 已停掉)
    docker run -d \
    --name mysql \
    -p 3307:3306 \
    -e TZ=Asia/Shanghai \
    -e MYSQL_ROOT_PASSWORD=123 \
    mysql:8
    参数对号:
    docker run 创建并运行一个容器
    -d 后台运行(不占终端)
    --name mysql 容器名,必须唯一(后面 docker stop mysql 靠它)
    -p 3307:3306 宿主机 3307 → 容器 3306(左外右内)
    -e TZ=… 时区(不然日志和 now() 差 8 小时)
    -e MYSQL_ROOT_PASSWORD=123 MySQL 镜像要求的 root 初始密码
    mysql:8 镜像名:版本(本地没有会自动去仓库拉)
    三、端口与连接串
    容器的 3306 是隔离的、外面看不见,所以映射到宿主机 3307:
    · 宿主机上原来的 MySQL 占用 3306,映射 3307 互不打架
    · 项目/客户端连它写:jdbc:mysql://192.168.100.128:3307
    (宿主机 IP + 宿主机端口,不是 3306、也不是容器的 IP)
    四、验证
    docker ps → 状态 Up,PORTS 显示 0.0.0.0:3307->3306/tcp
    docker logs mysql → 看 MySQL 启动日志([111 篇])
    别的机器用客户端连 192.168.100.128:3307(root / 123)→ 能连上就成
    五、拉不到镜像怎么办(本机实测的坑)
    报错:
    docker: Error response from daemon: failed to resolve reference
    "docker.io/library/mysql:8": failed to authorize: … EOF
    原因:没配镜像加速(docker info 里 Registry Mirrors 为空),连不上 Docker Hub。
    办法①:在 Docker 设置里加 Registry Mirror,命令原样可用;
    办法②:把镜像名换成带国内源前缀的写法(如 docker.m.daocloud.io/library/mysql:8)。
    六、手工装 vs Docker 装
    ┌────────┬──────────────────────────┬───────────────────────┐
    │ 环节 │ 手工装(108 篇) │ Docker │
    ├────────┼──────────────────────────┼───────────────────────┤
    │ 找包 │ 官网翻版本、选平台、上传 │ 从镜像仓库自动拉 │
    │ 安装 │ 十几条命令 │ 一条 docker run │
    │ 启停 │ systemctl start/stop │ docker start/stop │
    │ 卸载 │ rpm -e + 删目录 + 清配置 │ docker rm │
    │ 换版本 │ 整套重来 │ 换 tag 再来一条 │
    └────────┴──────────────────────────┴───────────────────────┘

    检查点:① 三条痛点写全;② 命令里五个参数一个不少、端口方向对;③ 连接串写的是宿主机 IP + 3307;④ 验证方式给了两条;⑤ 报错原文和两条办法都在。

评论区

[ 标签 ]
# AI37# AI 编程2# AI工具1# AI绘图1# AI辅助开发2# Ajax7# Apifox1# AstrBot3# Astro2# CC Switch1# CDN2# Claude Code1# claudecode2# ClaudeCode1# Cloudflare2# CloudFlare2# CloudFlare-ImgBed3# coc4# CSS10# DeepSeek6# deepseek2# DELETE1# Docker5# EdgeOne3# Gist1# git1# GitHub1# hexo-circle-of-friends1# HTML9# HTTP10# ImageManager1# Java23# java13# JavaScript11# JavaWeb113# JDBC7# JSON2# JUnit1# LangChain25# Linux4# Logback1# Maven17# Muse Spark1# Mybatis1# MyBatis18# MySQL45# MySql1# NapCat1# Node.js1# obsidian2# Obsidian5# OpenCode4# ORM1# PathVariable1# PicGo1# PyCharm1# Python70# RequestBody1# RequestMapping1# RESTful风格1# skills1# Slf4j1# SpringBoot37# SpringMVC5# SQL2# Streamlit5# Svelte2# TailwindCSS1# Telegram3# Tlias2# Vercel1# vscode2# Vue20# Waline3# Web3# WebDAV1# Web基础6# Web开发6# WinSCP1# YAML1# 三层架构1# 中二宣言1# 书籍1# 使用文档10# 写作1# 函数2# 刷步数1# 前端52# 动态1# 动漫1# 包1# 单词2# 博客8# 博客工作流1# 博客开发2# 参数接收1# 友链1# 反思2# 后端48# 图床6# 地图1# 备份2# 大模型1# 奇思妙想1# 存储1# 学习方法6# 学校1# 宝塔面板3# 宝宝10# 实战4# 对象1# 导航栏1# 工具2# 布局2# 开发1# 开发工具1# 开发规范1# 开心1# 异常处理1# 影视2# 微信1# 性能优化2# 总结1# 想法15# 感受1# 感悟11# 指南1# 提示词工程2# 插件5# 故障排除1# 效率工具2# 教程10# 数据分析9# 数据库27# 数据结构1# 文件操作2# 斩神1# 日常95# 日志框架1# 朋友圈1# 朱元璋1# 模块1# 模板1# 正则表达式2# 测试3# 游戏2# 爬虫7# 生活迁移1# 电影2# 电脑1# 碎碎念1# 视觉识别1# 类1# 类型注解1# 网络基础2# 网络教室1# 羊毛2# 脚本2# 脚本工具1# 自动化2# 蓝奏云1# 表单1# 订阅推荐2# 记录2# 评论系统1# 词根1# 词缀1# 说说1# 足迹1# 跑步2# 路径参数1# 转载2# 运动1# 部署11# 部落冲突1# 配置1# 随机图1# 面向对象5# 音乐3# 音标1# 项目实战11# 饮食1# 驼峰命名1# 高德地图1
[ 公告 ]

如果你喜欢,那么欢迎来到我的世界!

了解更多
[ 音乐 ]
封面

音乐

暂未播放

0:000:00
暂无歌词
找不到相关结果。
[ contents ]
[ 全部文章 ]