
我直接用一句话回答这个标题背后最核心的问题Docker不只是一个软件它是一整套围绕“镜像、容器、仓库、网络、数据卷、编排”构建的容器化技术体系。很多人一上来就在Windows上装了个Docker Desktop打开界面发现有个大大的鲸鱼图标然后就不知道下一步该干嘛了。也有人买了服务器照着教程一行一行敲命令装是装上了但“docker包括哪些内容”这个问题依然很模糊。这篇文章我就按自己这些年实际使用的经验把Docker的完整组成、安装方式、常用命令、真实部署案例以及高频故障排查一次讲透适合刚入门的同学也适合那些已经装好Docker但总觉得没真正“会用”的人。1. 先拆清楚Docker到底“包括”哪些东西要理解Docker别急着背命令先把它的组成模块搞清楚。Docker本身可以拆成两大部分一部分是软件架构层面的组成也就是它的客户端、服务端、守护进程另一部分是使用层面的对象模型也就是镜像、容器、网络、数据卷这些概念。这两层都有你对Docker的认知才算完整。1.1 镜像Docker世界里的“安装包”和“模板”镜像Image是整个Docker体系的地基。一句话解释镜像是一个只读的、分层的文件系统模板里面装好了操作系统的基础文件、运行时、依赖库、应用程序代码以及启动配置。我经常给朋友打一个比方镜像就像盖房子用的“预制板图纸”。它不是房子本身但拿着它能造出无数栋一模一样的房子。你拉取一个MySQL镜像本质上是把一套已经配置好的MySQL运行环境打包到了本地之后每次基于它创建容器都会得到一个同样运行环境的MySQL实例。镜像有个非常关键的特性——分层存储。你在网上看到的很多Dockerfile每一行指令都会生成一个新层。因为层可以被复用所以多个镜像可以共享底层比如两个Python应用镜像可以共享同一个Python基础层这既省磁盘空间又加快拉取速度。实操感悟用docker image inspect可以看到镜像的具体分层信息生产环境里我经常用这个命令去排查镜像臃肿的原因。如果你发现某个镜像体积异常大八成是Dockerfile里某些层把临时文件、缓存也提交进去了。1.2 容器镜像跑起来后的“运行实例”容器Container是镜像的运行时实例。镜像本身是只读的容器则在镜像之上加了一层可写层。还是用盖房子类比镜像是一套图纸加预制件容器就是按这套图纸实际盖好的房子。你可以在房子里改装修、放家具所有改动都会落在容器自己的可写层里。但你删掉这个容器改动也随之消失除非你提前把数据放到了数据卷里。容器的生命周期也是Docker包括的核心内容创建create、启动start、停止stop、重启restart、删除rm。日常用得最多的是docker run它等于“创建启动”合并执行。容器之间相互隔离进程、网络、文件系统彼此独立但也可以通过指定参数共享网络或数据卷这就是后面要说的编排基础。实操感悟别把容器当成虚拟机去管理。虚拟机里你登录系统、装各种软件、长期运行容器讲究“用完即走”状态最好都放到数据卷里容器本身随时可以删掉重建这才是云原生理念下推荐的做法。1.3 仓库、Dockerfile、数据卷、网络剩下的几块拼图仓库Registry是存放镜像的服务端。Docker Hub是最常用的公共仓库企业里也常用私有仓库比如Harbor。命令docker pull就是从仓库拉取镜像docker push是上传镜像。你可以把仓库理解为“应用商店”所有镜像的分发都靠它。Dockerfile是构建镜像的“配方文件”。它用一批指令告诉Docker怎么一步步把应用和依赖打成镜像。Dockerfile并不是Docker运行时的必需部分但它是Docker使用体系中最重要的部分之一因为没有它你就没法生成属于自己的镜像。数据卷Volume解决的是持久化问题。容器删除后数据默认丢失Volume可以把宿主机目录挂载到容器内部容器写数据实际写入宿主机容器毁了数据还在。网络Network是容器通信的基础。Docker内置了bridge、host、none等网络模式还可以自定义网络让多个容器通过容器名互相访问。一句话总结整个体系Dockerfile负责“造镜像”仓库负责“传镜像”镜像负责“定义模板”容器负责“跑应用”Volume负责“保数据”Network负责“通网络”。把这几个对象理解清楚Docker就算入门一半了。2. 安装DockerWindows与Linux的完整操作与踩坑记录安装Docker看起来很简单实际踩坑的人非常多。尤其是Windows用户经常会卡在“Virtualization support not detected”这一步后面我会专门讲怎么处理。先按平台把安装过程完整梳理一遍。2.1 Windows下安装Docker Desktop与关键前置条件Windows安装Docker的主流方式是装Docker Desktop它自带图形界面还集成了Docker Engine、Compose插件等一整套东西。需要注意Docker Desktop不是所有Windows版本都能直接装它要求Windows 10/11 64位专业版、企业版或教育版家庭版需要额外开启Hyper-V或安装WSL2。我在实际安装中的一个建议顺序是这样的先去“控制面板→程序→启用或关闭Windows功能”确认勾选“适用于Linux的Windows子系统”和“虚拟机平台”。在PowerShell里执行wsl --install把WSL内核装好然后重启电脑。从Docker官网下载Docker Desktop安装包双击安装安装过程中保持默认选项即可。安装完成后打开Docker Desktop如果一切正常右下角鲸鱼图标会常驻不再转圈。安装完成后可以在命令行里敲docker version验证。如果Client和Server两部分都输出了版本号说明安装成功。提示Docker Desktop只写进了Windows但Docker引擎实际跑在WSL2的Linux虚拟机里。这也是为什么Docker Desktop要求“虚拟机平台”和“WSL2”两个功能必须打开。如果启动过程一直报错优先检查的就是这两项。还有很多人问“Docker Desktop能不能装到D盘”——可以装但要注意WSL2的虚拟磁盘默认在C盘时间长了C盘会被占掉几十甚至上百GB。解决办法是启动WSL2后用wsl --export和wsl --import把发行版迁移到其他盘并且可以在Docker Desktop的设置里修改镜像存储位置。这个细节很多人不知道等C盘红了才来后悔。2.2 Linux下安装Docker Engine从Ubuntu到CentOSLinux服务器上通常装的是Docker Engine比Docker Desktop更轻没有界面纯命令行操作。Ubuntu和CentOS安装命令略有差异但思路一致设置仓库、安装docker-ce包、启动服务。Ubuntu推荐用官方源安装方式sudo apt-get update sudo apt-get install ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod ar /etc/apt/keyrings/docker.gpg echo deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release echo $VERSION_CODENAME) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginCentOS 7服务器的同学需要注意CentOS 7自带的yum源里Docker版本很老建议先卸载旧版本然后添加官方yum源再安装。如果系统是企业内部环境没法访问外网那就是另一个话题了但思路是离线安装rpm包。Linux安装后的第一件事是启动服务并设为开机自启sudo systemctl enable docker --now docker version2.3 权限问题为什么每次都要加sudoLinux安装完Docker后如果你执行docker ps报权限错误是因为当前用户不在docker用户组里。解决办法是sudo groupadd docker sudo usermod -aG docker $USER然后注销重新登录或者执行newgrp docker让组权限立即生效。这个操作做完之后就不用每次敲sudo了。实测心得我见过太多新手一直被权限问题卡住以为是Docker装坏了。其实Docker守护进程默认是root权限运行的普通用户想访问它的socket必须加入docker用户组。这条命令解决完基本一劳永逸。2.4 安装后必做的三件事验证、配镜像源、确认自启动安装完别急着拉镜像先做三件事第一验证环境。docker run hello-world这个命令会拉取一个测试镜像并运行如果输出了一系列说明文字说明整个链路是通的。第二配置镜像加速。国内直接拉取Docker Hub的镜像经常很慢建议在Docker的配置里加上可信的镜像加速地址。这个不同环境配置方式不同Docker Desktop在Settings里改Linux直接编辑/etc/docker/daemon.json改完重启docker服务。第三确认开机自启。Linux执行sudo systemctl enable dockerWindows的Docker Desktop默认会跟随开机启动不想要的可以在设置里关掉。3. 日常高频命令与真实部署实战Docker命令非常多但日常你真正高频用到的其实就十几个。我把它们按类别整理出来再结合两个热门的实战场景部署MySQL 8.0和搭建Redis主从把整个操作流程走一遍。3.1 和镜像、容器打交道的命令谱系镜像相关docker images查看本地镜像列表docker pull nginx拉取镜像docker rmi nginx删除镜像docker build -t myapp:1.0 .用Dockerfile构建镜像并打标签容器相关docker ps查看运行中的容器加-a查看所有容器docker run -d -p 8080:80 --name web nginx后台运行一个nginx容器把宿主机8080端口映射到容器80端口docker exec -it web bash进入容器内部相当于ssh到一台机器上docker logs -f web实时查看容器日志这是排查问题最重要的命令docker stop 容器名/docker start 容器名停止和启动docker rm 容器名/docker rmi 镜像名删除容器和镜像其他docker inspect查看容器或镜像的详细信息包括IP、挂载卷、环境变量docker stats实时查看容器的CPU和内存占用这些命令覆盖了日常95%以上的操作。不需要背那么多用熟这几个就能完成从部署到排查的完整闭环。3.2 实战用Docker部署MySQL 8.0并持久化数据部署MySQL是Docker最常见的需求之一。很多教程直接丢一条命令让你跑跑完了是能启动但容器一删数据全没了。这里给出一个完整、规范的做法。首先创建数据存储目录和配置文件目录mkdir -p /opt/mysql/{data,conf}然后编写配置文件vim /opt/mysql/conf/my.cnf内容可以按需写基础配置如下[mysqld] character-set-serverutf8mb4 collation-serverutf8mb4_unicode_ci default-storage-engineINNODB max_connections512保存后运行容器docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDYourPwd123 \ -v /opt/mysql/data:/var/lib/mysql \ -v /opt/mysql/conf/my.cnf:/etc/mysql/conf.d/my.cnf \ --restartalways \ mysql:8.0这条命令里有几个参数值得单独说-e MYSQL_ROOT_PASSWORD是初始化数据库时设置root密码的环境变量只对首次初始化生效。-v /opt/mysql/data:/var/lib/mysql把宿主机目录挂载到容器数据目录这是数据持久化的核心。容器删了、重建了数据都还在。--restartalways让容器在Docker重启或自身崩溃后自动拉起生产环境基本都要加。-p 3306:3306是端口映射宿主机的3306对到容器内MySQL的3306。启动完成后用docker ps确认状态然后用客户端连接测试docker exec -it mysql8 mysql -uroot -p踩坑提醒如果你宿主机3306端口已经被占用启动会报端口冲突。换个宿主机端口即可比如-p 3307:3306。另外MySQL 8.0默认认证插件是caching_sha2_password如果你用旧版客户端连接可能会报认证失败需要修改用户认证方式为mysql_native_password。3.3 实战Redis主从架构的一次快速搭设很多人问“docker安装redis主从”其实用Docker搭Redis主从非常轻松核心就三步先跑一个主节点再跑一个从节点最后让从节点指向主节点。这里我采用自定义网络的方式让两个容器可以通过容器名互通docker network create redis-net启动主节点docker run -d --name redis-master --network redis-net -p 6379:6379 redis:7 redis-server --appendonly yes启动从节点docker run -d --name redis-slave --network redis-net -p 6380:6379 redis:7 redis-server --appendonly yes --slaveof redis-master 6379注意从节点里的--slaveof redis-master 6379用的不是IP而是容器名。在自定义网络中Docker自带的DNS解析能做到容器名互通这就是为什么我要先建网络的原因。验证主从状态docker exec -it redis-master redis-cli info replication输出里role:master和connected_slaves:1就说明主从搭建成功。你可以登录主节点写几个key再到从节点查数据已经同步过去了。这个例子很小但背后反映的是Docker的编排能力通过自定义网络让容器之间“以名寻址”通过redis-server命令行参数传递配置。这些思路放大到微服务场景里是完全一致的。4. 数据卷、网络与编排让容器“互通”和“不死”前面讲了镜像和容器的基础操作现在往深走一层容器之间怎么通信、数据怎么持久化、多容器应用怎么统一管理。这三块正是“docker包括那些内容”这个问题的进阶答案。4.1 数据卷容器删除后数据不丢的机制数据卷Volume是Docker持久化的核心机制。前面MySQL实战里用了bind mount方式也就是把宿主机目录直接挂进容器。此外还有一种叫“具名卷”的方式由Docker自行管理目录docker volume create mysql_data docker run -d -v mysql_data:/var/lib/mysql mysql:8.0具名卷的好处是用docker volume ls就能统一查看管理而且目录位置由Docker托管不用关心它到底在哪。bind mount的好处是配置文件可以直接改宿主机文件改动即时生效适合挂配置。两者各有适用场景。为什么强调数据卷因为容器是“一次性”的。升级镜像、迁移服务器、程序崩溃重建都需要删除旧容器。如果数据写在容器内部可写层删除容器等于删除数据。我在生产环境见到太多教训Redis没开持久化、MySQL没挂数据卷容器一删数据全没了只能找备份或者认栽。4.2 网络模式bridge、host、none与自定义网络Docker网络是初学者最容易懵的部分。记住一个简化模型就行默认bridge网络容器有自己的独立IP通过NAT方式访问外网。不同容器只要在同一网络中就能通过IP互相访问但容器重建后IP会变所以生产环境不建议直接依赖IP通信。host网络容器直接共享宿主机网络栈没有独立IP端口直接占用宿主机端口。性能损耗最低但隔离性差不适合多容器部署。none网络容器没有网络配置适合完全不需要网络的任务。自定义bridge网络这是我最推荐的模式。除了具备默认bridge的一切能力它额外提供了容器名DNS解析功能。你不需要关心容器IP是什么直接用名字访问就行。后端的微服务调用、主从同步、集群内部通信应该优先用自定义网络。验证容器间通信也很简单docker exec -it redis-slave ping redis-master能通就说明网络配置正确。4.3 微服务编排从docker run到docker compose手动执行docker run搭一两个容器还行如果系统有五六七八个服务一个个敲命令、一个个记忆参数很快会疯。Docker Compose就是来解决这个问题的。Compose的核心是一个docker-compose.yml文件把跨容器的配置一体化描述出来。举个例子一个简易的Web应用用到了nginx和redisversion: 3.9 services: nginx: image: nginx:latest ports: - 80:80 volumes: - ./html:/usr/share/nginx/html restart: always redis: image: redis:7 container_name: redis ports: - 6379:6379 restart: always然后执行docker compose up -d两个服务就会一起启动并自动加入同一个默认网络通过服务名互相访问。停掉所有服务执行docker compose down。使用心得Compose非常适合开发环境和中小型项目。它不需要学Kubernetes那么重的编排体系但又把“多个服务如何协同启动”这个核心问题解决了。等哪天服务数量多到需要水平扩容、滚动更新时再考虑上Kubernetes也不迟。5. 常见问题排查实录这部分我把自己实际遇到过的、以及社区里被高频讨论的问题都整理了一遍按“现象→原因→处理”的方式写出来。直接按列表查就行。5.1 启动失败Virtualization support not detected与WSL2问题这个报错几乎每个Windows安装Docker Desktop的人都会遇到。它出现的原因很明确Windows没有检测到硬件虚拟化或虚拟机平台没有开启。处理流程按顺序排查打开任务管理器→性能→CPU看右下角“虚拟化”是不是“已启用”。如果是“已禁用”需要进BIOS把Intel VT-x或AMD-V打开。确认“虚拟机平台”和“适用于Linux的Windows子系统”两项Windows功能已勾选。确认WSL2是默认版本PowerShell里执行wsl --set-default-version 2。如果以上都正常还报错建议执行wsl --update然后重启电脑。还有种情况是Docker Desktop提示启动中然后卡死多半是WSL2发行版损坏。可以执行wsl --shutdown后重试不行就重新导入发行版。提示Windows家庭版用户尤其容易出现这个问题因为家庭版默认不带Hyper-V管理功能虽然WSL2不受影响但Docker Desktop对系统的检测有时比较严格。实在装不上可以考虑直接在系统里独立安装WSL2环境然后在WSL2内部安装Docker Engine效果一致。5.2 镜像拉不下来、下载速度慢怎么办这个问题的根源是网络环境导致访问Docker Hub不稳定。思路是配置国内镜像加速源具体做法前面2.4节已经提过。如果加速源也拉不动某些镜像还有个土办法用较小体积的替代镜像。比如把node:latest换成node:alpine体积能小好几倍。alpine版的镜像是基于Alpine Linux的体积小、拉取快、安全性也不错很适合生产环境。还有一种情况是Dockerfile构建过程卡在拉取基础镜像阶段这时候除了耐心等待也建议尽量选择已经被大量使用的基础镜像拉取更快质量也更可信。5.3 容器网络不通怎么排查“docker网络不通”是出现频率极高的关键词处理思路按顺序排查第一层确认容器是否在正常运行。docker ps看状态容器没起来当然不通。第二层查容器日志。docker logs 容器名很多所谓“网络不通”其实是应用本身启动失败。第三层查端口映射。docker port 容器名能看到宿主机的端口映射关系。如果访问的是宿主机IP加端口确认映射是否正确。第四层进容器内部测试。docker exec -it 容器名 bash进去后ping自己的网关、ping宿主机、ping外网逐段判断是哪一层断了。第五层检查防火墙和安全组。宿主机防火墙可能拦截了映射端口云服务器则要看安全组策略有没有放行对应端口。很多人查了半天容器配置最后发现是云控制台端口没开。5.4 服务启动失败、权限错误、磁盘占用等零碎问题容器启动后立刻退出用docker logs看日志绝大多数时候是应用启动命令有问题。另外也可能是前端进程不是常驻进程比如直接跑一个shell脚本脚本执行完容器就退了。可以加-it参数保持交互或者把应用改为前台运行。docker命令提示权限错误2.3节已经给了处理方法加入docker用户组重新登录即可。磁盘空间被镜像和容器占满常见的原因是容器日志无限增长。在Docker配置里加日志轮转限制是个好办法{ log-driver: json-file, log-opts: { max-size: 20m, max-file: 5 } }然后重启Docker服务。另外定期清理悬空镜像和停止状态的容器docker system prune -a这个命令会清理所有不用的镜像、容器、数据卷执行前确认好用完就没法恢复了。6. 我把时间花在哪些地方才算真正“会了Docker”写到这里我把Docker包括的各个模块基本覆盖了一遍最后说点务实的个人体会。Docker不是一门需要“学完”才能用的技术它更像一把工具。你先装好它拉个镜像跑起来再试着自己写Dockerfile做一个镜像接着把数据卷和网络机制搞懂最后用Compose把两三个服务编排起来——整个学习的路径是环环相扣的不需要一步到位。我自己在实际操作中的体会是能不能把常规项目用Docker部署跑通比背多少命令更重要。命令忘了随时可以查docker --help或者上网检索但思路忘了一次排查问题要浪费的时间可不止半小时。如果你现在正准备从零开始接触Docker我的建议很具体今天先把Docker装好跑一个nginx容器访问一下页面明天部署一个MySQL挂上数据卷把数据持久化搞定后天再搭一个Redis主从。三天下来你已经能应付90%的日常Docker使用场景了。剩下那些复杂问题遇到了再查查完再动手这个过程才是最快的进步方式。