尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Spring Boot 容器镜像:Windows 构建到 Linux 运行全记录
简介面向需要将SpringBoot项目容器化的Java开发者和运维人员详细讲解从Windows环境构建Docker镜像再到Linux环境部署的完整流程。资源共包含1个docx文档大小2.48MB内容覆盖Dockerfile基础、镜像构建、容器运行、端口映射、网络共享模式、MySQL数据库容器化以及镜像打包迁移等知识点。文档先介绍在Java项目根目录创建Dockerfile并编写基础指令接着通过docker build与docker run完成镜像构建和容器启动并给出日志查看与访问验证方法。针对数据库连接问题作者提供了共享主机网络、容器ping测试、数据库用户授权等解决方案同时演示了MySQL容器化部署的挂载目录与参数配置。最后讲解如何将镜像从Windows打包传输到Linux环境直接运行实现跨平台快速交付。已有134人学习下载适合需要快速上手Docker化部署的初中级后端开发与运维工程师。1. Windows 上构建 Spring Boot 镜像搬到 Linux 运行这套流程到底卡在哪把 Spring Boot 项目打包成 Docker 镜像在 Windows 上构建、再搬到 Linux 运行是很多中小团队开发和部署服务器分离时的标准操作。Docker 的镜像跨平台特性让这个过程听起来很简单但实际走一遍你会发现Dockerfile 写错、端口映射冲突、容器里连不上数据库、镜像 save 之后 load 下来没有 tag每一个问题都能让人耗掉一下午。这篇文章是我把一套 Spring Boot 项目连带着 MySQL、Redis 一起容器化再从 Windows 搬到 Linux 的全过程记录。重点不是科普概念而是把命令参数、网络配置、数据卷挂载和常见报错修法写清楚。如果你正卡在“本地镜像能跑上了服务器就挂”的阶段照着下面顺序走完应该能少踩几条弯路。2. 先用 Dockerfile 把 Spring Boot 项目打成镜像FROM、COPY、ENTRYPOINT 是关键2.1 编写 Dockerfile基础镜像选型、工作目录和 jar 包复制Spring Boot 项目要容器化第一步不是直接敲docker run而是先准备一个 Dockerfile。这个文件没有扩展名放在项目根目录下。我一般会先mvn clean package -DskipTests打好 jar 包确认target目录里生成了可执行 jar再去写 Dockerfile。# 使用 OpenJDK 8 的 Alpine 精简版镜像体积小启动快 FROM openjdk:8-jdk-alpine # 容器内统一使用 /app 作为工作目录后续命令都在这里执行 WORKDIR /app # 将本地 target 目录下的 jar 包复制进镜像并重命名为 app.jar COPY target/demo-0.0.1-SNAPSHOT.jar app.jar # 声明容器对外服务端口为 8080这个只是声明不直接生效 EXPOSE 8080 # 容器启动后运行的命令必须是 exec 格式字符串数组 ENTRYPOINT [java, -jar, /app/app.jar]FROM决定了基础镜像带-alpine的版本比较小适合部署在 Linux 服务器上。WORKDIR /app设置了当前目录后面COPY的第二个参数app.jar是相对路径实际会放到/app/app.jar。COPY的源路径是相对于 Dockerfile 上下文路径也就是你执行docker build时后面那个点号所指的目录所以 jar 包必须能在target/下找到文件名也要对应。EXPOSE更像文档真正让外部访问到容器端口要靠后面docker run -p。ENTRYPOINT这里必须写成 JSON 数组形式也就是带方括号否则容器启动时可能因为命令格式问题直接退出。这里有个容易忽略的点jar 包文件名里尽量不要带中文或特殊字符虽然 Windows 上能构建但镜像传到 Linux 后文件名解析偶尔会出乱子。项目如果是 Java 11 以上可以把基础镜像换成openjdk:11-jdk-slim启动命令和端口声明不用改。2.2 构建镜像docker build 的 -t 参数和末尾的上下文路径Dockerfile 准备好后打开 PowerShell把当前目录切到项目根目录也就是 Dockerfile 所在目录。执行构建命令前最好先确认 Docker Desktop 已启动否则会提示连不上 daemon。docker build -t springboot-demo:1.0.0 .-t的作用是给镜像起名并打 tagspringboot-demo:1.0.0中冒号前面是镜像名后面是版本号。最后那个.是构建上下文路径代表当前目录。Docker daemon 会把当前目录所有内容都接收过去作为上下文Dockerfile 里的COPY target/demo-0.0.1-SNAPSHOT.jar才能找到文件。这个点号不是装饰漏掉它命令会直接报“Dockerfile 未指定”。如果 Dockerfile 文件名不是默认的Dockerfile比如叫Dockerfile-dev那就需要加-f Dockerfile-dev指定。我平时会在项目里加一个.dockerignore文件把.git、.idea、target/*这些不需要打包进镜像的东西排除掉这样构建上下文体积小构建速度快很多。.git .idea target/*这个文件内容不是给镜像用的是让构建时不要往 daemon 传无关文件。构建完成后用docker images能看到刚才的镜像和大小。如果构建中间报错先看是下载基础镜像超时还是 COPY 找不到 jar 包这两类问题占大多数。2.3 运行容器-d、-p、--name 的配合镜像构建好后就可以用它创建容器了。第一次跑的时候我默认不加--net之类的参数先用最干净的配置把应用拉起来确认基础启动没问题再处理网络。docker run -d -p 8080:8080 --name springboot-demo-app springboot-demo:1.0.0-d表示后台运行跑完命令后终端不会卡住。-p 8080:8080左边是宿主机端口右边是容器内部端口外部访问localhost:8080会进入容器内的 8080。如果宿主机 8080 已经被其他服务占用可以改成8081:8080这个映射值不是死的。--name给容器起一个固定名字方便后续docker stop、docker logs引用。启动后用docker ps看容器状态。STATUS是Up说明还在运行如果过几秒变Exited那就是启动失败。查看日志是最直接的排查方法docker logs -f springboot-demo-app-f是持续跟踪日志输出看到Started DemoApplication之类的字样说明 Spring Boot 已经启动完成。如果日志末尾报数据库连接拒绝别急着搜数据库问题先想一下 jar 包里的application.yml配置的是哪个地址。如果你本机跑了一个 MySQL而容器默认是 bridge 网络它在容器里访问localhost指向的是容器自己不是宿主机这也是下一章要解决的问题。后面如果改了代码或配置流程需要重来一遍先重新打包 jar再重新构建镜像然后停止旧容器并删除最后用新镜像创建新容器。直接改容器里的文件是没用的容器一旦重建就会还原。3. 容器里的 Spring Boot 怎么访问数据库网络模式、ping 排查与 yml 配置3.1 先确认网络通不通docker exec 进容器执行 ping 和 telnetSpring Boot 容器默认跑在 bridge 网络它有一个独立的网段。如果数据库跑在宿主机上或者数据库在另一个容器里直接访问默认配置的 IP 很可能不通。我遇到这种情况第一反应不是改配置而是先进容器里做一次网络连通性验证。docker exec -it springboot-demo-app ping 192.168.1.100 docker exec -it springboot-demo-app telnet 192.168.1.100 3306docker exec -it是进入运行中容器的交互模式后面接容器名和要执行的命令。第一条命令用 ping 测主机可达性第二条用 telnet 测 3306 端口是否能连通。如果 ping 不通说明容器和数据库不在同一个可路由的网络里如果 ping 通但 telnet 不通说明端口被防火墙挡住或者 MySQL 没在监听。命令里的192.168.1.100要换成你数据库的实际 IP。如果在容器里没有 ping 或 telnet 命令那是因为基础镜像太精简可以改用docker exec -it springboot-demo-app sh进入容器后手动装工具或者直接跳过容器排查在宿主机上先看数据库端口是否正常监听。很多时候问题不在容器网络而在数据库配置本身。3.2 使用 --nethost 的临时方案和它的局限网上有一种说法是给docker run加--nethost容器共享宿主机的网络栈这样容器里访问localhost就等于访问宿主机。命令确实能跑docker run -d -p 8080:8080 --name springboot-demo-app --nethost springboot-demo:1.0.0但我不推荐把这当成正式方案。第一在 Linux 上用 host 网络时-p端口映射参数会被忽略容器直接占用宿主机端口多个容器之间容易冲突。第二Windows Docker Desktop 对 host 网络的支持并不完整经常出现“看起来加了参数实际上没生效”的情况。第三如果数据库部署在另一个服务器或另一个容器host 网络并不能解决所有连通问题。所以我一般只把这个参数用在临时调试上真正要稳定连接数据库还得靠自定义网络 容器名解析。3.3 创建自定义网络让容器名互通最稳妥的做法是创建一个自定义 bridge 网络把 Spring Boot 容器、MySQL 容器、Redis 容器都放进去。在同一个网络里容器之间可以直接用容器名互相访问Docker 自带的 DNS 会解析到对应 IP。docker network create dev_net docker network connect dev_net mysqldoc docker network connect dev_net redis docker network connect dev_net springboot-demo-appdocker network create dev_net创建了一个名为dev_net的网络。docker network connect可以把一个已经存在的容器加入该网络支持在容器运行中操作。这里mysqldoc、redis、springboot-demo-app分别是容器名你可以按自己的名称替换。更推荐的做法是docker run创建 Spring Boot 容器时直接指定网络避免容器同时挂在两个网络下产生不确定的路由docker run -d -p 8080:8080 --network dev_net --name springboot-demo-app springboot-demo:1.0.0这样容器启动时就属于dev_net与 MySQL、Redis 之间用容器名访问IP 随便变都不影响。3.4 修改 yml 配置并重建容器网络配好后Spring Boot 项目里application.yml的数据源地址就不能写成 IP 了要改成容器名。下面是一个典型配置spring: datasource: url: jdbc:mysql://mysqldoc:3306/yourdb?useSSLfalseserverTimezoneAsia/Shanghai username: root password: root redis: host: redis port: 6379 password: redis注意这里写的端口是容器内部端口MySQL 是 3306Redis 是 6379不是宿主机对外映射的 3307、6380。容器间通信走内部端口外部工具才走映射端口这是最容易混的地方。如果你 MySQL 容器映射到了宿主机 3307那只是给宿主机和外部工具用的容器内部访问 MySQL 依然用 3306。改完 yml 后需要重新打包 jar再重新构建镜像并重建容器。Spring Boot 的配置在 jar 内部不重打镜像就不会生效运行时在容器里改配置文件是没用的。完整流程就是mvn clean package -DskipTests docker build -t springboot-demo:1.0.0 . docker stop springboot-demo-app docker rm springboot-demo-app docker run -d -p 8080:8080 --network dev_net --name springboot-demo-app springboot-demo:1.0.0docker stop是停止容器docker rm是删除容器。因为容器名不能重复旧容器没删干净直接docker run --name会报 name already in use。3.5 数据库授权别让 host 字段卡住你哪怕网络通了MySQL 也可能拒绝连接因为在 MySQL 里用户是绑定 host 的。我一般会进入 MySQL 容器创建一个允许任意来源的账号免得被 IP 问题卡住。docker exec -it mysqldoc mysql -uroot -p执行下面的 SQLCREATE USER root% IDENTIFIED BY root; GRANT ALL PRIVILEGES ON *.* TO root% WITH GRANT OPTION; FLUSH PRIVILEGES;root%表示这个用户可以从任意 IP 连接如果你只想让某个开发机连接可以把%换成具体 IP比如root192.168.0.27。但如果你用容器名mysqldoc访问实际来源 IP 是容器网络里的地址限制太严反而连不上所以开发环境我一般直接用%。MySQL 8 默认用caching_sha2_password认证插件如果你的 JDBC 驱动太老可能报Authentication plugin caching_sha2_password cannot be loaded。可以执行下面这条 SQL 兼容一下ALTER USER root% IDENTIFIED WITH mysql_native_password BY root; FLUSH PRIVILEGES;这个坑在旧项目里特别常见服务端和客户端驱动版本不一致时出现频率很高。4. 把 MySQL 和 Redis 也容器化挂载目录与端口映射的取舍4.1 先规划目录数据卷必须落在宿主机上Spring Boot 连接数据库的问题是解决了但如果你还没有数据库容器或者数据库不在目标 Linux 上那这一步就得把 MySQL 和 Redis 也容器化。容器本身是无状态的一删就什么都没了所以数据必须通过-v挂载到宿主机目录。在 Windows 上我习惯把所有 Docker 数据卷集中放到一个目录比如D:\development_sources\docker。先建四个 MySQL 相关目录mkdir D:\development_sources\docker\mysql\log mkdir D:\development_sources\docker\mysql\data mkdir D:\development_sources\docker\mysql\conf mkdir D:\development_sources\docker\mysql\mysql-files这四个目录分别对应容器内的日志目录、数据文件目录、配置文件目录和文件导入导出目录。mysql-files对应 MySQL 的secure_file_priv权限导入导出 CSV 时会用到。路径里的反斜杠在 PowerShell 里可以直接用但如果你切到 Git Bash 或 WSL 里执行路径格式要改成/d/development_sources/...否则 Docker 不认。4.2 启动 MySQL 8.0.24 容器目录准备好后执行 MySQL 容器创建命令。我这边宿主机 3306 已经被本机 MySQL 占用了所以将容器 3306 映射到宿主机的 3307。docker run -p 3307:3306 --restartalways --name mysqldoc \ -v D:\development_sources\docker\mysql\log:/var/log/mysql \ -v D:\development_sources\docker\mysql\data:/var/lib/mysql \ -v D:\development_sources\docker\mysql\conf:/etc/mysql \ -v D:\development_sources\docker\mysql\mysql-files:/var/lib/mysql-files \ -e MYSQL_ROOT_PASSWORDroot \ -d mysql:8.0.24-p 3307:3306将容器内 MySQL 默认端口 3306 映射到宿主机 3307外部访问用 3307容器内部还是 3306。--restartalways指定容器在 Docker 重启或异常退出时自动启动这个参数对服务器环境很重要。-v后面四组分别把日志、数据、配置、导入导出目录挂载到宿主机。-e MYSQL_ROOT_PASSWORDroot在容器第一次初始化时设置 root 密码如果data目录里已经有旧数据这个环境变量会被忽略。这里有一个细节如果data目录是第一次挂载容器会自动初始化 MySQL 数据。如果这个目录之前已经有别的一套 MySQL 数据再用同一个镜像去启动可能会报版本或权限不匹配。所以迁移镜像时数据目录要一并备份或迁移不能只搬容器。4.3 启动 Redis 容器Redis 相对于 MySQL 要简单一些只需要一个数据目录。我先建目录再启动容器mkdir D:\development_sources\docker\redis\data docker run -p 6380:6379 --restartalways --name redis \ -v D:\development_sources\docker\redis\data:/data \ -d redis \ redis-server --appendonly yes --requirepass redis这里-p 6380:6379是因为宿主机的 6379 也被占用所以把 Redis 容器端口映射到宿主机 6380。-v把宿主机目录挂载到容器内/dataRedis 的持久化文件会写在这里。最后的redis-server --appendonly yes --requirepass redis是覆盖容器默认启动命令开启 AOF 持久化并设置访问密码为redis。--appendonly yes表示每个写操作都会追加到 AOF 文件重启后可以恢复数据适合对数据安全性要求高的场景。--requirepass redis是设置密码如果这里不设Spring Boot 配置里的password: redis就会报认证失败。外部工具连接时端口填 6380密码填redis。4.4 将 MySQL 和 Redis 连接到 dev_net并做外部访问验证容器都起来后需要把它们加进dev_net这样 Spring Boot 容器才能用容器名访问。如果之前已经创建过网络用下面命令直接连接docker network create dev_net docker network connect dev_net mysqldoc docker network connect dev_net redisdocker network create如果遇到“network already exists”的报错说明网络已经存在直接跳到 connect 就行。连接完成后外部工具有一张参数表可以参考服务容器名容器内端口宿主机映射端口密码MySQLmysqldoc33063307rootRedisredis63796380redis用 Navicat 连 MySQL 时主机填宿主机 IP端口填 3307用户填 root密码填 root。用 Another Redis Desktop Manager 连 Redis 时地址填宿主机 IP端口填 6380密码填 redis。如果从其他电脑连不上优先查宿主机防火墙是否放行了 3307 和 6380以及云服务器的安全组规则。5. Windows 到 Linux 的镜像搬运docker save 导出、scp 上传、docker load 加载5.1 导出镜像用 docker save 而不是 docker exportWindows 上的环境都调试好后要把整套东西搬到 Linux。这里有个关键点要导出的是镜像不是容器。docker export导出的是容器文件系统不包含镜像层历史Load 回来后不能直接docker run成原本的镜像。所以必须用docker save。docker save -o springboot-demo.tar springboot-demo:1.0.0 docker save -o mysql.tar mysql:8.0.24 docker save -o redis.tar redis-o指定导出的 tar 包文件名后面跟镜像名。如果你有多个镜像需要一次导出也可以在一条命令里写多个镜像名但我习惯分开导出这样上传到 Linux 后可以单独加载排查问题也更方便。注意镜像名要写完整带 tag 就写 tag缺了容易在 load 后出现none。导出完成后可以在 Windows 上看到这几个 tar 文件。文件体积一般不小Spring Boot 镜像如果基础镜像大可能几百 MB。如果网络带宽有限可以先压缩再传在 PowerShell 里可以直接用 tar 命令压缩tar -czf springboot-demo.tar.gz springboot-demo.tar但优先建议直接传输原始 tar 包免得在 Windows/Linux 之间压缩格式不兼容导致解压乱掉。5.2 准备 Linux 环境安装 Docker 并启动我这边 Linux 服务器是 CentOS 7。拿到一个全新环境先不急着传镜像先把 Docker 装好。如果是开发环境我习惯先关防火墙因为后面要放行 8080、3307、6380 等多个端口省得一个个配置。生产环境千万别照做。systemctl stop firewalld systemctl disable firewalld然后更新 yum 包。yum -y update会连系统和内核一起升级耗时较长如果只想更新软件包不升内核用yum -y upgrade。开发环境我一般直接 update生产环境会保持谨慎。yum -y updateDocker 安装前先把可能残留的旧版本卸载干净否则版本冲突很烦yum remove docker docker-common docker-selinux docker-engine然后安装依赖工具和阿里云 yum 源yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum list docker-ce --showduplicates | sort -ryum-utils提供yum-config-manager后两个是 Docker 存储驱动依赖。阿里云源在国内下载速度比官方源快得多。yum list可以列出所有可用版本方便挑一个指定版本安装。我这次按照原环境选的是18.03.1.ce这是一个比较老的版本但在这台 CentOS 7 上能稳定跑。如果你的内核太新反而建议选 20.10 以上的版本具体可以对照 Docker 官方兼容矩阵。yum -y install docker-ce-18.03.1.ce systemctl start docker systemctl enable docker docker versionsystemctl start docker启动 Docker 服务systemctl enable docker设置开机自启。docker version能同时看到 client 和 server 版本如果只显示 client 而 server 报错说明 daemon 没起来看/var/log/messages或运行systemctl status docker。5.3 上传镜像并加载到 LinuxDocker 装好后把 Windows 上的 tar 包传到 Linux。我用的是 Finalshell 这类带图形界面的工具直接拖文件上传很方便。命令行场合下scp 更快scp springboot-demo.tar mysql.tar redis.tar root192.168.x.x:/root/loadimages/上传后在 Linux 上加载镜像cd /root/loadimages docker load -i springboot-demo.tar docker load -i mysql.tar docker load -i redis.tar docker imagesdocker load -i是从指定 tar 文件导入镜像。导入后docker images应该能看到与 Windows 上一致的镜像名和 tag。如果看到none说明导出时镜像仓库和标签信息丢了需要用docker tag重新打标。镜像加载完之后运行容器时数据卷路径必须改为 Linux 路径。Windows 的D:\development_sources\docker\mysql\data在 Linux 上是不存在的直接复用命令会导致挂载失败。我在 Linux 上习惯把数据放到/data/docker下mkdir -p /data/docker/mysql/{log,data,conf,mysql-files} mkdir -p /data/docker/redis/data然后启动 MySQLdocker run -p 3307:3306 --restartalways --name mysqldoc \ -v /data/docker/mysql/log:/var/log/mysql \ -v /data/docker/mysql/data:/var/lib/mysql \ -v /data/docker/mysql/conf:/etc/mysql \ -v /data/docker/mysql/mysql-files:/var/lib/mysql-files \ -e MYSQL_ROOT_PASSWORDroot -d mysql:8.0.24Redis 同理docker run -p 6380:6379 --restartalways --name redis \ -v /data/docker/redis/data:/data \ -d redis redis-server --appendonly yes --requirepass redisSpring Boot 容器启动前记得先创建网络并把数据库容器加进去docker network create dev_net docker network connect dev_net mysqldoc docker network connect dev_net redis docker run -d -p 8080:8080 --network dev_net --name springboot-demo-app springboot-demo:1.0.0注意网络dev_net不会随镜像一起被 save/load所以到 Linux 后必须重新创建。这一步漏了容器名解析就会失败应用照样连不上数据库。6. 镜像迁移与容器联调中的常见问题避坑现象、原因、解决6.1 Windows 数据卷路径直接搬到 Linux 导致挂载失败现象在 Linux 上执行原本 Windows 用的docker run命令容器启动失败docker logs mysqldoc里报mkdir: cannot create directory /var/lib/mysql或chown: /var/lib/mysql: operation not permitted。原因Windows 路径D:\development_sources\docker\mysql\data在 Linux 上不存在Docker 会尝试创建一个名为D:的相对路径或直接报错导致挂载源无效。解决把-v左侧的宿主机路径改成 Linux 绝对路径比如/data/docker/mysql/data并提前用mkdir -p建好目录。如果数据目录权限不对可以执行chown -R 999:999 /data/docker/mysql/data因为 MySQL 容器内部用户 UID 是 999。6.2 容器重启后 IP 变化导致 yml 写了固定 IP 连不上现象Spring Boot 容器第一次能连上数据库重启容器后报Connection refused检查容器 IP 发现已经变了。原因默认 bridge 网络的容器 IP 是动态分配的重启后可能变。application.yml里如果写的是容器 IPIP 一变就失效。解决使用自定义网络并把 yml 里的数据库地址改成容器名。创建网络docker network create dev_netSpring Boot 容器启动时加--network dev_netMySQL 容器也连接该网络然后 yml 里写mysqldoc:3306而不是 IP。这样无论容器 IP 怎么变Docker 内部 DNS 都能解析到容器名。6.3 docker save 导出镜像后 load 到 Linux 出现 标签现象docker images里多了一个none的镜像名用docker run springboot-demo:1.0.0报找不到镜像。原因docker save时没有写完整 tag或者原镜像本身就是none。比如docker save -o demo.tar 5f02c1e8a6a3只保存了镜像 IDrepository 信息为空load 回来自然没有名字。解决导出前先确认docker images里镜像名和 tag 完整。load 后发现none用docker tag补上镜像名docker tag 镜像ID springboot-demo:1.0.0镜像ID用docker images里的 IMAGE ID 前几位即可。6.4 防火墙关了从其他电脑还是连不上容器端口现象systemctl stop firewalld已经执行在 Linux 本机curl localhost:8080能通但从其他电脑连不上 8080 或 3307。原因不是 firewalld 拦截而是 SELinux 或云安全组在起作用。CentOS 7 的 SELinux 可能拦截 Docker 端口映射云服务器厂商的安全组也独立于系统防火墙。解决先在 Linux 上确认端口在监听执行ss -tlnp | grep 3307如果能看到监听列表再执行getenforce查看 SELinux 状态临时关闭可以用setenforce 0。如果问题出在公网入方向需要到云控制台安全组放行对应端口。生产环境不建议全局关 SELinux应该用semanage port -a -t http_port_t -p tcp 8080之类的方式放行。6.5 宿主机端口被占用导致容器启动失败现象执行docker run -p 3306:3306 mysql时报错bind: address already in use容器根本没创建。原因宿主机上已经有一个进程占用了 3306 端口Docker 无法再把该端口映射给容器。解决换一个宿主机端口比如-p 3307:3306。容器内部端口不变外部访问 3307 即可。这时候要注意如果其他容器要访问 MySQL应该用容器名mysqldoc和内部端口 3306不要被映射端口带偏。7. 装完怎么验证从日志、端口、访问到自启动一条命令都不少整套环境在 Linux 上搭好后我一般会强制自己按下面四步走一遍每步都能揪出不同层面的问题。第一步确认容器都在运行。执行docker ps看 mysqldoc、redis、springboot-demo-app 的STATUS是不是UpPORTS列有没有显示0.0.0.0:8080-8080/tcp、0.0.0.0:3307-3306/tcp、0.0.0.0:6380-6379/tcp。如果有容器变Exited马上docker logs 容器名先处理启动报错。第二步验证应用接口。在 Linux 本地执行curl http://localhost:8080/actuator/health或者你自己项目里定义的某个接口。能返回 JSON 说明 Spring Boot 起来了如果返回连接错误马上看日志多半是数据库或 Redis 地址没改对。注意有的 Spring Boot 接口没加 health 端点会返回 404这是正常的这时候直接看docker logs -f springboot-demo-app最后几行有没有Started就够。第三步验证外部工具连接。在另一台电脑上用 Navicat 连宿主机IP:3307用户 root密码 root用 Another Redis Desktop Manager 连宿主机IP:6380密码 redis。连不上就一层层排查先ss -tlnp | grep 3307看端口是否监听再执行getenforce看 SELinux最后检查云安全组。这套顺序能定位绝大多数“本地能连远端连不上”的问题。第四步重启 Docker 验证自启。执行systemctl restart docker等十几秒后再docker ps--restartalways的那几个容器必须自动回到Up状态。如果 Spring Boot 容器没起来很可能是它比 MySQL 先启动了JDBC 连接池还没等到数据库就绪。这时候可以在 docker run 命令里加--restartalways并配合 Spring Boot 的重试机制或者用 Docker Compose 的depends_on加condition: service_healthy控制启动顺序。从那以后我每次迁移 Spring Boot 镜像到 Linux都会强制自己走一遍docker ps、docker logs、curl 接口、systemctl restart docker这四个动作缺一个都可能把问题留到半夜。这次记录下来的数据卷路径、容器名解析、端口映射冲突这些坑也都是一次次翻车后总结出来的。希望帮到你照着这套流程走完Windows 上构建的镜像到 Linux 上跑通不会比你想象中更难。本文还有配套的精品资源点击获取
RELATED

相关推荐

企业微信 API 接口:微信客服消息接收与自动回复

企业微信 API 接口:微信客服消息接收与自动回复

微信客服是企微的一个特殊场景——客户从微信侧发起咨询,企微侧通过 API 接收和回复。这个场景和普通单聊、群聊的接口逻辑有差异,这篇专门讲清楚。先搞清"微信客服"是什么微信客服是企微提供的一种客服能力。客户在微信里(视频号、…

📅 2026/10/20 17:08:57
拼多多客服机器人接入实战:对话中台工程化落地指南

拼多多客服机器人接入实战:对话中台工程化落地指南

简介:这是一套面向拼多多商家的智能客服机器人落地实现方案,解决电商大促期间人工客服响应不及时、重复咨询处理效率低等痛点,适用于具备基础Windows部署能力的中小商家或技术运维人员。资源包共18个文件,含4个核心DLL插件&#x…

📅 2026/10/20 17:08:57
Skill开发避坑指南:如何让技能扛住用户的一百种说法

Skill开发避坑指南:如何让技能扛住用户的一百种说法

1. 从“一次能跑”到“换个说法就废”:一个被忽视的Skill设计陷阱你有没有遇到过这种情况:自己写了一个Skill,第一次测试的时候,输入一句指令,它跑得漂漂亮亮,输出结果完全符合预期。你心里一阵窃喜&#x…

📅 2026/10/20 17:08:56
MORE NEWS

更多资讯

📰

提示词工程师会消失吗?从模型进化看AI职业转型之路

“提示词工程师”这个职位,这两年算是坐了趟过山车。2023年那阵子,只要你舍得研究怎么跟AI好好说话,就有人把这套东西包装成年薪百万的魔法;到了2025年风向又急转直下,朋友圈里开始刷屏说,这岗位可能是2026…

📰

LeetCode 730详解:区间DP与容斥原理解决不同回文子序列计数

第一次看到LeetCode 730这道题的时候,我的第一反应是“这题怎么又是Hard”。再仔细读两遍,发现它把三个很容易让人头大的点揉在了一起:子序列、回文、去重。单独看每个词都没那么可怕,但是组合起来就成了经典的区间DP难题。题目给…

📰

AI透明度危机:大模型安全评测、脑机接口与幻觉治理的底层逻辑

最近在刷资讯的时候,一条聚合日报里同时出现了三个看似互不相干的消息:国内大模型发布时披露安全评测结果的比例低得惊人,脑机接口领域又拿出了类似“读心帽”的新成果,某主流AI助手在对话中向用户“指认”了一起凶杀案线索&#…

📰

LeetCode 730 不同回文子序列:动态规划去重与Java实现

LeetCode 730 这题,光看标题就带着一股 hard 题特有的气场: countPalindromicSubsequences ,统计不同回文子序列。我第一次刷到的时候,先让 Qwen3.5-Plus 帮忙给了一版思路,模型不到十秒就甩出了“二维 DP 容斥”的…

📰

数据库设计与应用开发实战:ER图、索引优化与事务控制要点

数据库系统概论学到设计与应用开发这一章,大概是很多人最摸不着头脑的地方。前面几章关系代数、SQL、完整性约束都是明确的知识点,考试能背、能写。但到了设计,突然没有标准答案了:一张业务表怎么拆,ER图画到什么程度&…

📰

DE/SHADE/L-SHADE算法在CEC2005基准函数上的Matlab对比实验及实现细节

做算法对比实验最怕的不是算法本身跑不出来,而是对比口径不统一,跑完一遍结果根本没法写进论文。我最近把差分进化算法(DE)以及它的两条改进线——SHADE(带成功历史自适应的DE)和L-SHADE(线性种…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬