
简介一份面向有Linux基础与开发经验技术人员的Docker全景学习手册内容覆盖从行业痛点与核心概念到生产级实战部署的完整链路。文档从“在我机器上能运行”等经典困境切入用大量命令实例讲解环境搭建、镜像拉取与构建、容器生命周期管理、自定义网络配置并深入解析Dockerfile多阶段构建、层缓存优化等最佳实践。资源为1个PDF文件压缩包大小仅1.11MB内容结构完整、章节清晰便于离线阅读与随查随用。目前已有236人学习下载。除基础操作外文档还系统介绍了Docker Compose、Swarm、Kubernetes等容器编排方案对比五种网络模式覆盖生产环境中的安全加固、监控日志、性能调优与典型故障排障思路并附有分阶段学习计划和免费资源推荐能帮助读者将所学快速落地到实际项目实现从新手到专家的稳步进阶。 搞Docker这些年我最大的感受就是入门阶段最难的其实不是命令多而是脑子里没有一套“容器思维”。很多人卡在第一步是因为老拿Docker跟虚拟机比结果越学越乱。这份“Docker新手学习大全”就是冲着这个问题去的——从“Docker到底解决什么问题”讲起再到Windows和Linux下的安装、常用命令、数据持久化最后用MySQL 8.0和Redis主从两个实战把知识串起来。文章面向的读者很明确没碰过容器的小白、刚学完Linux想提升效率的开发者、以及想用Docker统一开发和生产环境的运维同学。读完不敢说你能成为容器专家但至少能独立部署一套带数据库的服务遇到常见报错知道去哪查、怎么修。1. Docker到底解决什么问题1.1 从“环境地狱”说起为什么需要容器化你一定遇到过这种场景代码在本地跑得好好的一到同事电脑上就报错版本不对、依赖缺失、配置没同步光是排查环境问题就耗掉半天。这就是典型的“环境地狱”——软件开发里最磨人、也最没技术含量的事之一。Docker解决这个问题的方式是把应用连同它的运行环境一起打包成一个“镜像”。镜像里有什么有操作系统的基础层、有运行时比如Python或Node.js、有项目依赖的库、有配置文件。别人拿到这个镜像不需要自己安装任何依赖直接跑起来就是一模一样的环境。刚入门的人容易把Docker想成一个“轻量级虚拟机”这个类比方向对但不够准确。虚拟机会虚拟出一整套硬件里面跑一个完整的操作系统启动慢、占资源。容器则直接复用宿主机的操作系统内核只把文件系统、进程空间、网络这些做了隔离所以容器秒级启动、占用的内存和磁盘都很小。理解这个差异你后面看很多Docker的设计就会觉得顺理成章。1.2 镜像与容器的关系一次弄懂三个核心概念Docker有三个概念必须彻底搞懂镜像、容器、仓库。我的经验是用“食谱、菜、图书馆”来类比特别容易记住。镜像就是一张只读的“食谱”或者“模具”它定义了最终跑起来的程序长什么样、依赖什么环境。容器是镜像运行起来后的“实例”你可以对它做任何操作——装软件、改配置、跑服务甚至弄坏了也没关系删掉再从镜像重新生成一个就行几秒钟的事。仓库则是存放镜像的地方默认的Docker Hub就像是全球最大的“食谱图书馆”里面有MySQL、Redis、Nginx等几百万个现成镜像pull下来就能用。这套设计带来的好处非常实用同一个镜像可以同时跑出多个容器互不干扰开发环境和生产环境用同一个镜像环境差异彻底被消灭。1.3 新手最容易踩的认知误区带过不少同事入门我发现大家的困惑点高度一致。第一个误区是“容器里装了东西会不会丢”——会如果你没挂载数据卷容器一删数据就没了。这个问题后面会详细讲但新手一定要现在就建立意识容器是临时的数据要放外面。第二个误区是“Docker只能跑Linux程序”。早期确实如此但现在Windows和macOS上都有Docker Desktop底层帮你跑了一个轻量的Linux虚拟机跑Linux容器完全没问题。第三个误区是“镜像一定要自己写”。新手总觉得自己得从零编写Dockerfile才算会Docker实际工作中80%的场景是直接拉官方镜像改改参数就上线。学会写Dockerfile是加分项但先用好现成镜像才是正确路径。2. 环境准备与安装Windows和Linux两条路线2.1 Windows安装Docker Desktop一步步操作与避坑指南Windows上目前最主流的方案是Docker Desktop它自带图形界面适合新手。安装前有一个硬性检查CPU的虚拟化必须在BIOS里开启。大部分人的电脑默认是开着的但一些老机器或品牌机可能默认关闭。具体安装步骤先去官网下载Docker Desktop Installer.exe双击运行安装过程中保持默认选项即可。装完重启电脑开始菜单打开Docker Desktop等右下角小鲸鱼图标变绿就说明启动成功了。实际上手时你会发现真正的坑往往在启动报错环节。最经典的一条报错是“Docker Desktop failed to start because virtualisation support wasnt detected”。这行字的意思直白Docker需要虚拟化支持但它没检测到。处理路径按顺序来进BIOS开机按Del或F2找到Intel Virtualization Technology或AMD SVM Mode设为Enabled保存重启。如果BIOS没问题检查Windows功能是否启用了“适用于Linux的Windows子系统”和“虚拟机平台”。在控制面板的“启用或关闭Windows功能”里勾上这两项重启。打开PowerShell执行wsl --update升级WSL内核。Docker Desktop 4.26之后对WSL2内核版本有要求老版本内核会直接导致启动失败。我遇到过一台机器BIOS和Windows功能都正常最后就是wsl --update没执行更新完立刻就能启动了。2.2 Linux安装DockerUbuntu和CentOS的常用姿势Linux服务器上装Docker其实就几条命令的事。Ubuntu用户最简单的办法是用官方安装脚本我在全新的云服务器上实测执行curl -fsSL https://get.docker.com | sh一条命令装完再把当前用户加入docker组省得每次敲命令都加sudosudo usermod -aG docker $USERCentOS 7用户习惯用yum装。老实的做法是配置Docker官方的yum源后再安装避免装到过时的版本sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum install -y docker-ce docker-ce-cli containerd.io装完之后不管哪个发行版都要执行启动和开机自启sudo systemctl enable --now docker如果你之前用yum装过老版本的docker想升级到新版直接sudo yum install docker-ce --only-upgrade即可配置文件一般不用动。2.3 镜像下载慢的解决办法配置镜像加速器国内拉Docker镜像慢是老生常谈的问题了尤其是第一次docker pull ubuntu的时候几MB的镜像能卡到怀疑人生。原因很简单Docker默认从国外仓库拉取网络路径长速度自然上不去。解决办法是给Docker配置“镜像加速器”也就是registry mirror。原理不复杂你在国内找一个和官方仓库保持同步的公共镜像服务让Docker从更近的地方拉镜像。Linux系统修改/etc/docker/daemon.json没有就新建填入{ registry-mirrors: [https://你的加速服务地址] }改完之后执行sudo systemctl daemon-reload和sudo systemctl restart docker再拉镜像就会明显变快。Windows的Docker Desktop更省事Settings - Docker Engine里直接编辑同格式的JSON应用后会自动重启Docker。必须提醒一句不要用来历不明的加速地址尽量选择有信誉、长期维护的公共镜像服务。另外拉取失败时不要一根筋重试换个tag比如把latest换成具体的版本号或者换个时间段往往能解决问题。3. 核心概念与常用命令从会用到底层原理3.1 镜像、容器、仓库再往深挖一层第一节用食谱类比帮你建立了整体印象现在往深一层讲。镜像其实是一堆只读层的堆叠Docker通过“联合文件系统”把这些层合并成一个统一的文件系统视图。你写Dockerfile时每一行指令比如RUN apt-get install都会生成一个新层。这个设计带来的好处是层可以复用多个镜像共用同一层时磁盘占用和拉取时间都会减少这也是为什么Docker镜像通常比虚拟机镜像小得多。镜像的tag也有讲究。mysql:8.0的意思是仓库名为mysql、标签为8.0的镜像标签通常代表版本。不写tag默认拉latest但这个tag在不同镜像里对应的版本差异很大生产环境里强烈建议锁定具体版本号。3.2 生命周期管理命令日常使用频率最高的十几个命令不需要背多用几次自然就熟了。我最常用的命令基本能覆盖90%的日常操作整理成表格如下操作命令拉取镜像docker pull 镜像名:tag查看本地镜像docker images运行容器docker run -d -p 宿主机端口:容器端口 --name 容器名 镜像名:tag查看运行中的容器docker ps查看所有容器含已停止docker ps -a进入容器内部docker exec -it 容器名 bash查看容器日志docker logs -f 容器名停止容器docker stop 容器名启动已停止的容器docker start 容器名删除容器docker rm 容器名删除镜像docker rmi 镜像名:tag查看容器详细信息docker inspect 容器名实测下来docker exec -it 容器名 bash是排查问题最频繁用到的命令。容器跑起来了但功能不正常第一件事就是进容器看进程、看配置、看网络。docker logs排第二大部分启动失败的线索都在这里。3.3 数据持久化不挂载数据说没就没容器设计哲学是“用完即弃”但数据库这种服务偏偏不能这样。MySQL的数据如果写在容器里一个docker rm就全没了。解决办法是数据卷volume或目录挂载bind mount。最粗暴也最好理解的用法是目录挂载启动时加参数docker run -d --name mysql8 -p 3306:3306 -v /data/mysql:/var/lib/mysql mysql:8.0这行命令的意思是把宿主机的/data/mysql目录映射到容器的/var/lib/mysql目录。MySQL往容器里写数据实际落盘到了宿主机上容器删了、换了数据依然还在。命名卷named volume是官方更推崇的用法docker run -d --name mysql8 -v mysql_data:/var/lib/mysql mysql:8.0区别在于你不关心数据具体存在宿主机哪个目录Docker统一管理。好处是备份迁移方便坏处是对新手来说不够直观。我的建议个人学习用挂载目录最直观生产环境按团队规范来。3.4 端口映射与网络模式容器之间怎么通信容器默认使用桥接网络它会从Docker分配的子网里拿一个IP。但这个IP是Docker内部的宿主机和外面网络访问不到。要对外提供服务必须做端口映射-p 宿主机端口:容器端口。比如-p 3306:3306就是把宿主机的3306端口流量转发到容器的3306端口。如果宿主机3306已被占用可以改成-p 3307:3306外部通过3307访问这对本地装了原生MySQL、又想在Docker里跑一个的人来说特别实用。容器之间通信有几种方式。最简单的是通过IP访问但Docker重启后容器的IP可能变化所以不推荐。更优雅的方式是创建自定义网络容器之间通过容器名互相访问docker network create my-net docker run -d --name mysql8 --network my-net mysql:8.0 docker run -d --name myapp --network my-net myapp:latest这样一来myapp容器里连接数据库只需用mysql8作为主机名网络层面由Docker自动解析IP怎么变都不影响。4. 实战一用Docker部署MySQL 8.04.1 拉取镜像与启动三分钟跑起一个数据库选MySQL 8.0做第一个实战是因为它是目前最主流的关系型数据库部署过程中会涉及到数据卷、环境变量、端口映射、进入容器排错等多个核心知识点。第一步拉镜像docker pull mysql:8.0第二步启动容器docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDMyRootPass123 \ -e TZAsia/Shanghai \ -v /data/mysql:/var/lib/mysql \ mysql:8.0-d表示后台运行--name给容器起名-e传入环境变量MySQL官方镜像用MYSQL_ROOT_PASSWORD指定root密码用TZ设置时区-v挂载数据目录。这时候用docker ps看状态如果变成Up说明MySQL已经在跑。用Navicat或其他客户端连一下localhost:3306用户名root密码就是你设的那个。4.2 进入容器验证版本、字符集和配置容器跑起来了怎么确认里面配置对不对答案是进入容器内部直接操作docker exec -it mysql8 bash进去之后就是Linux命令行执行mysql -uroot -p输入密码进入MySQL客户端。两个东西建议确认一下一是SELECT VERSION();看版本是否是8.0二是SHOW VARIABLES LIKE character%;看字符集。MySQL 8.0默认字符集就是utf8mb4一般不需要额外配置但如果你的项目需要定制配置比如调低max_connections、修改sql_mode可以在宿主机建一个配置文件然后挂载进去docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDMyRootPass123 \ -v /data/mysql/conf.d:/etc/mysql/conf.d \ -v /data/mysql:/var/lib/mysql \ mysql:8.0把自定义的.cnf文件放到宿主机的/data/mysql/conf.d目录MySQL启动时会自动加载。这样改配置不用重新构建镜像改文件后重启容器即可。4.3 实战中的常见坑端口冲突、密码失效、时区错乱先说自己踩过的两个坑。第一个是端口冲突。本机装了原生MySQL的情况下再启动容器映射3306必然报错。解决办法就是换宿主机端口-p 3307:3306外部连接时填3307。第二个坑是容器能启动但连不上。这时候按三步排查先docker ps确认容器状态是Up再docker logs mysql8看启动日志最后docker exec -it mysql8 bash进容器内用mysql命令连本机。如果容器内能连、外面连不上基本就是端口映射或防火墙的问题。还有一个小细节MySQL 8.0的caching_sha2_password认证插件对老版本客户端兼容性不太好。如果你是用的Navicat旧版或老项目连接时报“Authentication plugin caching_sha2_password cannot be loaded”可以创建用户时指定兼容插件CREATE USER app% IDENTIFIED WITH mysql_native_password BY password; GRANT ALL PRIVILEGES ON *.* TO app%;4.4 清理容器与镜像不用的资源及时回收测试过程中可能会创建很多容器堆积在系统里。docker rm -f mysql8-f表示强制删除运行中的容器。删除容器不会影响挂载在宿主机/data/mysql的数据所以你可以尽情折腾删错了重新run一次数据都还在。这就是数据卷挂载最实在的价值——把容器当成一次性的进程而不是需要细心呵护的“虚拟机”。5. 实战二用Docker Compose部署Redis主从5.1 Compose是什么多容器编排的“一键启动”手动docker run部署单个容器没问题但部署有依赖关系的一整套服务时命令会变得又长又难维护。Docker Compose就是干这个的用一份YAML文件定义多个服务一条docker compose up -d全部启动。Redis主从是个很好的入门场景一个主节点负责写一个从节点负责读配置简单却覆盖了Compose的核心用法。先看docker-compose.yml文件version: 3 services: redis-master: image: redis:7.0 container_name: redis-master ports: - 6379:6379 volumes: - ./redis-master.conf:/etc/redis/redis.conf command: redis-server /etc/redis/redis.conf redis-slave: image: redis:7.0 container_name: redis-slave depends_on: - redis-master ports: - 6380:6379 volumes: - ./redis-slave.conf:/etc/redis/redis.conf command: redis-server /etc/redis/redis.conf5.2 主从配置文件一分钟看懂核心参数主节点配置redis-master.conf重点是开启密码保护requirepass redisMaster123从节点配置redis-slave.conf重点是指定主节点地址。注意这里的主机名是Compose服务名redis-masterCompose内部自动做了DNS解析requirepass redisMaster123 replicaof redis-master 6379 masterauth redisMaster123两个配置文件放在docker-compose.yml同目录下然后执行docker compose up -d用docker compose ps查看状态看到两个服务都是Up用docker compose logs redis-slave | grep -i MASTER可以确认主从是否建立成功。5.3 实测验证主从复制写主读从主从配置好了怎么验证真在同步数据启动一个临时Redis客户端容器来测试docker exec -it redis-master redis-cli -a redisMaster123 set testkey hello docker exec -it redis-slave redis-cli -a redisMaster123 get testkey主节点写入testkey从节点能读到同样的值说明主从复制已经生效。这里要强调一个新手特别容易忽略的点depends_on只保证容器启动顺序不保证主节点已经就绪。刚才的例子里从节点可能比主节点先完成启动然后在主节点可用之前就尝试连接需要重试。Redis从节点有自动重连机制一般不会出问题但你在编排复杂服务时一定要意识到depends_on不是万能的必要时需要在应用层做健康检查或重试。5.4 Compose的日常操作启动、停止、看日志Compose最舒服的一点是整个服务组可以通过一条命令统一管理docker compose up -d # 启动全部服务 docker compose ps # 查看服务状态 docker compose logs -f # 实时查看所有服务的日志 docker compose down # 停止并删除全部容器注意docker compose down默认不会删除挂载的volume数据这点设计很合理方便你随手重建服务而不丢数据。如果想连数据一起清掉才需要加-v参数。实际使用中我发现把docker-compose.yml提交到Git仓库团队新成员一拉代码docker compose up -d就拥有完整环境比写十几页的环境搭建文档高效得多。6. 进阶实战构建自己的镜像与环境一致性6.1 编写Dockerfile从零打包一个应用镜像拉现成镜像只能覆盖通用软件自己写的应用最终还是要打成一个专属镜像。这份学习的最终目标是让你能独立完成这一步。一个最简单的Node.js应用Dockerfile长这样FROM node:18 WORKDIR /app COPY package*.json ./ RUN npm install COPY . . EXPOSE 3000 CMD [npm, start]每一行的含义FROM指定基础镜像好比“买了一套带精装修的毛坯房”WORKDIR设定容器内的工作目录后续操作都在这里执行COPY把本地的package.json拷进去RUN npm install安装依赖再次COPY把全部源码放进来EXPOSE声明容器监听端口不过它只是文档性质的真正的端口映射还是要靠-pCMD定义容器启动时执行的命令。构建命令docker build -t myapp:1.0 .-t指定镜像名和tag最后的.表示Dockerfile所在目录也叫构建上下文。6.2 镜像瘦身的实用技巧多阶段构建新手构建镜像最常见的毛病是“什么都往里装”最后镜像几个GB拉取慢、占用大。多阶段构建是解决这个问题的标准姿势。拿一个Java Spring Boot应用举例# 第一阶段使用包含完整JDK的镜像进行编译 FROM maven:3.8-openjdk-17 AS build WORKDIR /app COPY pom.xml . RUN mvn dependency:go-offline COPY src ./src RUN mvn package -DskipTests # 第二阶段只拷贝编译产物配合精简运行环境 FROM openjdk:17-jre-slim WORKDIR /app COPY --frombuild /app/target/*.jar app.jar EXPOSE 8080 CMD [java, -jar, app.jar]关键就在于第一阶段是“编译器”第二阶段是“运行环境”。最终镜像里只有编译好的jar包和精简版JRE没有源码、没有Maven、没有临时文件镜像体积能缩小一大半。6.3 由“部署一个服务”到“部署一组服务”学会单镜像构建后自然要过渡到多服务编排。把前一节的Compose思路和自定义镜像结合就是一套典型的微服务开发环境前端一个容器、后端两个服务容器、中间件MySQL/Redis各一个容器全部由Compose管理。实际项目里我常看到的问题是用IP地址写配置。容器重启IP可能会变导致服务之间突然连不上。正确的做法是服务间通信使用服务名把配置信息数据库地址、密码通过环境变量注入而不是写死。Compose的environment字段和env_file就是干这个的。还有一个容易被忽略的点构建镜像时避免把敏感信息写进Dockerfile。比如数据库密码如果你是RUN echo password写进去的别人一docker history你的镜像密码就暴露了。正确做法是运行时通过环境变量传入或者用Docker Secret管理。7. 常见问题与排查技巧速查学完前面的内容剩下的就是实战中不断遇到报错、解决报错的过程。我把自己这一年多来遇到的高频问题整理成一个速查表方便你直接对照处理现象可能原因排查与解决Docker服务启动失败宿主机内核版本过低、配置文件损坏sudo journalctl -u docker看日志检查/etc/docker/daemon.json语法是否正确docker命令提示permission denied当前用户不在docker组执行sudo usermod -aG docker $USER后重新登录临时方案是命令前加sudo容器启动后立即退出前台进程结束、配置错误docker logs 容器名查看日志多数线索都在这里镜像拉取超时网络问题、镜像过大配置镜像加速换用体积更小的tag多试几次端口映射后外部访问不了防火墙、端口被占用先宿主机curl localhost:端口测试再检查防火墙最后看容器IP能否直接访问磁盘空间告急悬空镜像、无用缓存堆积执行docker system prune清理docker system df查看空间占用分布MySQL中文乱码连接时字符集不对确认连接字符串加了characterEncodingutf8确认容器内字符集是utf8mb4Redis主从不生效密码不一致、网络不通检查masterauth是否配置docker compose logs看主从连接日志7.1 两个必须养成的习惯看日志和看状态排查Docker问题我始终坚信一条原则先看日志再看状态最后才动用搜索引擎。很多新手一看到容器没起来第一反应是把容器删了重新跑结果还是一样报错殊不知docker logs早就把原因说得明明白白。容器的标准输出被Docker捕获docker logs能看到应用打印的日志服务启动失败、连接失败、配置文件加载错误全都写在这里。docker inspect则是看容器配置细节的神器。它输出的是庞大的JSON包含环境变量、挂载卷、网络配置、重启策略等一切信息。用grep过滤一下比到处猜靠谱得多。7.2 资源清理别让你的机器被镜像堆满学习阶段你会频繁拉镜像、构建镜像、跑容器磁盘很容易被吃光。docker system df可以看清磁盘占用分布docker system prune一条命令清掉停止的容器、悬空镜像和未使用的网络。加-a参数会连未被任何容器使用的镜像一起清理谨慎使用。最后再分享一点个人经验按这套学习路径走下来你大概需要半个月的时间就能把Docker用得有模有样。我的建议是不要刻意背命令把原理搞懂命令用多了自然就记住了不要想着看完所有文档再动手先跑起来一个Nginx再部署MySQL然后写自己的Dockerfile最后上Compose编排。每一步都踩在实地上遇到问题回来翻这个速查表基本都能解决。容器技术更新很快但核心思路——环境隔离、镜像复用、数据持久化——不会变把这些根基打牢以后接触Kubernetes、Service Mesh这些上层技术时你会发现一切都很顺理成章。本文还有配套的精品资源点击获取