Docker入门到实战:镜像、容器、数据卷与部署全攻略 1. 先把Docker这玩意儿说清楚聊Docker之前先说个场景。你花了半天时间搭好一套环境MySQL、Redis、Nginx、应用服务全部调通项目跑得正欢。结果换台电脑或者同事入职要复现这套环境你又得从头开始——装系统依赖、配环境变量、改配置文件、折腾版本兼容。运气好两小时搞定运气不好一下午就没了。Docker就是解决这个问题的。从本质上看Docker 是一种操作系统层面的虚拟化技术。它不像 VMware 那样虚拟出一整套硬件和操作系统而是直接复用宿主机的内核把应用连同它依赖的运行环境一起打包成一个标准单元。这个单元你随时可以启动、复制、分发不管底层是 Windows 还是 Linux只要装了 Docker跑起来的行为完全一致。很多人第一次接触 Docker 会把它理解成一个轻量级虚拟机这个理解方向没错但不完全准确。虚拟机需要模拟完整的硬件再在硬件上装完整的操作系统光启动就够喝一壶的。Docker 容器不一样它只是用一个隔离机制把进程圈起来启动一个容器就是启动一个进程秒级完成。这也是为什么它适合微服务架构的原因——服务拆得再细拆出一百个容器来Docker 都能扛住。Docker 能解决的问题用一句话概括就是环境一致性。开发环境、测试环境、生产环境以前是三个环境三种配置每换一个环境就要处理一次环境差异的破事。现在把环境和应用一起打包成镜像走到哪都是同一套不折腾。适合读者主要分几类开发人员每天要和 MySQL、Redis、Nginx 这些基础组件打交道不想在自己的机器上装一堆乱七八糟的依赖用 Docker 拉个镜像就能跑。运维和实施人员要频繁部署项目、发布版本用 Docker 打包部署比传统的发布流程省事太多。在家折腾技术的新手想在自己电脑上搭个靶场、装个团队协作工具、研究某个开源项目Docker 是最快的路径。这篇文章从安装讲起把镜像、容器、数据卷、网络这些核心概念全部梳理一遍再带两个实操案例MySQL 和 Redis 主从最后把我踩过的坑整理成问题排查清单。全程用大白话看完照着敲就能跑。2. 安装Docker之前先把这几个概念刻在脑子里2.1 镜像和容器一个是模板一个是实例镜像Image和容器Container是 Docker 体系里最核心的两个概念很多新手栽跟头就栽在没搞清楚这俩的区别上。你可以把镜像理解成做蛋糕的模具容器就是用模具做出来的蛋糕。模具本身不能吃但它定义了蛋糕的形状和配方容器是活的可以启动、停止、删除删了之后再从模具里再做一个新的。镜像是只读的模板容器是镜像运行时的实例。当你执行docker pull mysql:8.0Docker 会从镜像仓库把 MySQL 8.0 的只读模板拉到你本地。执行docker run mysql:8.0时Docker 会基于这个模板创建一个可写的容器层然后启动容器里的主进程。你在容器里做的任何修改比如往 MySQL 里写了数据都保存在容器层。一旦容器被删除这个可写层也跟着没了。这里就能引出第一个重要的实操教训注意不要往容器里存重要数据。容器是随时可以删除重建的数据写进容器里等于写在沙子上。数据必须通过数据卷Volume或目录挂载的方式持久化到宿主机。2.2 镜像分层为什么拉同一个镜像第二次特别快Docker 镜像不是一个大文件而是一层一层的只读文件系统叠加组成的。拉取镜像时Docker 会检查本地已有的层只下载缺失的层。举个例子你拉了一个mysql:8.0然后又要拉mysql:8.0.36。这两个镜像底层的基础层比如基于某个 Linux 发行版几乎是相同的Docker 发现本地已经有这些层就直接复用只拉取真正不同的几层。这也是为什么很多人在同一台机器上拉不同版本的镜像越拉越快的根本原因。镜像分层的设计很有实际价值。你基于某个基础镜像构建自己的应用镜像时如果只改了应用代码重新构建时 Docker 会缓存之前没变过的层只重新构建有变化的层。这个机制用的好构建速度能快几十倍。2.3 容器端口映射为什么容器里的服务外面访问不到这是个高频问题。你在容器里跑了一个 Nginx容器内监听 80 端口但宿主机上访问http://localhost:80却打不开。原因很简单容器有自己独立的网络命名空间容器内的 80 端口宿主机是看不到的。要让宿主机能访问容器内的服务必须做端口映射。启动容器时加参数-p 宿主机端口:容器端口比如-p 8080:80意思就是把容器内 80 端口的流量转发到宿主机的 8080 端口上。访问宿主机 8080 端口就相当于访问容器内的 80 端口。这个概念不搞清楚后面所有容器化部署都会卡壳。牢记两件事一是端口映射靠-p或-P参数二是映射的宿主机端口不能冲突同一台机器上两个容器不能同时映射同一个宿主机端口。2.4 数据卷让数据脱离容器而存在数据卷是 Docker 提供的一种持久化机制。它可以是 Docker 管理的卷Volume也可以是宿主机上的一个目录Bind Mount。容器启动时用-v参数把数据卷挂载到容器内某个路径容器内对这个路径的读写操作会直接落到宿主机上。挂载之后的好处立竿见影容器删了数据还在想升级镜像版本旧容器删掉用新镜像起一个新容器挂载同样的数据卷数据无损。不夸张地说没有数据卷的 Docker 是没有灵魂的。后面实操环节我会演示 MySQL 数据持久化的具体挂载方式。3. Windows 和 Linux 上的安装实操3.1 Windows 装 Docker Desktop最容易踩坑的一步Windows 上装 Docker 绕不开 Docker Desktop这玩意儿是一个带图形界面的 Docker 管理工具。安装文件去官网下载即可双击安装。但很多人装完一启动直接弹一个红色报错Docker Desktop failed to start because virtualisation support wasn‘t detected.这个报错是 Windows 环境最著名的 Docker 安装拦路虎。原因基本锁定在三个方向原因一CPU 虚拟化没开启。重启电脑进 BIOS找到 Intel Virtualization TechnologyIntel VT-x或 AMD SVM 选项改成 Enabled保存重启。这一步是绝大多数人卡住的地方。进 BIOS 的方式各品牌不一样绝大多数是开机时狂按 Del 或 F2部分联想或戴尔是 F12 或 FnF12。原因二Hyper-V 功能没启用。Docker Desktop 依赖 Windows 的 Hyper-V 虚拟机平台。启用方法控制面板 → 程序和功能 → 启用或关闭 Windows 功能 → 勾选 Hyper-V 和 “虚拟机平台” 和 “适用于 Linux 的 Windows 子系统”确定后重启。原因三WSL2 没安装或版本太旧。新版 Docker Desktop 底层使用 WSL2Windows Subsystem for Linux 2需要以管理员身份打开 PowerShell 执行wsl --update wsl --set-default-version 2执行完再启动 Docker Desktop绝大多数问题都能解决。还有一个比较隐蔽的坑如果你装了第三方杀毒软件或电脑管家它们可能干扰 Hyper-V 的运行。实在找不到原因时可以试试暂时退出安全软件看能不能启动。3.2 Windows 老版本系统的问题部分老旧 Windows 10 版本在安装 Docker Desktop 时会提示We’ve detected that you have an incompatible version of Windows.Docker Desktop 对 Windows 版本有最低要求一般是 Win10 2004 及以上版本且需要 64 位系统。遇到这个问题优先去 Windows Update 把系统更新到最新版本。如果电脑确实太老硬件不支持虚拟化那 Docker Desktop 这条路基本走不通可以考虑装一个 Linux 虚拟机在虚拟机里用 Docker Engine。3.3 Ubuntu / CentOS 上安装 Docker EngineLinux 服务器上用 Docker 通常不装 Docker Desktop而是直接安装 Docker Engine。Ubuntu 系的安装命令比较统一sudo apt update sudo apt install -y ca-certificates curl gnupg lsb-release curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-pluginCentOS 7 的老用户需要注意CentOS 7 自带的 Docker 版本可能太旧需要先卸载旧的sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine然后安装依赖并配置 Docker 官方源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 docker-compose-plugin安装完成后启动服务并设置开机自启sudo systemctl start docker sudo systemctl enable docker验证是否装好执行docker version能看到 Client 和 Server 两段信息就说明服务已经在跑了。如果只有 Client 信息没有 Server说明 Docker 服务没启动成功需要看服务状态排查。3.4 Docker 镜像下载慢的解决方案装好 Docker 之后第一个实际操作就是拉镜像。国内网络环境下直接拉官方镜像仓库Docker Hub的速度一言难尽几百 MB 的镜像动辄要几个小时。解决办法是配置镜像加速器。打开 Docker Desktop 的设置Settings → Docker Engine在 JSON 配置里加一行registry-mirrors{ registry-mirrors: [ https://docker.m.daocloud.io, https://dockerproxy.com, https://docker.mirrors.ustc.edu.cn ] }保存后 Docker 会自动重启。这个配置的作用是让 Docker 优先从国内镜像源拉取速度会有质的提升实测从几 KB/s 变成几 MB/s 是常态。Linux 上配置方式类似编辑/etc/docker/daemon.json文件{ registry-mirrors: [https://docker.m.daocloud.io] }然后重启 Dockersudo systemctl daemon-reload sudo systemctl restart docker需要特别提醒的是镜像加速器只对 Docker Hub 官方镜像有效。有些仓库里的镜像本身就不在国内加速器也无能为力这种情况就只能换源或者用其他途径了。4. Docker 常用命令和核心玩法4.1 镜像和容器的基本操作命令命令不用背但常用的必须要熟练。我按使用频率从高到低整理了一遍镜像相关docker search mysql # 搜索镜像 docker pull mysql:8.0 # 拉取镜像版本号可省略省略时拉 latest docker images # 查看本地镜像列表 docker image rm mysql:8.0 # 删除镜像先把基于它的容器删掉容器相关docker ps # 查看正在运行的容器 docker ps -a # 查看所有容器包括已停止的 docker run -d --name my-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD123456 mysql:8.0 docker exec -it my-mysql bash # 进入容器内部后面的 bash 表示执行一个 shell docker logs -f my-mysql # 滚动查看容器日志 docker stop my-mysql # 停止容器 docker start my-mysql # 启动已停止的容器 docker rm my-mysql # 删除容器删除前必须先 stopdocker run的参数比较密集拆开说几个最常用的-d后台运行。不加这个参数容器会挂在前台CtrlC 就会退出容器。--name给容器命名。不命名的话 Docker 会随机生成一个名字管理起来不方便。-p端口映射格式是宿主机端口:容器端口。-e设置容器内的环境变量。像 MySQL 这种镜像root 密码就是通过环境变量传进去的。-v数据卷挂载格式是宿主机路径:容器内路径。--restartalways容器挂了自动重启生产环境部署服务建议加上。4.2 docker exec进入容器内部操作开发调试时最常用的命令之一。容器在后台跑着你想看看里面的文件结构、手动执行某个 SQL或者排查程序日志都得靠它。docker exec -it my-container bash-i表示交互式操作-t分配一个终端。合起来用就是打开一个交互终端进入容器内部。进去之后你会发现容器内部就是一个精简版的 Linux 系统但很多基础命令可能没有。比如官方的 Alpine 镜像连 bash 都没有只能用shdocker exec -it my-container sh有些镜像更精简连ls、cat这些命令都没有。遇到这种情况要么用docker logs看日志要么就在构建镜像时自己装需要的工具。这也是 Docker 镜像能做得特别小的原因——不需要的东西一概不留。4.3 docker-compose一键编排多个容器单个容器用docker run就够了但真实的项目通常是一堆服务应用容器、数据库容器、缓存容器、消息队列容器。每个都用docker run命令去启动参数又长又容易记错更别提交互依赖了。docker-compose 就是干这个的。它在项目根目录放一个docker-compose.yml文件把所有服务的配置写进去然后执行docker-compose up -d一条命令所有服务全部启动。我见过最典型的场景是搭一套 Dify一个开源的 LLM 应用开发平台用一个 compose 文件定义后端服务、前端服务、PostgreSQL、Redis、向量数据库等七八个容器全部一键拉起来。一个最小的 MySQL Redis 组合的 compose 文件大概长这样version: 3 services: mysql: image: mysql:8.0 container_name: my-mysql ports: - 3306:3306 environment: MYSQL_ROOT_PASSWORD: 123456 volumes: - ./mysql-data:/var/lib/mysql restart: always redis: image: redis:7 container_name: my-redis ports: - 6379:6379 restart: always存成docker-compose.yml文件在文件所在目录执行docker-compose up -dMySQL 和 Redis 会同时拉起来。以后要停服务一条docker-compose down全部停掉。4.4 Dockerfile把自己的应用打包成镜像使用别人的镜像始终受制于人真正的工作流是写一个 Dockerfile把自己的应用打成镜像然后在任何有 Docker 的机器上跑起来。一个 Java SpringBoot 项目的 Dockerfile 示例FROM openjdk:8-jdk-alpine COPY target/app.jar /app.jar EXPOSE 8080 ENTRYPOINT [java, -jar, /app.jar]构建命令docker build -t my-app:v1 .-t指定镜像名和标签最后的.表示使用当前目录下的 Dockerfile。构建完成后docker images就能看到刚刚打好的镜像。这里有个心得写 Dockerfile 尽量把变化最小的操作放前面把频繁变化的 COPY 命令放后面。因为 Docker 构建有缓存机制前面步骤没变就会走缓存构建速度会快很多。Java 项目典型的做法是先拷贝 pom.xml 并下载依赖再 COPY 源码进行打包这样源码改动不会触发依赖重新下载。5. 实战用 Docker 部署 MySQL 8.0 并完整使用5.1 拉取镜像并启动容器部署 MySQL 8.0 是新手接触 Docker 后最值得做的第一个实战。它涉及了 Docker 的端口映射、环境变量、数据卷、日志查看、容器交互这些基础操作完整跑一遍之后基本就能融会贯通了。先拉镜像docker pull mysql:8.0然后启动容器docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDyour_password \ -e MYSQL_DATABASEtest_db \ -v /home/user/mysql-data:/var/lib/mysql \ --restartalways \ mysql:8.0每个参数都别跳过逐一解释-d后台运行。--name mysql8容器叫 mysql8后续操作都靠这个名字。-p 3306:3306把容器内的 3306MySQL 默认端口映射到宿主机的 3306。-e MYSQL_ROOT_PASSWORDyour_password指定 root 密码。这是 MySQL 官方镜像的必填参数不填容器会启动失败。-e MYSQL_DATABASEtest_db容器启动时自动创建一个名为 test_db 的数据库。-v /home/user/mysql-data:/var/lib/mysql数据卷挂载把 MySQL 的数据文件存到宿主机/home/user/mysql-data目录。容器删了数据不丢。--restartalwaysDocker 服务启动时容器跟着自动启动避免服务器重启后服务起不来。5.2 验证容器和连接 MySQLdocker ps看到mysql8容器状态是 Up 就说明启动成功。再确认下日志有没有报错docker logs mysql8看到类似ready for connections的日志说明服务正常。然后用任意 MySQL 客户端连上去连接地址填宿主机 IP 或 localhost端口 3306用户名 root密码就是刚才设置的。比如用命令行连接mysql -h127.0.0.1 -P3306 -uroot -p能进到 MySQL 交互界面整个部署就算完成了。整个过程不超过五分钟爽点在于你本机既不用装 MySQL 软件也不用配置任何系统依赖。5.3 升级 MySQL 版本时数据不丢的操作流程Docker 部署 MySQL 最大的一个痛点解决点升级版本。传统方式升级 MySQL备份、停服务、替换二进制、恢复数据一套操作下来胆战心惊。用 Docker 就简单很多。假设当前跑的是 MySQL 8.0要升级到 8.0.36# 1. 停掉旧容器 docker stop mysql8 docker rm mysql8 # 2. 用新镜像启动数据卷挂载路径保持一致 docker pull mysql:8.0.36 docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDyour_password \ -v /home/user/mysql-data:/var/lib/mysql \ mysql:8.0.36由于数据卷路径没变新容器启动后读到的还是原来的数据升级完成数据完好无损。整个操作可以做到分钟级。提示MySQL 版本跨大版本升级比如 5.7 升 8.0需要格外谨慎直接替换数据目录可能导致不兼容。小版本升级这个流程没问题大版本升级前一定要先备份数据。5.4 再加一个 Redis顺便搞个主从MySQL 部署通了再部署 Redis 基本一摸一样。单机版 Redisdocker run -d --name redis7 -p 6379:6379 redis:7默认的 Redis 镜像没有密码保护生产环境一定要加密码docker run -d --name redis7 -p 6379:6379 -e REDIS_PASSWORDyour_password redis:7 --requirepass your_passwordRedis 主从结构用 Docker 部署起来很直观。先起一个主节点docker run -d --name redis-master -p 6379:6379 redis:7再起一个从节点通过--slaveof参数指向主节点docker run -d --name redis-slave -p 6380:6379 redis:7 --slaveof 172.17.0.x 6379这里的172.17.0.x是主节点容器的 IP可以通过docker inspect redis-master查到。从节点启动后往主节点写数据从节点会实时同步。这个玩法最大的价值在于以前要搭主从你得准备两台机器或者两个虚拟机来回配置网络和认证。现在两条命令搞定。6. 高频问题排查实录这些坑我全踩过6.1 Docker Desktop 一直 Starting 卡住不动这问题八成出在 WSL2 身上。Docker Desktop 启动时依赖 WSL2 子系统WSL2 一旦卡住或者内核版本不兼容Docker Desktop 就会一直卡在 Starting。建议路径亲测有效# 管理员身份运行 PowerShell wsl --shutdown wsl --update wsl --set-default-version 2然后完全退出 Docker Desktop右下角托盘图标右键退出不是直接关窗口重新启动。如果还是卡住去 Windows 功能里把“适用于 Linux 的 Windows 子系统”和“虚拟机平台”关掉重启再重新打开重启。这两个功能重新启用后 Docker Desktop 一般就好了。这个过程有点玄学但确实很多人都靠这个办法修复了。如果你发现自己的机器之前没有安装过 WSL 发行版还需要先执行wsl --install装一个默认发行版通常是 Ubuntu。6.2 Linux 上 permission denied 连不上 Docker在 Linux 上使用 Docker 命令时没有加sudo会报这么一段Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock原因是 Docker 的守护进程以 root 身份运行socket 文件的权限属于 root。普通用户没权限访问。最简单的做法是加sudo但每次加sudo太麻烦推荐把当前用户加入 docker 用户组sudo usermod -aG docker $USER newgrp docker执行完重新登录终端再执行docker ps就不需要 sudo 了。注意加入 docker 用户组相当于给了用户 root 级别的权限因为可以操控 Docker 容器容器里可以挂载宿主机的任何目录。生产环境的服务器要谨慎使用最好只给受信任的管理员账户加。6.3 镜像拉取一直超时或卡住除了配置镜像加速器还有一个可能的原因公司网络或服务器防火墙限制了外网访问。Docker 拉镜像走的是 HTTPS 443 端口如果你的网络环境对这个端口做了限制配置镜像加速器也救不了。这种情况只能从网络层面解决比如在服务器上配置代理或者使用内网部署的私有镜像仓库。6.4 docker exec 提示容器内没有 bash报错通常是OCI runtime exec failed: exec failed: container_linux.go: ...或者bash not found。原因很简单容器镜像里根本没装 bash。Alpine 这类精简镜像默认只有sh修改命令docker exec -it 容器名 sh如果连sh都没有说明镜像精简到连 shell 都没有需要换启动命令或者检查镜像设计。6.5 容器启动后立刻退出docker ps 看不到docker ps看不到容器docker ps -a能看到一个 Exited 状态的容器。这是新手最常见的问题。原因通常是容器内的主进程执行完就退出了。比如你跑一个 Ubuntu 镜像docker run ubuntu这个命令执行完容器立刻退出因为 Ubuntu 镜像的默认命令是bash没有终端输入时 bash 立刻退出容器主进程一退出容器就停止。正确做法是给容器指定一个保持运行的命令或者使用-it进入交互模式docker run -it ubuntu bash还有一种情况是容器启动时配置错误比如环境变量缺失、配置文件路径不对主进程启动失败后退出。这时用docker logs 容器名看日志能直接从报错信息里找到启动失败的原因。6.6 端口被占用导致容器启动失败docker run -p 3306:3306的时候报错port is already allocated说明宿主机 3306 端口已经被其他进程可能是另一个容器也可能是宿主机上直接装的 MySQL占用了。解决办法有三种换宿主机的映射端口比如-p 3307:3306或者先停掉占用端口的程序或者docker rm掉之前创建的容器因为容器创建时虽然退出状态但端口绑定还没有释放。6.7 Docker 服务启动失败Linux 上执行systemctl start docker报错先看服务状态详细信息sudo systemctl status docker90% 的情况是/etc/docker/daemon.json配置写错了JSON 格式错一个逗号都会导致 Docker 服务起不来。检查这个文件有没有语法错误测一下cat /etc/docker/daemon.json如果格式正确再看具体报错常见的原因有网络冲突iptables 规则残留、磁盘空间不足镜像层写不进去。df -h看看根分区使用率超过 90% 就该清理了。6.8 Docker Desktop 修改存储路径Docker 默认把镜像和容器数据存在 C 盘C 盘空间紧张的用户迟早会遇到磁盘满的问题。修改方法Docker Desktop → Settings → Resources → Advanced → Disk image location改成其他盘符的路径应用后 Docker 会重启。注意这个操作不会自动迁移已有的数据需要先导出再导入或者干脆手动删除后重新拉取镜像。6.9 Kali 搭建 DVWA 靶场这个场景在安全圈子里很常见。Kali 系统自带 Docker 支持一条命令直接跑起 DVWA 靶场docker pull vulnerables/web-dvwa docker run -d -p 80:80 vulnerables/web-dvwa访问http://localhost就能进入 DVWA 的登录页默认账号admin密码password。整个搭建过程从零到可用不超过三分钟这就是 Docker 在学习和实验场景下的价值——不在环境搭建上浪费一秒钟。7. 进阶玩法容器化部署的真实工作流7.1 把数据库和应用一起容器化实际项目中应用容器和数据库容器往往要配合使用。用 docker-compose 编排一个 SpringBoot 应用和 MySQL 的组合。项目结构my-project/ ├── docker-compose.yml ├── mysql/ │ └── init.sql # 初始化 SQL首次启动自动执行 └── app/ └── Dockerfiledocker-compose.yml内容version: 3 services: mysql: image: mysql:8.0 container_name: project-mysql environment: MYSQL_ROOT_PASSWORD: root123456 MYSQL_DATABASE: app_db volumes: - ./mysql/data:/var/lib/mysql - ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql ports: - 3306:3306 restart: always app: build: ./app container_name: project-app depends_on: - mysql environment: SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/app_db SPRING_DATASOURCE_USERNAME: root SPRING_DATASOURCE_PASSWORD: root123456 ports: - 8080:8080 restart: always这里有一个关键的细节应用容器连接数据库时数据库地址不是localhost而是服务名mysql。因为容器之间通过 Docker 内部网络通信localhost指向的是容器自身。depends_on参数保证应用容器会在数据库容器启动后再启动但这是容器级别依赖不保证 MySQL 已经就绪。实际运行中应用启动时数据库还没完全初始化的情况很常见所以应用代码里要对数据库连接配置重试机制或者等待一段时间再启动。7.2 Docker Desktop 上的微服务项目部署在 Windows 上做开发时部署微服务项目到 Docker Desktop 已经是很多团队的标配流程。关键点在于本地代码修改后重新构建镜像、启动容器的过程要足够快否则开发效率会被拉低。一个提高效率的骚操作在开发环境把项目的源码目录挂载到容器内实现代码热更新version: 3 services: app: build: . volumes: - ./src:/app/src ports: - 8080:8080宿主机改了代码容器内的代码同步更新配合热加载工具比如 SpringBoot DevTools改完代码自动编译重启。这样就不用每次改代码都重新打镜像了。7.3 青龙面板的镜像管理和依赖管理很多喜欢用青龙面板一个定时任务管理平台的人也会有 Docker 方面的需求。青龙面板本身就是一个 Docker 容器依赖管理说白了就是把常用依赖装进容器里。docker run -d \ --name qinglong \ -p 5700:5700 \ -v ~/qinglong/config:/ql/config \ -v ~/qinglong/log:/ql/log \ -v ~/qinglong/scripts:/ql/scripts \ whyour/qinglong:latest依赖装错地方导致脚本跑不起来是高频问题。记住一个原则脚本运行需要什么依赖就要装进运行脚本的容器里。不是装在本机也不是装在 MySQL 容器里而是你要执行任务的那个容器一般是青龙容器里。7.4 把微服务做成 Hadoop 镜像大数据方向的读者会用到 Hadoop 的 Docker 镜像。Hadoop 官方没有发布 Docker 镜像但社区里有不少现成的比如bde2020/hadoop-namenode和bde2020/hadoop-datanode。用 docker-compose 可以把一套 Hadoop 集群变成几个容器启动命令统一管理。这个方向的水比较深涉及网络配置、内存分配、端口映射一堆细节建议先跑通单机伪分布模式再去折腾多节点集群。8. 我的几条实战心得第一Docker 文档虽然多但最该先吃透的就是镜像和容器的关系。这个关系理解透了后面所有操作都会很顺。凡是卡住的地方多半都是没搞清自己在跟镜像打交道还是跟容器打交道。第二数据卷的挂载路径一定要规范。团队协作时如果每个人都把路径挂到不同的地方交接起来就是一场灾难。建议约定统一的挂载根目录比如/data/docker/服务名存放所有容器的重要数据。我在生产环境就一直用这个规范排查问题、备份恢复都方便很多。第三学会看日志等于解决了 90% 的问题。容器出问题第一反应不是到处查资料而是docker logs 容器名日志里通常直接写着失败原因。排查问题的顺序应该是看日志 → 确认配置 → 检查网络 → 上网搜索而不是反过来。第四别迷信 latest 标签。生产环境拉镜像一定要指定版本号比如mysql:8.0.36而不是mysql:latest。latest 跟着上游更新哪天上游发布了不兼容的版本你的服务可能稀里糊涂就被影响到了。Docker 这个东西单独看每个概念都不复杂难的是把它串起来用。先从这篇文章里的 MySQL 实战开始把命令敲一遍再试着自己写一个 Dockerfile 打包一个小应用最后用 docker-compose 把两三个服务编排起来。跑通这几个流程Docker 的基本功就算打牢了。

相关新闻

最新新闻

ruflo实战:用Rust构建嵌入式实时日志告警流处理管线

ruflo实战:用Rust构建嵌入式实时日志告警流处理管线

ruflo 这个名字念起来有点拗口,但拆开看就很直白了:ru 是 Rust,flo 是 flow。我最初是在一个内部监控服务里需要处理实时日志流,过滤异常、聚合计数、触发告警,结果翻了半天生态,要么直接上 Flink 这种重型…

2026/9/9 11:21:43
STM32F103 DAC输出正弦波:DMA+定时器驱动全解析

STM32F103 DAC输出正弦波:DMA+定时器驱动全解析

简介:这是一份关于 STM32F103 内置 DAC 输出正弦波的实战资源,面向嵌入式开发初学者,旨在解决数字量如何转换为模拟电压并形成连续波形的问题。内容基于 STM32F103RCT6,完整展示了正弦波的数据点计算、DAC 配置、定时器触发、DMA …

2026/9/9 11:21:43
IDEA+Tomcat控制台中文乱码根治:字符编码统一方案

IDEA+Tomcat控制台中文乱码根治:字符编码统一方案

用 IDEA 开发 Java Web 项目,启动 Tomcat 时控制台输出一堆中文乱码,这几乎是每个刚接触 Spring MVC 或者 SSM 框架的同学都撞过的坑。乱码看起来是小事,但真正排查起来涉及的环节一点都不少:源文件编码、JVM 启动参数、IDEA 控制…

2026/9/9 11:21:43
SpringBoot智慧垃圾分类系统实战:从识别到清运调度完整指南

SpringBoot智慧垃圾分类系统实战:从识别到清运调度完整指南

前两天有个学弟来找我聊计算机毕业设计选题,刚坐下就问我:“哥,我准备用SpringBoot做一个智慧城市垃圾分类管理系统,这题是不是太烂大街了?”我反问他:你打算怎么做?他说:“就是管理…

2026/9/9 11:21:43
从调频连续波到汽车雷达:FMCW信号处理仿真全链路实战

从调频连续波到汽车雷达:FMCW信号处理仿真全链路实战

开篇先把话说透:做雷达信号处理这行,如果没亲手把调频连续波(FMCW)从波形生成、目标回波建模、混频、距离FFT、多普勒FFT到CFAR检测这条链路在仿真里完整跑通一遍,那“汽车雷达”这几个字基本就停留在PPT上。这篇博文就…

2026/9/9 11:21:43
ponytail:零构建的极简前端开发工具

ponytail:零构建的极简前端开发工具

1. 项目概述:一个被严重误读的“ponytail”——它根本不是发型,而是一个极简主义前端构建工具最近刷技术社区,总能看到“ponytail”这个词高频出现,搭配着“ponytail skill”“npx skill add dietrichgebert/ponytail”这类命令&a…

2026/9/9 11:16:42