简介:面向Docker初学者的《Docker新手学习大全:从入门到实战部署》是一份PDF文档,适合有一定Linux基础、希望掌握容器化技能并落地到实际项目的开发与运维人员。内容从“为什么Docker是开发者必备技能”切入,系统讲解镜像、容器、守护进程与网络模型,再通过环境搭建、镜像操作、容器管理、网络配置等实战章节,帮助读者独立完成常用操作;同时深入Dockerfile多阶段构建与缓存优化,介绍Compose、Swarm、Kubernetes等编排工具,并给出生产环境安全加固、监控日志与性能调优建议。资源包共1个PDF文件,大小1.11MB,便于移动端或桌面端查阅,已有236人学习。文档配有命令示例、阶段学习计划和常见问题排障指南,读者可据此每天动手实践,将个人项目容器化,从入门稳步进阶到生产部署水平。 凡是亲手装过一套 MySQL + Redis + 应用环境的人,多少都体会过那种说不出口的烦:系统里残留了老版本、端口被占用、依赖冲突、配置改了又改……我当年第一次听说 Docker 时,第一反应是“又一个虚拟机”,等真把它用起来,才意识到问题根本不在“装软件”,而在“整套环境的成本被人为放大了”。这篇内容是我把《Docker新手学习大全:从入门到实战部署》完整捋了一遍,结合自己在 Windows 和 Linux 两台机器上的实操记录整理出来的,适合完全没接触过 Docker、正准备装 Docker Desktop,或者已经装上但经常被镜像拉取、权限报错、端口映射问题困扰的人。
1. 先搞清楚 Docker 在解决什么问题:从“装环境”到“装整套环境”
1.1 虚拟机、WSL2 与 Docker 的本质区别
很多人第一次学 Docker,都会下意识拿它跟虚拟机比:不都是在一个系统里再跑一个系统吗?
这个理解不算错,但会直接导致你后面用错方法论。传统虚拟机是在宿主机上模拟一整套硬件,然后在上面装一个完整的操作系统,隔离性确实强,代价是启动要等几十秒、镜像动不动几个 GB、跑几个服务内存就报警了。Docker 的思路完全不同,它依赖 Linux 内核里的 namespace 和 cgroups 技术,把进程、文件系统、网络、进程组隔离开,所有容器和宿主机共享同一个内核,所以容器本质上是一组被隔离的进程。
放在 Windows 上,这个区别更明显。Docker Desktop 默认借助 WSL2 作为后端,WSL2 本身又是一个轻量级虚拟机,正是这个“套娃”结构让很多入门者迷惑——其实 WSL2 只是 Docker Desktop 在 Windows 上运行 Linux 容器的基础设施,容器本身还是进程,并不是你肉眼可见的一个新桌面系统。
理解这一点后,很多问题都解释得通了:为什么容器镜像比虚拟机镜像小一个量级?因为镜像只带程序和运行所需的环境,不打包内核。为什么容器能秒启?因为启动容器就是启动进程。这也是 Docker 在大规模部署时受欢迎的核心原因——同样的环境从开发机原封不动搬到服务器,中间没有“在我机器上是好的”这种借口。
1.2 镜像、容器、仓库:三个名词一次讲透
我见过太多新手把这三个词混在一起,实际用起来全是坑。打个比方就很清楚:
- 镜像(Image),相当于菜谱,只读的,定义好了环境长什么样。
- 容器(Container),是按菜谱做出来的那一盘菜,可运行、可修改、可删除。
- 仓库(Registry),是存放菜谱的图书馆,默认的公共图书馆就是 Docker Hub。
整套流程其实就是:docker pull从仓库把镜像拉到本地,docker run用镜像创建并启动容器。一个镜像可以同时起多个容器,互相不干扰;容器删掉了,镜像还在本地,下次还能再起,不用重新下载。
我一开始也犯过蠢,跑了个容器测试完,直接docker rm把容器删了,以为东西全没了。后来才发现镜像还在,重新docker run一条命令就回来了。这不是什么高级技巧,但理解“镜像和容器是两层东西”,后面学数据卷、Compose 都会顺很多。
2. 安装环节最容易卡住的两个坑:虚拟化没开与镜像拉不下来
2.1 Windows 上 Docker Desktop 的安装与虚拟化检测
安装 Docker Desktop 本身不难,从官网下载 installer.exe,一路 Next 就行。真正拦住大多数人的是两个前置条件:BIOS 里的虚拟化没开,和 Windows 的“虚拟机平台”功能缺失。
我第一次装完 Docker Desktop,双击启动直接弹了那个经典恶梦:Docker Desktop failed to start because virtualisation support wasn't detected。当时第一反应是卸载重装,折腾两次毫无作用。后来老老实实按顺序排查:
- 打开任务管理器 → 性能 → CPU,看右下角“虚拟化”是否显示“已启用”。如果显示“已禁用”,需要进 BIOS/UEFI,找到 Intel VT-x 或 AMD-V 开关,把它打开并保存重启。
- 回到 Windows,打开“控制面板 → 启用或关闭 Windows 功能”,勾选“虚拟机平台”和“适用于 Linux 的 Windows 子系统”。这一步很多人会漏,只装 Docker Desktop 没开 Windows 侧的功能,WSL2 后端起不来。
- 在管理员权限的 PowerShell 里执行
wsl --update,把 WSL 内核更新到新版。 - 最后重启电脑,再启动 Docker Desktop。
顺序不要乱,很多教程只让你重装,却不提 BIOS 和 Windows 功能,问题自然解决不了。Windows 11 普遍没这些毛病,Windows 10 的老机器踩得最多,如果你正好卡在这一步,先别急着怪 Docker。
2.2 镜像下载慢的真正解法:配置镜像加速器
装好 Docker 之后,第一个打击基本都来自docker pull。默认从 Docker Hub 拉镜像,网络状况你懂的,经常几 KB/s 甚至直接超时。网上关键词搜“docker 镜像下载慢”,能翻出几十种说法,但真正通用、安全的解法只有一个:配置镜像加速器。
Docker 的镜像拉取支持 registry mirror 机制,你可以把公共镜像加速服务写在配置里,拉镜像时 Docker 会优先走加速地址。Windows 上打开 Docker Desktop → Settings → Docker Engine,直接把配置改成这样:
{ "registry-mirrors": [ "https://docker.m.daocloud.io", "https://docker.mirrors.ustc.edu.cn" ] }Linux 上对应改/etc/docker/daemon.json,没有这个文件就新建一个,改完重启 Docker 守护进程:
sudo systemctl daemon-reload sudo systemctl restart docker我实测下来,不同时间段不同镜像源的稳定性差别很大,配置文件里多放几个备选,一个拉不动就换下一个。这里也提醒一句,别去信那些让你翻来翻去的旁门左道,加两行合法合规的镜像加速配置就够了。
2.3 Linux 服务器上的安装差异
Linux 上装的不是 Docker Desktop,而是 Docker Engine,这也是服务器上最常见的形态。Ubuntu/Debian 系可以直接sudo apt install docker.io,但版本可能偏旧;CentOS 7 这类老系统更需要注意,系统自带的 docker 包是老版本,和现在的 compose 命令兼容性一般,建议先把旧版本卸载,再装 docker-ce。
无论哪个发行版,装完顺手执行一下:
sudo systemctl enable docker sudo systemctl start docker这两步保证 Docker 服务开机自启、当前立即启动。很多人装完才发现跑docker ps报Cannot connect to the Docker daemon,不是装坏了,就是服务没起来。另外 Linux 安装方式多,我个人的建议是新手优先用系统包或官方一键脚本,别自己编译源码,没必要给自己加难度。
3. 高频命令体系:把 Docker 当“带仓库的进程管理器”用
3.1 镜像生命周期:拉取、查看、删除
命令记太多容易劝退,其实日常高频的也就那么二十来条。先把镜像层次搞熟:
docker pull nginx:alpine # 拉取镜像 docker images # 列出本地镜像 docker rmi nginx:alpine # 删除镜像这里有个小知识点,:alpine是镜像标签(tag),表示基于 Alpine Linux 的精简版本。同一款 nginx 镜像,alpine 标签可能只有几十 MB,普通版本却有两三百 MB。开发测试、个人项目用 alpine 往往更顺手。
生产环境里,我不建议直接用latest标签,因为它的内容会随上游更新变化,今天能跑明天不一定能跑。固定到具体版本号,比如mysql:8.0,才具备可复现性。这也是 Docker 环境一致性的前提——镜像不锁定,环境就不锁定。
3.2 容器生命周期:运行、进入、日志、停止
容器相关命令是重中之重,其中docker run的参数组合最多,新手最容易在这里懵。我一般建议把参数拆开记:
docker run -d \ --name web-test \ -p 8080:80 \ -v $(pwd)/html:/usr/share/nginx/html \ nginx:alpine-d表示后台运行;--name给容器起名字;-p 8080:80把宿主机的 8080 端口映射到容器的 80 端口;-v把当前目录下的 html 文件夹挂载进容器的 nginx 网页目录。跑完之后打开浏览器访问http://localhost:8080,如果能看到页面,说明这条链路已经完全通了。
想进容器内部看看,用:
docker exec -it web-test sh排错时离不开日志:
docker logs -f web-test停止、删除容器:
docker stop web-test docker rm web-test有个细节新手容易忽略:docker stop只是停掉容器,容器还在,docker start还能再启动;docker rm才真正删除。判断“这个容器还存在吗”,看docker ps -a,只看docker ps只会显示运行中的容器,很容易造成误判。
3.3 端口映射与数据卷:让容器真正“可用”
端口映射的意义是把容器内部的端口暴露到宿主机,否则容器和外界就是完全隔离的。写-p 8080:80时,左边是宿主机端口,右边是容器端口,方向搞反了基本连不上。如果端口冲突,报错往往是Bind for 0.0.0.0:8080 failed: port is already allocated,解决办法就是换一个宿主机端口,比如-p 8081:80。
数据卷解决的是另一个核心问题——容器的易失性。容器被删除后,容器内产生的所有数据都会消失,因为它的可写层是临时的。要持久化数据,得用卷:
docker volume create mysql-data docker run -d -v mysql-data:/var/lib/mysql mysql:8.0这句话的意思是:把名为 mysql-data 的卷挂载到容器的/var/lib/mysql目录,MySQL 写库数据实际落在卷里,容器删了重建,数据还在。我自己就吃过没挂数据卷的亏,跑了个测试库,随手docker rm,库没了,那种心情不想体验第二次。
4. 实战部署:MySQL 8.0 与 Redis 主从一次跑通
4.1 MySQL 8.0:从裸容器到带数据卷的可用实例
安装类关键词里,docker 安装 mysql8.0是出现频率最高的了。先建一个自定义网络,方便后面 Redis 主从和 MySQL 互相通信:
docker network create app-net启动 MySQL 8.0 的完整命令是:
docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=root123 \ -e MYSQL_DATABASE=appdb \ -v mysql-data:/var/lib/mysql \ --network app-net \ mysql:8.0几个环境变量的含义:MYSQL_ROOT_PASSWORD是 root 密码,MYSQL_DATABASE是首次启动自动创建的数据库。这里的密码我写了简单值方便演示,实际部署一定要换成强密码。
验证是否可用:
docker exec -it mysql8 mysql -uroot -p进入 MySQL 后执行SHOW DATABASES;,能看到appdb就说明成功了。如果你本机 3306 端口已经有一个 MySQL 在跑,把映射改成-p 3307:3306就能避开冲突。字符集问题也值得注意,数据有中文需求的,建议在命令里加上--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci。
4.2 Redis 主从:网络、配置与验证
Redis 主从部署是热词里大家问得很多的一个场景,用 Docker 来做其实比手工部署简单,因为不用考虑本机安装的路径和配置问题。重点是主从节点必须在同一个自定义网络里,不能用 localhost 互访。
先启动主节点:
docker run -d \ --name redis-master \ -p 6379:6379 \ --network app-net \ redis:7 \ redis-server --appendonly yes主节点开启了 appendonly,数据持久化到 AOF 文件。再启动从节点:
docker run -d \ --name redis-replica \ -p 6380:6379 \ --network app-net \ redis:7 \ redis-server --replicaof redis-master 6379这里最关键的是--replicaof redis-master 6379,从节点连接的是容器名redis-master而不是 IP,因为在自定义网络里,Docker 内置 DNS 会帮我们把容器名解析成对应 IP。验证主从是否成功:
docker exec -it redis-replica redis-cli info replication输出里role:slave(或role:replica)和master_link_status:up同时出现,说明挂上了。
4.3 删除与重置:新手必会的恢复手段
新手练手阶段起错容器很正常,别慌,一套流程停掉、删掉、重来:
docker stop mysql8 redis-master redis-replica docker rm mysql8 redis-master redis-replica docker network rm app-net数据卷我先没删,所以即使容器全删了,再用同样的-v mysql-data跑新容器,MySQL 数据还在。如果确定要彻底清掉数据,再执行docker volume rm mysql-data。
这套“停止 → 删除 → 重建”的思路,是 Docker 排障的基本动作。很多网上问的“容器起不来怎么办”,一半以上是可以先docker logs看日志,再决定要不要重建,而不是盲改命令猜来猜去。
5. 从单容器到整套环境:Docker Compose 与 Dockerfile 的入门组合
5.1 Dockerfile:把环境固化成镜像
用docker run跑 MySQL、Redis 这种现成镜像很简单,但实际项目里总有自己应用的镜像要构建。这时候就用 Dockerfile 把环境固化下来,配置文件版本化,别人拿过去也能构建出一样的东西。
拿一个 Node.js 应用举例:
FROM node:20-alpine WORKDIR /app COPY package.json /app/ RUN npm install COPY . /app EXPOSE 3000 CMD ["npm", "start"]构建命令是:
docker build -t my-app .Dockerfile 每一行都会生成一个层,层有缓存机制:只要前几层没变,后面构建会直接复用缓存,速度飞快。所以我习惯先把package.json单独 COPY 进去装依赖,再 COPY 整个项目,这样代码改了依赖没变时,不会触发 npm install 重跑。这个优化对构建体验的提升非常明显。
5.2 compose.yaml:把多容器串成一套系统
容器一多,靠一条条docker run去记参数肯定不行,Docker Compose 就是干这个的。在项目目录下建一个compose.yaml,把刚才的 MySQL、Redis 和应用编排在一起:
services: mysql8: image: mysql:8.0 container_name: mysql8 ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: root123 MYSQL_DATABASE: appdb volumes: - mysql-data:/var/lib/mysql networks: - app-net redis-master: image: redis:7 container_name: redis-master ports: - "6379:6379" command: ["redis-server", "--appendonly", "yes"] networks: - app-net app: build: . container_name: my-app ports: - "3000:3000" depends_on: - mysql8 - redis-master networks: - app-net volumes: mysql-data: networks: app-net:然后一条命令全部搞定:
docker compose up -d --build-d后台运行,--build表示启动前先构建应用镜像。想查看整体状态用docker compose ps,看多个容器的日志叠加用docker compose logs -f。
很多项目官方也提供了现成镜像,比如常见的 KodBox 网盘、DVWA 靶场,本质就是一条docker run加上端口映射和数据卷,你按前面的思路去拆解,会发现一点都不神秘。Compose 的价值在于把所有参数固化成文件,别人一拉代码一执行就还原整套环境,这比复制聊天记录里的命令可靠得多。
5.3 和 Compose 配合的调试姿势
用 Compose 之后,进入某个容器调试的写法是:
docker compose exec app sh改完代码要重启应用,不需要把整个栈都删掉,只重建单个服务即可:
docker compose up -d --build app新手最容易犯的错是:改了compose.yaml里的端口或挂载,只执行docker compose start,发现配置没生效。因为start只启动已有容器,不重新创建容器。正确做法是用docker compose up -d,它才会对比配置变化并重建相关容器。这个坑我踩过一次之后,已经形成肌肉记忆了。
6. 新手报错排查实录:我见过最多的三类问题
6.1 permission denied 与 Docker 守护进程连接失败
Linux 上第一次运行docker ps,经常直接报:
permission denied while trying to connect to the Docker daemon socket这个报错的原因很清楚:Docker 是 C/S 架构,CLI 要通过 socket 和后台守护进程 dockerd 通信,而当前用户不在 docker 用户组里,没有访问 socket 的权限。解法:
sudo usermod -aG docker $USER执行完重新登录终端(或执行newgrp docker)让组权限生效。如果连 socket 文件都找不到,那大概率不是权限问题,而是 Docker 服务根本没起来,先检查sudo systemctl status docker,或者直接sudo systemctl restart docker。这两个方向不要搞混,排查效率会高很多。
6.2 Desktop 启动失败:虚拟化支持未检测到
Docker Desktop failed to start because virtualisation support wasn't detected这个报错,几乎是 Windows 新手的必经之路。我前面提过完整的解决顺序,这里再强调排查链条:
- 先确认 BIOS 里 Intel VT-x 或 AMD-V 已经打开;
- 再确认 Windows 功能面板里“虚拟机平台”和“适用于 Linux 的 Windows 子系统”都勾上了;
- 用
wsl --update更新内核; - 重启后打开 Docker Desktop。
我曾经见过有人 BIOS 和 Windows 功能都开了,还是报同样错误,最后发现是 Windows 版本太旧,缺了对 WSL2 的支持,系统更新到较新版本才解决。因此遇到这个报错,先把系统更新完成再考虑其他方向。
6.3 容器起来了但连不上:端口映射与网络排查
这是最折磨新手的一类问题:容器明明在跑,就是访问不了。我总结为三类情况:
第一,宿主机访问不到容器。检查-p参数的方向,-p 8080:80是把宿主机 8080 映射到容器 80,如果容器里服务监听的是 8080,你映射到 80,那肯定连不上。第二,容器 A 访问容器 B,不能在容器里用 localhost,因为每个容器有自己独立的网络命名空间,localhost 指向容器自己。正确做法是让两个容器在同一个自定义网络里,然后用容器名访问。第三,端口占用了,报Address already in use,换个宿主机端口即可。
排查时最有力的工具是docker logs,它能直接看到容器内部服务的实际日志,比猜配置高效太多了。我见过有人反复重启容器十几次,却从没看过日志,最后一看日志发现是数据库密码不对,一分钟就解决了。
这套内容写下来,基本覆盖了我从零上手 Docker 时踩过的所有坑。工具本身不复杂,复杂的是理解它背后的几个核心抽象:镜像与容器的关系、网络与端口、数据卷的持久化。你把这几个点吃透,再去翻《Docker新手学习大全》里的具体章节,速度会快很多。学习过程中遇到报错别硬记命令,先定位是哪一层出了问题——是镜像、容器、网络,还是宿主机的环境,这个排查习惯一旦养成,比背一百条命令都管用。
本文还有配套的精品资源,点击获取