news 2026/10/10 3:34:04

Docker实战指南:从安装部署到MySQL、Redis与微服务全流程排错

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Docker实战指南:从安装部署到MySQL、Redis与微服务全流程排错

1. 先搞懂Docker到底在解决什么问题

Docker这个词,这几年几乎成了后端开发和运维同学的必修课。我最早听说Docker的时候觉得它就是个装软件的“壳子”,直到自己踩了一堆坑、在服务器上用它把整个开发环境一键拉起来之后,才真正明白它解决的是什么级别的问题。如果你搜过“docker安装教程”、“ubuntu 安装docker”、“docker desktop 安装教程”,大概率是刚准备上手,或者已经在某个环节卡住了。这篇文章不打算讲太多抽象理论,我会按照自己实际折腾过的路线,从环境准备、镜像下载、MySQL部署、Redis主从,到微服务打包和网络排查,一条线捋下来。中间遇到的报错和排查逻辑,我也会全部写出来。

Docker能解决的核心问题,我用一句话概括:把你的应用连同它依赖的运行环境,一起装进一个标准化的集装箱里。以前你在一台机器上部署项目,要先装JDK、装MySQL、调各种环境变量,换一台机器再来一遍,版本稍微不一致就崩给你看。用Docker之后,这些东西全部固化在镜像和容器里,镜像走到哪,环境就跟着到哪。这个思路本身不难,难的是把镜像、容器、仓库、网络这些基础概念彻底理顺,以及遇到“permission denied while trying to connect to the docker api”、“docker镜像下载慢”这类高频问题时,知道该从哪里下手。

1.1 环境不一致这个老大难

做开发或者运维的人,对“在我机器上是好的”这句话应该都不陌生。我自己就经历过:本地联调一切正常,代码一发到测试服务器,连JDK版本都对不上,数据库编码也不一样,最后查来查去发现是系统装了不同版本的依赖库。这个问题的根源不是某个人的失误,而是传统部署方式中,应用代码和运行环境是分离的。代码可以拷贝,环境却很难百分百复刻。

Docker的思路很直接:把代码、运行时、系统依赖、配置全部打进同一个镜像里,运行的时候用这个镜像创建容器。容器在宿主机上是一个隔离的进程,它有自己的文件系统、网络栈和进程空间,和宿主机的其他进程相互独立。就像搬家的时候,不是把一堆零散家具运到新家再重新组装,而是直接把已经装好的房间整体搬过去,到了新地方打开就能用。这样说可能比较抽象,但你只要记住一点:自从用了Docker,我在不同机器上部署同一个项目的成功率,从“全靠运气”变成了“基本必成”。

1.2 镜像、容器、仓库:三个必须分清的词

新手最容易混淆的三个概念,是镜像(Image)、容器(Container)和仓库(Repository)。很多搜“docker仓库”的朋友,其实就是想找地方下载现成的镜像,但又不清楚仓库到底存的是什么。

我用一个做饭的类比来解释:

  • 镜像是菜谱加食材的半成品包。它是一套只读的模板,里面已经有操作系统的基础环境、应用代码、依赖库和默认配置。你可以用同一个镜像创建任意多个互不影响的容器。
  • 容器是你按照这个半成品包做出的成品菜。它是镜像运行起来后的实例,有自己的状态,可以启动、停止、删除。对容器的任何修改不会影响原来的镜像。
  • 仓库是存放各种镜像的地方。你执行docker pull mysql,就是从仓库拉取别人做好的MySQL镜像;你也可以把自己做的镜像推到仓库里分享。

实际操作中,这三个动作是你最常遇到的:

docker pull mysql:8.0 # 从仓库拉取镜像 docker run -d --name my-mysql mysql:8.0 # 基于镜像创建并启动容器 docker images # 查看本机已下载的镜像 docker ps -a # 查看本机存在的容器(含已停止的)

很多人搜“hadoop的docker镜像”,其实想的就是“有没有人已经把Hadoop环境打包好了,我直接拉下来用”。有,而且确实能帮你省掉自己搭Hadoop集群的半天时间。这种现成镜像基本都是各技术社区维护的,拉下来之后微调一下配置就能跑,这就是Docker能普及的根本原因——大家把重复的环境搭建工作做成了镜像,你用就行了。

1.3 Docker Desktop 和 Docker Engine 的区别

再解释一个让很多人绕晕的点:搜“docker desktop 安装教程”和“ubuntu 安装docker”的人,看起来都在装Docker,但装的其实是两个不同的东西。

  • Docker Engine是Docker的核心运行引擎,负责创建和运行容器。它主要在Linux服务器上以守护进程的方式运行。你搜到的“ubuntu 安装docker”、“centos7 安装docker”,装的就是这个。
  • Docker Desktop是面向Windows和macOS用户的图形化应用,内置了Docker Engine。因为Windows和macOS本身不是Linux系统,Docker Desktop需要借助虚拟化技术创建一个轻量级的Linux虚拟机,Docker在里面运行。你在Windows上点开Docker Desktop,看到那个鲸鱼图标,本质上是Docker通过Windows的WSL2或Hyper-V在后台运行了一个Linux环境。

所以如果你用的是云服务器或者自己的Linux机器,老老实实装Docker Engine就行,不需要Docker Desktop。如果你是在本地Windows电脑上做开发,想模拟线上环境,那就装Docker Desktop。我见过不少人在Windows上折腾半天,其实他要的只是一个能在本机跑Linux容器的环境,那就必须走Desktop这条路,因为Windows原生不能直接跑Linux容器。

这两种方式没有谁更好,只有谁更适合当前场景。我的建议是:服务器部署一律用Engine,本地开发调试用Desktop,两边的使用场景完全不同,别混着搞。

2. 环境准备:不同系统下的安装与启动

2.1 Windows上Docker Desktop的正确安装姿势

先聊Windows,因为“docker desktop failed to start because virtualisation support wasn't detecte”这个报错,我见过太多人问了。这个报错翻译一下就是“没检测到虚拟化支持”。Docker Desktop依赖Windows的虚拟化能力来运行Linux容器,如果你的电脑没开虚拟化,它启动到一半就会卡住,最后弹这个错。

解决办法分两步:

第一,进BIOS/UEFI把Intel VT-x或AMD-V虚拟化打开。开机时按F2、F10、Del等键进BIOS,找到虚拟化相关的选项,一般是“Intel Virtualization Technology”或“SVM Mode”,设为Enabled。这个操作每台电脑的位置不太一样,但关键词基本就这几个。

第二,在Windows功能里启用虚拟机平台和WSL2。以管理员身份打开PowerShell,执行:

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

执行完重启电脑。然后下载安装Docker Desktop安装包,装完它会自动帮你配置WSL2环境,之后在终端里执行docker version如果能同时看到Client和Server的版本信息,说明Docker Engine已经正常启动了。我遇到过有朋友装完后Docker Desktop一直右下角转圈,进设置把“Use the WSL 2 based engine”勾上重启就能解决。

2.2 Ubuntu和CentOS的Docker Engine安装记录

Linux服务器上装Docker Engine,主流方式有两种:用官方脚本一键装,或者配置软件源后用包管理器装。我强烈建议用软件源的方式,因为脚本装出来的版本有时候不好控制。

Ubuntu 20.04及以上的装法:

sudo apt update sudo apt install -y apt-transport-https ca-certificates curl software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo "deb [arch=amd64 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

CentOS 7升级Docker跟Ubuntu不一样。默认源里的docker版本太老,需要先卸载旧版本,再通过docker-ce源安装新版:

sudo yum remove docker docker-common docker-selinux docker-engine 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

还有老系统,比如Ubuntu 14、16这类,现在直接装新版Docker会提示内核版本太低装不上。我实际测过的稳妥方案是装旧一点的版本,比如Docker 18.06或者19.03,或者直接换用Docker提供的历史版本源。这类老机器一般不建议再折腾Docker,如果实在没条件换系统,就认准能装的旧版本,别指望跑最新功能。

装完之后启动服务:

sudo systemctl enable docker sudo systemctl start docker

然后跑docker run hello-world验证,能打印出Hello from Docker就说明环境没问题了。如果你每次执行都要加sudo,看下一节。

2.3 权限错误:permission denied while trying to connect to the docker api

这个报错,可能是新手遇到最多的一个,完整信息是:

permission denied while trying to connect to the docker daemon socket at unix:///var/run/docker.sock

意思是当前用户没有访问Docker守护进程socket的权限。Docker客户端要和守护进程通信,默认走的是/var/run/docker.sock这个Unix套接字,而这个套接字默认归属root用户和docker组。普通用户不在docker组里,自然就被拒绝了。

解决办法是把当前用户加入docker组:

sudo usermod -aG docker $USER

执行完记得重新登录或者执行newgrp docker,不然组权限不会立刻生效。这是很多人的坑:命令执行成功了,重启终端试docker还是报同样的错,其实是没有重新登录。加了组还不行的话,干脆先把sudo chmod 666 /var/run/docker.sock作为临时方式,但我实名不建议长期这么干,这相当于让所有用户都能控制Docker守护进程,等于把服务器的后门敞开了。

生产环境我都是给专门的运维账号加docker组,而不会直接给普通开发账号这个权限。原因很简单:有docker权限的人在容器里挂载根目录后,就和root差不多了,控制力极强,权限给太散早晚出事。

3. 镜像下载:为什么慢、怎么加速、pull报错怎么解

3.1 镜像分层与下载原理

搜“docker镜像下载慢”的人,十有八九是第一次跑docker pull,眼看着进度条卡在几MB不动,心态直接崩。要理解为什么慢,得先知道镜像下载的是什么。

镜像不是一个大文件,而是由多层只读文件系统叠加组成的。每一层对应Dockerfile里的一条指令,比如FROM ubuntu:22.04就是一个基础层,RUN apt-get install又生成一个新层。Docker在拉取镜像的时候,会把每一层分别从仓库下载下来。基础层往往体积巨大,一个Ubuntu系统镜像就有几十MB甚至上百MB,加上应用层,一个完整的开发镜像动辄几百MB到1GB以上,下载慢是很正常的。

但“正常慢”和“异常卡”是两回事。如果你发现docker pull半天没动静,多半是网络到Docker官方仓库的连接被干扰了。解决思路是配置镜像加速器,让Docker从国内可达的公共镜像仓库拉取。做法是在/etc/docker/daemon.json(Linux)或者Docker Desktop的设置页面(Windows)里添加registry-mirrors配置:

{ "registry-mirrors": ["https://你的加速地址"] }

加速地址这一块我说点实在的:不同地区、不同运营商的网络对各个镜像加速服务的连通性差异很大,别人用着快的你不一定快,网上流传的老加速地址很多已经关停或者失效,别迷信。正确做法是搜“docker镜像加速”找当前可用的公共加速服务,进去看一眼规则,选一个你自己网络能通、能拉得动的,然后反复试几次,找到相对稳定的那个。企业内网环境还可以直接用公司搭建的镜像仓库,这种一般稳定性和速度都是最好的。

3.2 docker pull mysql 报 failed to decode referrers index 怎么处理

这个报错是我近期被问得最多的,完整信息是:

failed to decode referrers index: invalid

出现场景基本是:执行docker pull mysql:8.0之类的命令后,进度条走了一段时间,直接弹出这个错,镜像拉不下来。我一开始也以为是网络问题,换了好几个加速地址都没用,后来查资料才发现是Docker客户端和镜像仓库之间对镜像清单的解析出现了兼容性问题。

原因大概是:新版Docker的镜像拉取机制改用了OCI标准,会额外生成并解析一个叫“referrers index”的索引数据,用于关联镜像的签名、漏洞扫描等附加信息。但很多历史镜像仓库或者某些中转仓库,存储在里面的镜像清单并没有这个索引字段,或者是用旧格式生成的。新客户端去解析不存在的字段,直接就抛异常了,连带镜像也拉不下来。

我实测有效的解决方案有三条,从推荐到备选排个序:

  1. 换镜像源。这个是首选。报错的根源是客户端和仓库之间的格式兼容,换成能生成完整OCI清单的镜像源之后,同样一条docker pull mysql:8.0就能顺利跑完。我自己的经历就是换了源之后问题立刻消失。
  2. 降级Docker版本。如果你不想换源,可以退回到24.0.x系列。旧版客户端没有强制去解析referrers index,所以不会触发这个报错。代价是老版本没有新特性,安全更新也少了。
  3. 拉取时指定完整摘要。镜像仓库页面一般会提供一个完整的digest引用,形如docker pull mysql@sha256:xxxx,这种拉取方式走的是另一种解析链路,有时候能绕开这个报错。但成功率不保证,只能试试。

这个报错一句话总结:不是你没装好,是客户端和仓库的协议格式没对齐,换源降级二选一,基本都能解决。

3.3 镜像瘦身与清理技巧

镜像越来越大,本地磁盘被docker占满,这是用了一段时间之后必会遇到的问题。docker system df可以看看到底多少空间被镜像和容器占用了,docker system prune -a可以一键清理所有停止的容器、未使用的镜像和构建缓存。

但清理只是治标,治本还是要在写Dockerfile的时候控制体积:

  • 每个RUN尽量合并成一条,因为每一层都会残留中间文件,层越多镜像越大。
  • 多阶段构建,比如编译Java应用时,第一阶段用maven镜像编译出jar包,第二阶段只用一个小体积的运行时镜像把jar包拷进去,最终镜像就不会携带编译器。
  • 写.dockerignore,把本地的.git、node_modules、target这类目录排除掉,避免这堆东西被拷进构建上下文。

我第一次用IDEA打包Docker镜像的时候,没写.dockerignore,结果构建上下文把整个项目的target目录都传给了Docker守护进程,构建又慢又大。后来老老实实加上,瞬间清爽。

4. 实战一:MySQL 8.0 部署与容器内外访问

4.1 一条命令装好MySQL 8.0

搜“docker安装mysql8.0并使用”的人,一般就是想把数据库跑在容器里,省去本机装MySQL的服务管理烦恼。命令行版本我来写一个完整示例:

docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=YourPass123 \ -e MYSQL_DATABASE=testdb \ -v mysql-data:/var/lib/mysql \ -v mysql-config:/etc/mysql/conf.d \ mysql:8.0

我逐项解释一下这些参数,因为很多时候报错就出在不理解参数含义:

  • -d表示后台运行。
  • --name mysql8给容器起名,方便后续用docker exec -it mysql8 bash进容器操作。
  • -p 3306:3306是端口映射,宿主机3306端口映射到容器3306端口,这样宿主机外的客户端才能访问到容器内的MySQL。
  • -e MYSQL_ROOT_PASSWORD是给MySQL的root用户设置初始密码,这是初始化容器时必须设置的,不设置MySQL根本起不来。
  • -v mysql-data:/var/lib/mysql是把容器内的MySQL数据目录挂载到Docker命名卷里。我一直强调:容器可以被随意删除重建,但数据卷不会跟着删。如果哪天镜像有问题要重建容器,只要数据卷还在,数据就还在,这是我吃过亏之后总结出来的铁律。
  • -v mysql-config:/etc/mysql/conf.d是挂载配置目录,后面要调字符集或者最大连接数,不用进容器改文件,直接在宿主机挂载的卷里改就行。

启动完之后执行docker logs mysql8看一下日志,看到ready for connections就说明MySQL已经起来了。

4.2 为什么宿主机访问不了容器里的MySQL

这个问题在“访问docker容器内的mysql”这个搜索词里能看出来,是高频中的高频。现象是:项目部署在宿主机上,代码里连接数据库用的是127.0.0.1:3306,结果直接报连接超时或者Access denied。

先说连接超时。这不是MySQL密码错误,而是Docker容器默认有一个自己的网络命名空间。容器里的服务监听的是容器内部的网络接口,宿主机的127.0.0.1只能访问宿主机自己,除非做了端口映射。-p 3306:3306就是把容器内的3306端口暴露到宿主机上,这样127.0.0.1:3306才能真正到达容器里的MySQL。

再说Access denied。超时解决之后,又出现权限拒绝,这个大概率是MySQL内部的权限问题。最简单粗暴的排查方法,是直接进容器验证:

docker exec -it mysql8 mysql -uroot -p

如果进容器后用root密码能正常登录,说明MySQL本身没问题,那就是宿主机侧连过来的时候权限验证不通过。有些MySQL镜像默认的root用户只允许本机回环地址访问,宿主机IP不在允许列表里。解决办法是初始化容器时就指定远程访问的授权,或者在运行后执行授权SQL:

CREATE USER 'root'@'%' IDENTIFIED BY 'YourPass123'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES;

'root'@'%'代表任何来源的root连接都能通过。本地开发这么搞没关系,但生产环境还是老老实实创建专用账号,root开放远程是数据库大忌。

4.3 部署MySQL的经典报错与排查

“docker安装mysql失败”这个搜索词,我大概能猜到是哪些场景。最常见的有三类:

第一类,端口占用。宿主机3306已经有另一个MySQL在运行,docker run虽然能创建容器,但端口映射失败,容器会反复重启。处理方式:先netstat -tlnp | grep 3306看哪个进程占了端口,然后换一个宿主机的映射端口,比如-p 3307:3306。

第二类,磁盘空间不足。镜像可能比较大,数据卷也会持续增长,docker system df看一下空间使用情况,如果满了先做一次清理。

第三类,内存不足。MySQL 8.0默认的buffer pool占内存不小,小内存服务器上跑容器很容易因为内存不足导致MySQL启动失败。解决办法是启动时限制容器内存,或者调小MySQL的innodb_buffer_pool_size配置。

日志是排查一切问题的第一手信息,不要瞎猜,先执行docker logs mysql8看输出。报错信息里一般会直接告诉你原因,比在网上漫无目的地搜更高效。

5. 实战二:Redis主从、GitLab与微服务打包

5.1 用Docker快速搭Redis主从

Redis主从是缓存场景里的经典需求,平时手动编译安装Redis再配主从,得下载源码、编译、改配置文件、设置防火墙,折腾一圈至少半小时。用Docker的话,几分钟就能搞定。

先建一个主节点:

docker run -d \ --name redis-master \ -p 6379:6379 \ redis:7.0 redis-server --appendonly yes

--appendonly yes开启AOF持久化,这样重启容器数据不会丢。然后启动从节点,关键参数是--replicaof:

docker run -d \ --name redis-slave \ -p 6380:6379 \ redis:7.0 redis-server --replicaof 宿主机IP 6379

注意--replicaof后面的地址,如果从节点和主节点在同一台宿主机上,填宿主机IP而不是127.0.0.1。原因和MySQL那节说的一样,容器各自有独立的网络命名空间,127.0.0.1指向的是从节点自己,根本连不到主节点。

启动之后进从节点验证:

docker exec -it redis-slave redis-cli info replication

看到role:slave,以及master_host那一串信息正确,就说明主从关系建立了。然后往主节点写一个key,在从节点查一下,如果能查到,说明数据同步正常。

这套方案给我的最大感受是:以前配置主从最怕环境不一致,版本差一点同步可能就出问题。Docker直接把Redis主从的工具链固化成了镜像,剩下的只是几个参数的事。

5.2 GitLab和微服务部署,还有IDEA打包镜像

搜“docker安装gitlab”和“idea 打包docker镜像”的朋友,基本是团队里想自己搞一套代码托管和部署流程的。GitLab用Docker部署确实省事,但要注意它的资源胃口,官方推荐至少4GB内存。我实测2GB内存的服务器也能跑,但会很卡,建议至少4GB。

GitLab启动命令可以稍微简单一点:

docker run -d \ --name gitlab \ -p 8929:80 \ -p 2289:22 \ -v gitlab-config:/etc/gitlab \ -v gitlab-logs:/var/log/gitlab \ -v gitlab-data:/var/opt/gitlab \ gitlab/gitlab-ce:latest

首次启动初始化时间比较长,docker logs -f gitlab慢慢等,等看到“GitLab is running”就好。GitLab的备份数据都放在数据卷里,升级容器版本不会丢仓库数据,这一点是它用起来最舒服的地方。

至于微服务部署,核心就一句:把每个微服务打成镜像,然后用Docker Compose编排起来。我实际用IDEA打包Docker镜像走的链路是:

  1. 项目里写一个Dockerfile,示例:
FROM openjdk:17-jdk-slim ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} app.jar ENTRYPOINT ["java", "-jar", "/app.jar"]
  1. 用Maven把项目打成jar包。
  2. IDEA装好Docker插件并连接本地Docker,然后右键Dockerfile直接Build,或者在Maven构建后执行docker build。
  3. docker images能看到新生成的镜像,docker run或者Compose一键启动。

这套流程走顺之后,微服务部署变得非常规律:改代码、打jar包、重建镜像、替换容器,四个步骤而已。

5.3 网络不通用这招基本能排查

“docker网络不通”这个问题,搜的人很多,但大部分其实不是Docker的锅。我按排查顺序写一下,你照着做大概率能找到问题:

第一步,先确认容器到底能不能访问外网。进入容器执行:

docker exec -it 容器名 bash ping 8.8.8.8

ping通了说明容器网络正常,问题出在具体服务上;ping不通就要检查宿主机的网络和防火墙。

第二步,确认容器内服务是否真的在监听。进容器执行:

netstat -tlnp

或者直接curl 127.0.0.1:端口,如果服务都没监听,说明服务本身没起来,容器网络再好也白搭。

第三步,确认跨容器通信用的是正确地址。Docker容器之间可以通过容器名互相访问,但前提是它们都在同一个自定义bridge网络里。默认的bridge网络不支持容器名DNS解析,跨容器访问最好创建一个自定义网络:

docker network create mynet docker network connect mynet 容器A docker network connect mynet 容器B

然后把访问地址从IP改成容器名,比如mysql8:3306。这个改法能解决一大批“容器之间互相访问不了”的问题。我帮别人排查的时候,经常看到他们把容器的IP写死在配置文件里,结果容器一重建IP就变了,立刻又连不上。换成容器名之后,这个隐患就彻底没有了。

5.4 自动化任务项目里的Docker依赖管理

搜“docker青龙 依赖管理”的,多半是想在Docker里跑定时脚本任务,通过面板管理各种依赖库。这个场景本质上就是把一堆脚本和它们需要的Python或Node依赖打进容器,解决宿主机器上依赖互相污染的问题。Docker在这里的价值和前面提到的完全一样:它把运行环境和依赖彻底隔离,这个面板容器里装了什么、升级了什么,都不会影响到宿主机的Python、Node环境。依赖装坏了,直接把容器删了重建一个,几秒钟恢复原样。

我没有在具体某个面板上多花时间研究,但这种“依赖隔离、失败重建”的思路,适用于一切跑脚本任务的项目。你完全可以用同样的方式,在容器里维护一个Python环境跑自己的定时任务,比直接在宿主机上堆一堆全局依赖安全得多。

6. 常见问题速查表

最后把前面提到的那些报错和现象整理成一张速查表,方便你以后遇到问题直接过来查。

问题现象常见原因处理方式
permission denied while trying to connect to the docker api用户不在docker组sudo usermod -aG docker $USER后重新登录
Docker Desktop failed to start because virtualisation support wasn't detectedBIOS未开启虚拟化或Windows虚拟化功能未启用BIOS开启Virtualization,启用WSL2和VirtualMachinePlatform
docker pull镜像卡住或极慢访问官方仓库网络不通配置registry-mirrors,换当前可用的公共加速地址
docker pull mysql报failed to decode referrers index新Docker客户端与旧镜像仓库清单格式不兼容优先换镜像源,其次降级Docker到24.0.x
宿主机访问不了容器内MySQL端口未映射或MySQL root用户权限限制检查-p参数,创建'root'@'%'用户
docker run后容器反复重启端口占用、内存不足、MySQL初始化失败看docker logs 容器名定位具体原因
docker compose up -d报错配置文件缩进错误或镜像不存在先检查yml缩进,再docker logs查看服务日志
Docker Engine启动失败服务异常、配置文件错误systemctl status docker查看具体错误信息
docker容器之间网络不通不同网络或使用了默认bridge创建自定义network,按容器名访问
docker镜像占用空间过大构建层过多、依赖残留多阶段构建、合并RUN、docker system prune清理

写在最后的一些经验

Docker这套东西,入门其实不难,难的是遇到问题的时候能快速定位。我自己踩过最多的坑集中在三件事:一是权限,刚装完Docker就被permission denied教育了一晚上;二是网络,镜像拉不动、容器连不上,各种网络问题排查了半天才发现是网络模式和地址写错了;三是数据,早期觉得容器是临时的,数据没挂载到数据卷,重建容器之后数据全没了,那种懊恼到现在还记得。

如果你正在看这篇文章,我的建议是:别急着追求把所有概念都背下来,先拿MySQL或者Redis这种实际服务练手,跑起来一个,再把容器删了重建一次,感受一下数据卷的作用,这一轮下来你对Docker的理解会比看十篇文章都深。另外,容器命名规范、端口规范、数据卷规划这些,别看它们琐碎,在用了半年之后会直接影响你的运维效率,越早建立习惯越好。

Docker真正改变我的,是让我在部署这件事上有了“确定性”——同样的镜像,在任何一台装了Docker的机器上,跑出来的结果都是完全一致的。这种确定性,才是它最大的价值。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 3:34:04

数据结构和算法PDF:下载不是目的,建立索引才是

简介:超过1000页的算法题解PDF文档,面向准备技术面试、日常刷题的开发者和算法爱好者。内容按动态规划、回溯算法、贪心算法、DFS/BFS、双指针、滑动窗口、二叉树等专题系统整理,覆盖排序、查找、递归、前缀和等基础板块,每道题均…

作者头像 李华
网站建设 2026/10/10 3:34:04

Linux内核编译安装指南:配置、编译、引导与高频排障

“求助,装linux内核遇到了困难”——这个标题我在不少技术群里见过,每次都会引出十几条追问。但有意思的是,大家卡住的位置其实高度集中:有人是编译完重启直接黑屏,有人是模块加载报错,还有人根本卡在“到底…

作者头像 李华
网站建设 2026/10/10 3:33:20

Openclaw智能体网关:飞书微信钉钉QQ四端消息统一接入全攻略

2026年了,如果你还在一个平台一个平台地切来切去,让AI机器人分别处理飞书、微信、钉钉、QQ的消息,那真的有点跟不上节奏了。我第一次接触 Openclaw(也就是大家常说的 Clawdbot)时,它给我的印象不是"又…

作者头像 李华
网站建设 2026/10/10 3:32:55

Python进阶关键:迭代器、生成器与装饰器机制实战

Day 48 这个节点很有意思。能坚持到第 48 天,说明你已经把基础语法、函数、面向对象、文件操作这些硬骨头啃得差不多了,但这个阶段也最容易陷入一种“会写但不懂”的瓶颈:能跑通代码,却说不清代码在内存里到底发生了什么。我个人的…

作者头像 李华
网站建设 2026/10/10 3:32:38

【计算机毕业设计单片机案例】基于单片机的室内有害气体监测、声光告警与自动换气装置设计 基于单片机的室内四项环境指标采集与手自动联动排风装置设计(030115)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

作者头像 李华
网站建设 2026/10/10 3:30:03

时序数据库入门到选型:从监控数据积压到高压缩写入实战

1. 从一次监控数据积压说起:为什么普通数据库扛不住时间序列我第一次真正意识到时序数据库和普通关系型数据库不是一回事,是在一个设备监控项目上。当时系统接入了大约两千台设备,每台设备每秒上报一次温度、电压、电流三个指标,算…

作者头像 李华