ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Docker入门到实战:镜像、容器、数据卷与Compose编排全攻略

Docker入门到实战:镜像、容器、数据卷与Compose编排全攻略 简介面向有一定Linux基础和开发经验的技术人员这份《Docker新手学习大全从入门到实战部署》PDF文档系统梳理了容器化技术的完整知识链。文档从行业痛点切入说明Docker在环境标准化、资源利用、开发运维一体化与微服务架构中的价值深入解析镜像、容器、守护进程以及默认桥接、主机、无网络、覆盖、MAC直通等五种网络模型并给出跨平台环境搭建、镜像操作、容器管理和网络配置的实战步骤。Dockerfile部分重点展示多阶段构建、层缓存优化与常用指令帮助精简镜像体积容器编排部分覆盖Compose、Swarm和Kubernetes基础概念打通单机到集群的部署路径生产环境章节从安全加固、监控日志和性能调优三个维度提供最佳实践同时附带常见问题排障指南与分阶段学习路线便于对照实验和排查故障。整包为1个PDF文件大小仅1.11MB已有236人学习下载适合希望独立完成容器化部署并快速进阶的初中级技术人员。 第一次把一个 MySQL 8.0 装进 Docker 容器我只用了两条命令加一杯咖啡的时间。这个经历彻底改变了我对“部署环境”这件事的认知。这份 Docker 新手学习资料核心其实就是一条路线搞懂几个关键概念、装好一个可用的运行环境、背熟十几条高频命令、完整部署一次真实项目。这篇文章就按这条路线来写每个环节都附带我踩过的坑和现在还在用的习惯尽量让新手少走弯路。无论你用的是 Windows 还是 Linux无论你想跑数据库、网盘还是做本地测试都能从中找到一个可以直接抄作业的答案。1. Docker 到底是什么先删掉脑中的“虚拟机”印象1.1 镜像和容器的关系就像菜谱和做好的菜我见过很多人学 Docker 时第一个卡住的点就是“镜像”和“容器”分不清。这里我常用一个生活类比镜像是一份完整的菜谱里面写清楚了操作系统、运行环境、应用代码和所有依赖容器是按照这份菜谱实际做出来的一道菜可以做一盘、也可以做十盘每盘端上桌之后口味完全一样。这个类比有两点对新手特别重要。第一镜像本身是“只读”的你不会去改菜谱本身只会照着菜谱做菜。第二容器之间是互相隔离的一盘菜凉了不会影响另一盘菜删掉一个容器就像倒掉一盘菜菜谱镜像还在随时可以再做一份。理解了这两点Docker 里最核心的两个概念就通了。从技术角度说镜像是一个多层只读的文件系统容器则在镜像之上加了一个可写层并在里面跑一个或多个进程。它是直接共享宿主机内核的不需要虚拟化一套完整的操作系统所以容器启动通常是一秒级的事镜像占用的磁盘空间也远小于虚拟机。这也是为什么大家常说 Docker 解决的是“环境一致性问题”开发时用的是这个镜像测试和生产也用它环境差异就消失了。1.2 容器没有界面很正常靠端口访问服务经常有人在网上问“Docker 跑起来之后怎么看不到界面”“有没有像饭店点餐那样带界面的操作”这些问题的答案其实很统一容器里的应用本来就不是给你在桌面上一指禅开窗口用的它默认就是后台运行的服务。你需要访问应用时靠的是端口映射。端口映射简单说就是把宿主机上的某个端口和容器内的端口“接上线”。比如 Nginx 默认监听容器里的 80 端口启动时加上-p 8080:80浏览器里访问http://localhost:8080实际上请求会被转发到容器里的 80 端口从而看到 Nginx 欢迎页。这个机制贯穿整个 Docker 实战阶段MySQL、Redis、网盘系统、微服务项目全都靠端口映射对外提供服务。2. 环境准备Windows 和 Linux 安装 Docker 的完整姿势2.1 Windows 端Docker Desktop 安装与常见启动失败处理Windows 上装 Docker 一般就是装 Docker Desktop。装之前先去控制面板确认一下 Windows 功能里有没有开启“适用于 Linux 的 Windows 子系统”和“虚拟机平台”因为 Docker Desktop 默认依赖 WSL2 或 Hyper-V 来运行 Linux 容器。很多新手安装完 Docker Desktop 双击启动结果报错Docker Desktop failed to start because virtualisation support wasnt detected。这个问题十有八九是虚拟化没开或者 WSL2 没配好。排查路径我一般按顺序走先进 BIOS 确认虚拟化Intel VT-x / AMD-V已开启再以管理员身份运行 PowerShell执行wsl --update和wsl --set-default-version 2最后确认 Windows 功能里的“虚拟机平台”“适用于 Linux 的 Windows 子系统”两项都已经勾选需要重启的话就重启一次。装好并正常启动后建议在 Docker Desktop 的 Settings 里把资源调大一点比如内存给到 4GB 以上否则后面同时跑 MySQL、Redis、网盘等多个容器时会明显卡顿。另外一定要记住Docker Desktop 关掉意味着所有容器都会停止这和 Linux 上常驻后台的 Docker 引擎体验不同。2.2 Linux 端Ubuntu 和 CentOS 的 Docker 引擎安装Linux 服务器上通常安装 Docker 引擎docker-ceUbuntu 系列我推荐用官方源安装步骤如下先卸载系统里可能存在的旧版本docker、docker.io或podman接着安装依赖并添加 Docker 官方 GPG 密钥和 apt 仓库然后执行apt-get update和apt-get install docker-ce docker-ce-cli containerd.io。CentOS 系列思路类似只是包管理器换成了 yum先安装yum-utils再用yum-config-manager --add-repo添加官方仓库最后yum install docker-ce docker-ce-cli containerd.io即可。装完以后执行systemctl enable --now docker让 Docker 开机自启并立即启动。这里有个我反复提醒新手的点不要在 Linux 上一直用sudo docker。正确做法是把当前用户加入 docker 组执行usermod -aG docker $USER后重新登录这样后续命令就不用每次带sudo了。加完组如果执行 docker 命令还是报权限错误先注销重新进一次终端再说不用急着怀疑系统坏了。2.3 安装完先做三件事第一件事跑通docker run hello-world。这条命令会拉取一个测试镜像并启动容器只要看到一段英文欢迎信息说明引擎工作正常。第二件事检查docker info的输出重点看版本、容器数量、存储驱动这些信息。第三件事如果拉镜像很慢马上配置镜像加速这一步放到后面专门讲。3. 把常用命令练熟就能开始实战了3.1 核心命令速查镜像、容器、日志、清理一套搞定新手不需要背 Docker 的全部命令先把下面这张表里的练到肌肉记忆日常实战就够用了场景命令说明拉取镜像docker pull nginx:1.25指定镜像名和标签便于复现查看镜像docker images列出本地镜像及大小删除镜像docker rmi nginx:1.25删除前需先删除依赖它的容器运行容器docker run -d --name web -p 8080:80 -v web_data:/usr/share/nginx/html nginx后台运行、命名、端口映射、数据卷查看容器docker ps只显示运行中的容器加-a显示全部进入容器docker exec -it web bash进到容器里执行命令适合排查问题查看日志docker logs -f web持续输出日志排障必备停止容器docker stop web优雅停止删除容器docker rm -f web强制删除运行中的容器清理资源docker system prune清理停止的容器、无用网络和悬空镜像3.2 新手先记这三个“组合拳”第一套组合拳是启动一个容器并完成端口、数据卷、名称的一次性配置。比如启动 Nginxdocker run -d --name web -p 8080:80 -v web_data:/usr/share/nginx/html nginx:1.25。只要容器状态显示 Up浏览器访问http://localhost:8080能出现欢迎页你就已经完成了第一个部署。第二套组合拳是进入容器docker exec -it web bash。进入以后一定要记得镜像里的 shell 可能不同Debian 系是 bash精简镜像可能只有 sh。进不去的用docker exec -it web sh试试。进入容器的目的是查配置、看进程、临时验证但别养成在容器里乱装软件的习惯因为容器重建后这些改动全部消失。第三套组合拳是排查日志docker logs -f web。容器启动失败、端口不通、程序报错第一件事永远是看日志而不是凭感觉改参数。日志能解决 80% 以上的容器问题真正需要进容器里翻配置的场景反而很少。3.3 容器是临时角色别把它当成一台永久的服务器我刚接触 Docker 时犯过一个典型错误把一个运行中的容器当成虚拟机进去装了一堆调试工具改了配置后还觉得很顺手。直到某次清理环境执行docker rm -f把容器删掉才发现所有改动都没了那叫一个心疼。容器本身就是易失的设计初衷是“用完即焚”。所以配置、数据、日志这些需要保留的内容要么提前挂载数据卷要么在镜像层面解决而不要指望容器重启后还能保留现场。理解了这点后面学数据卷就顺理成章了。4. 镜像下载太慢加速器和镜像仓库配置是必修课4.1 为什么拉镜像会卡住默认情况下Docker 会从公共镜像仓库拉取镜像也就是大家常说的 Docker Hub。因为网络链路和访问延迟的原因在国内直接拉取经常会碰到超时、断流一个几百 MB 的镜像可能要下半小时体验非常差。这不是你电脑的问题也不代表 Docker 坏了只是因为默认仓库的访问链路不友好。解决思路很简单给 Docker 配置一个“镜像加速地址”让它从更快速可达的公共仓库拉取。这个操作在 Linux 和 Windows 上的做法不太一样但原理一致。4.2 修改 daemon.json 配置加速服务Linux 上编辑 Docker 守护进程配置文件/etc/docker/daemon.json如果文件不存在就新建加入如下内容{ registry-mirrors: [ https://docker.mirrors.ustc.edu.cn, https://hub-mirror.c.163.com ] }保存之后执行sudo systemctl daemon-reload sudo systemctl restart docker重启后敲docker info输出里应该能看到Registry Mirrors一栏说明加速配置已生效。Windows 的 Docker Desktop 要在 Settings 的 Docker Engine 选项卡里修改同一份 JSON 配置然后点击 Apply Restart。这里我要多说一句公共加速地址的可达性会随着时间变化有些地址可能镜像内容不全或者失效。我更推荐去你云的容器镜像服务控制台拿专属加速地址地址里会带你的账号 ID速度通常更稳。这类服务在控制台搜“容器镜像”、“镜像加速器”就能找到一般都有免费额度。4.3 进阶玩法自建镜像仓库和给镜像改标签团队里或者个人多台服务器之间也常用自建的镜像仓库。启动一个 registry 容器只需要一条命令docker run -d -p 5000:5000 --name registry registry:2然后给本地镜像重新打标签并推送到这个私有仓库docker tag nginx:1.25 localhost:5000/nginx:1.25 docker push localhost:5000/nginx:1.25其他服务器上只要执行docker pull localhost:5000/nginx:1.25就能拉取这个私有镜像。这个思路对团队协作很有用比如你用自己的 Dockerfile 构建好的镜像不想上传到公共仓库私有仓库就是一个靠谱选择。以后做 CI/CD 流水线这一步更是绕不开的。5. 数据挂载、端口映射和网络模型一次讲透5.1 容器删了数据就没了吗问题出在“可写层”上文中我一直强调容器是易失的根本原因在于容器拥有一个“可写层”。所有在容器运行时产生的文件都会写入这层容器一旦被删除可写层也会跟着销毁。如果你往 MySQL 容器里写入了一堆业务数据然后执行docker rm -f数据就真的没了连后悔药都不好找。解决办法是使用数据卷。在启动容器时通过-v参数把宿主机目录或命名卷挂载到容器内目录比如 MySQL 的官方镜像已经把数据路径明确为/var/lib/mysql启动时加-v mysql_data:/var/lib/mysql数据就会持久化到名为mysql_data的卷里。之后哪怕容器被删掉只要mysql_data卷还在重建一个容器挂载同样的卷数据原封不动。5.2 命名卷还是 bind mount按场景选-v mysql_data:/var/lib/mysql这种写法是命名卷卷由 Docker 管理目录位置不需要你去关心而-v /home/user/mysql-data:/var/lib/mysql这种写法是 bind mount直接把宿主机上的具体目录挂进容器。前者适合数据库这类“内容重要但不关心物理位置”的数据后者适合想直接在宿主机上查看、编辑配置文件的场景比如 Nginx 配置和日志。我个人的经验是Windows 上用命名卷更多因为 Windows 和 Linux 在路径和文件权限上有差异bind mount 容易遇到权限问题Linux 上用 bind mount 可能更直观编辑配置文件也方便。无论选哪种都要记住“容器可以一天重建八次数据一定要挂出来”。5.3 端口映射和 Docker 网络容器之间怎么互访-p 宿主机端口:容器端口是最常用的端口映射方式。这里要特别说明冒号后面的端口是容器内应用真正监听的端口不能随意改冒号前面的端口才由你分配宿主机上没被占用就行。比如开发环境下宿主机 3306 已被本机 MySQL 占用了就可以用-p 33061:3306连接。容器与容器之间通信默认有几个网络模式最常见的是 bridge 和 host。默认 bridge 网络下容器之间靠 IP 访问并不可靠因为容器重建后 IP 会变。更稳的做法是自建一个 bridge 网络让同网络下的容器可以直接用容器名互访docker network create app-net docker run -d --name mysql8 --network app-net mysql:8.0 docker run -d --name kodbox --network app-net kodcloud/kodbox这样 kodbox 里连接数据库时主机地址直接写mysql8就能解析到对应容器完全不用关心 IP 是多少。这个配置方式在 Docker Compose 里更是默认行为想不明白容器网络问题的人我建议重点体会这句话容器名前缀 自定义网络 容器世界的 DNS。6. 从手敲命令到一键编排Docker Compose 实战部署6.1 为什么需要 Compose当你要跑一个 MySQL、一个 Redis、再加一个应用命令会变得非常多且容易遗漏。这时候就要用 Docker Compose。它把多个容器的启动方式写进一个 YAML 文件一条docker compose up -d就能把整套服务拉起来。用大白话说Compose 就是你整个项目服务的“启动清单”。安装 Docker 时一般会自带 Compose 插件执行docker compose version能输出版本号就代表可用。没有的话去官方文档按平台安装即可。老版本中独立的docker-compose命令也还能用但新项目我建议统一用docker compose。6.2 一次搞定 MySQL 8.0 和 Redis 主从下面是一个可以直接保存的docker-compose.yml示例包含 MySQL 8.0、Redis 主节点和 Redis 从节点所有服务都在同一个自定义网络里services: mysql: image: mysql:8.0 container_name: mysql8 restart: always environment: MYSQL_ROOT_PASSWORD: your-password TZ: Asia/Shanghai ports: - 3306:3306 volumes: - mysql_data:/var/lib/mysql networks: - app-net redis-master: image: redis:7.0 container_name: redis-master restart: always command: redis-server --appendonly yes ports: - 6379:6379 volumes: - redis_master_data:/data networks: - app-net redis-slave: image: redis:7.0 container_name: redis-slave restart: always command: redis-server --replicaof redis-master 6379 depends_on: - redis-master ports: - 6380:6379 volumes: - redis_slave_data:/data networks: - app-net volumes: mysql_data: redis_master_data: redis_slave_data: networks: app-net:启动命令就一条docker compose up -d。执行后 MySQL 跑在 3306 端口Redis 主节点在 6379从节点映射到 6380。外部程序开发时连localhost:3306Redis 连localhost:6379容器之间的内部通信则用服务名mysql、redis-master和redis-slave。验证 Redis 主从是否生效执行docker exec -it redis-slave redis-cli info replication看到role:slave并且master_link_status:up就是正常的。MySQL 验证则进入容器执行docker exec -it mysql8 mysql -uroot -p输入密码后能进入命令行就说明部署成功。6.3 再加一个 kodbox 网盘服务Compose 的扩展非常方便。假如你还要部署一个 kodbox 网盘只需要在services下追加一段kodbox: image: kodcloud/kodbox container_name: kodbox restart: always ports: - 8080:80 volumes: - kodbox_data:/var/www/html networks: - app-net然后在文件末尾的volumes里加上kodbox_data:执行docker compose up -d浏览器访问http://localhost:8080就能进入 kodbox 的初始化安装界面。数据库地址在安装向导里填mysql而不是localhost因为 kodbox 和 MySQL 在同一个 Compose 网络里必须通过容器名通信。这个例子也说明了为什么 Compose 适合“个人或小团队”使用扩容、重建、迁移都很快迁移时只要把 Compose 文件和数据卷一起带走在另一台机器上执行同一份文件整套服务就直接复现了。7. 新手最容易踩的坑与排查思路7.1 常见问题速查表我把这几年看到的高频问题整理成下面的速查表遇到问题先对号入座现象原因解决方案permission denied ... docker.sock当前用户不在 docker 组执行sudo usermod -aG docker $USER后重新登录Cannot connect to the Docker daemon引擎没启动或 daemon.json 语法错误systemctl status docker查看状态检查 JSON 配置port is already allocated端口被占用换一个宿主机端口或用docker ps找占用容器的进程容器启动后立刻退出前台进程执行完毕或启动异常docker logs看报错别急着反复启动dial tcp: lookup ... i/o timeout拉镜像超时检查镜像加速配置确保已重启 DockerDocker Desktop failed to start because virtualisation support wasnt detectedWindows 虚拟化或 WSL2 未正确启用开 BIOS 虚拟化启用虚拟机平台执行wsl --updateexec format error镜像架构与宿主机架构不一致拉取匹配架构的镜像或用 buildx 构建多架构镜像7.2 日志和 inspect 是排障的两把钥匙遇到任何容器行为诡异第一反应应该是docker logs 容器名。启动失败、连接不上、配置错误日志里基本都会留下线索。如果日志看不出来再用docker inspect 容器名查看容器的详细配置环境变量、挂载卷、网络模式、启动命令全都一目了然。还有一条隐藏技能docker exec -it 容器名 /bin/sh进去以后先看进程列表再看配置文件最后看日志文件。比如 MySQL 连接失败进去之后确认一下 mysqld 进程是否存在、监听端口是否为 3306往往比反复排查外部网络更快定位问题。7.3 几条我在实战中总结的保命习惯第一不要在生产环境用latest标签拉镜像。镜像更新不可控题头写mysql:8.0都比写mysql:latest靠谱至少版本范围清晰。第二容器时区默认是 UTC数据库和应用经常差 8 个小时。启动 MySQL 时加环境变量TZAsia/Shanghai其他应用也建议设置同样的时区避免半夜数据上报时间对不上。第三别在容器里跑一个“不干正事”的主进程Docker 容器存在的基础是里面有一个前台进程如果这个进程退出了容器就结束。所以调试时即使进入容器开了 bash也不要轻易关掉原进程。我当初学 Docker 时最容易犯的错误就是把它当虚拟机用后来又花了很多时间在镜像加速上。回头来看最有效的学习路径是装好环境跑通hello-world启动一个 Nginx 并访问成功部署 MySQL 并写入数据使用 Compose 把 MySQL、Redis 主从和 kodbox 一起编排起来。走完这一遍Docker 对你来说就不再是概念问题而是每天都能用的工具了。之后再去看 Dockerfile、buildx 多架构构建、Kubernetes 这些进阶内容都会顺畅很多。本文还有配套的精品资源点击获取
返回列表