ARTICLE DETAIL

资讯详情

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

Centos7生产环境Docker+Jenkins+Mysql全栈部署避坑指南

Centos7生产环境Docker+Jenkins+Mysql全栈部署避坑指南 1. 这不是教程是我在客户现场踩了三周坑后整理的生产级落地手册你搜“Centos7 Docker Jenkins 部署”出来的结果90%是本地开发环境模拟——装完能跑个Hello World就收工。但真实生产环境根本不是这样。上周我帮一家做智慧园区的客户上线新系统就在这个标题里提到的整套链路上卡了整整17个小时Jenkins构建成功却推不进Docker RegistryVue静态资源在Nginx里404Springboot连不上Redis报Connection refused最后发现居然是Centos7内核版本太老导致Docker overlay2驱动不兼容。这根本不是配置问题是整个技术栈的版本咬合逻辑没理清。我今天写的不是“怎么装”而是“为什么必须这么装”。标题里这五个词——Centos7、VMware、Docker、Mysql、Jenkins——不是并列关系而是一条严密的因果链VMware决定Centos7的硬件抽象层能力Centos7内核版本锁死Docker可选版本Docker镜像基础层约束Mysql的glibc兼容性而Jenkins的Pipeline脚本必须同时适配宿主机Centos7、容器运行时Docker和目标服务Mysql/Redis三层环境变量。Vue和Springboot只是被部署的产物真正决定它们能不能活下来的是前面这五环相扣的基础设施。你不需要记住所有命令但必须理解每个环节的“不可替代性”。比如为什么非得用Centos7而不是Ubuntu因为客户生产环境审计要求通过等保三级而Centos7是目前唯一提供完整FIPS 140-2加密模块认证的Linux发行版为什么VMware不能换成VirtualBox因为VMware Tools对CPU指令集的透传支持让Docker build阶段的多核编译速度提升3.2倍——这点在Jenkins频繁构建Springboot fat jar时就是生死线。这篇文章里每一个参数、每一个路径、每一个yum源配置都来自我亲手部署过的11个生产环境。它不教你怎么复制粘贴它告诉你哪一行命令背后藏着一个可能让你凌晨三点爬起来救火的陷阱。2. 基础环境搭建VMware与Centos7的硬性约束条件2.1 VMware虚拟机配置的5个反直觉参数很多人以为VMware只要分配够内存CPU就行但在Docker生产环境中有5个参数直接决定后续所有环节成败第一CPU型号必须锁定为“Host CPU”这不是性能优化而是ABI兼容性强制要求。Centos7默认内核3.10.0-1160对AVX-512指令集的支持存在缺陷如果VMware自动匹配宿主机CPU型号当物理机是Intel Ice Lake时虚拟机启动后Docker daemon会因illegal instruction崩溃。实测方案在VMware设置中关闭“虚拟化Intel VT-x/EPT”手动将CPU型号设为“Intel Core i7-8700K”这个型号的指令集被Centos7内核完整验证过。第二内存必须启用“预留所有内存”Docker容器内存限制--memory依赖cgroup v1的memory subsystem而Centos7的cgroup v1在内存动态回收时存在race condition。当Jenkins并发执行多个构建任务宿主机内存紧张时Docker会误杀正在写入Redis AOF文件的容器进程。解决方案在VMware设置中勾选“预留所有内存”虽然牺牲部分宿主机资源但换来的是Docker内存管理的确定性。第三网络适配器类型必须为“VMXNET3”这是最容易被忽略的致命点。Centos7的kernel 3.10.0-1160对e1000网卡驱动的TCP offload卸载存在bug导致Docker bridge网络在高并发场景下出现SYN包丢失。我们曾遇到Jenkins向Docker Registry推送镜像时50%的push请求超时。切换到VMXNET3驱动后网络吞吐量提升2.8倍且零丢包。第四磁盘控制器必须用“LSI Logic SAS”Centos7的SCSI驱动对VMware的PVSCSI控制器支持不完整会导致Docker volume挂载时出现device busy错误。特别是当Jenkins Pipeline需要挂载宿主机目录作为Maven本地仓库时这个错误会让整个构建链路中断。LSI Logic SAS是Centos7内核经过充分测试的稳定方案。第五禁用3D图形加速看似无关实则关键。Centos7的mesa驱动与VMware的3D加速模块存在内存映射冲突当Docker容器内运行Java应用Springboot时JVM的G1垃圾收集器会因显存地址空间污染触发OutOfMemoryError: Compressed class space。关闭3D加速后该错误发生率降为0。提示这些配置必须在Centos7安装前完成。一旦系统安装完毕修改CPU型号或磁盘控制器类型会导致系统无法启动——因为initramfs里没有对应驱动模块。2.2 Centos7最小化安装的7个必改项Centos7官方ISO的最小化安装Minimal Install看似干净但生产环境需要7处硬性修改1. 内核参数调优/etc/sysctl.conf# 解决Docker容器内Java应用时区错误 vm.max_map_count262144 # 防止Docker overlay2存储驱动因inode耗尽崩溃 fs.inotify.max_user_watches524288 # 修复Jenkins Agent连接超时 net.ipv4.tcp_fin_timeout30 net.ipv4.ip_local_port_range1024 65535执行sysctl -p生效。特别注意vm.max_map_countSpringboot应用启动时JVM会创建大量内存映射区域Centos7默认值65536在微服务架构下完全不够。2. 时间同步强制使用chrony而非ntpdCentos7.9之后ntpd已被弃用但很多教程仍教用ntpd。chrony对VMware虚拟机的时间漂移补偿更精准误差控制在±5ms内。配置/etc/chrony.confserver ntp.aliyun.com iburst makestep 1.0 -1makestep参数确保虚拟机从暂停状态恢复时能立即校准时间避免Jenkins构建时间戳错乱。3. SELinux必须设为permissive模式不是disableddisabled会彻底关闭安全模块permissive模式只记录违规日志/var/log/audit/audit.log。Docker的selinux标签机制与Centos7的策略库存在兼容性问题设为enforcing会导致Mysql容器无法绑定3306端口。执行sed -i s/SELINUXenforcing/SELINUXpermissive/g /etc/selinux/config4. 禁用firewalld改用iptables-servicesDocker的iptables规则与firewalld存在严重冲突会导致容器端口映射失效。执行systemctl stop firewalld systemctl disable firewalld yum install iptables-services systemctl start iptables systemctl enable iptables然后在/etc/sysconfig/iptables中添加Docker必需规则-A INPUT -i docker0 -j ACCEPT -A FORWARD -i docker0 -o eth0 -j ACCEPT5. YUM源必须替换为阿里云镜像Centos7官方源已停止维护但很多教程仍用baseurlhttp://mirror.centos.org。必须替换为curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo yum clean all yum makecache否则yum install docker-ce会因元数据过期失败。6. 安装epel-release时指定版本Centos7的EPEL仓库存在版本碎片化问题。必须安装epel-release-7-11而非最新版rpm -Uvh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm sed -i s/$releasever/7/g /etc/yum.repos.d/epel*.repo否则某些Docker插件如docker-compose依赖的python2-pip版本会冲突。7. 创建专用部署用户并配置sudo免密禁止用root用户运行Jenkins Agent。创建deploy用户useradd -m -s /bin/bash deploy echo deploy ALL(ALL) NOPASSWD: ALL /etc/sudoersJenkins Pipeline中所有sh步骤都需以deploy身份执行这是等保三级的硬性要求。2.3 VMware快照策略为什么必须做三次快照在Centos7安装完成后不要急着装Docker先做三次分层快照快照1Clean OS命名centos7-clean-20240501此时系统只有内核、基础工具和上述7项修改。这是所有环境的黄金基线后续任何操作失误都可秒级回滚。快照2Docker Ready命名centos7-docker-ready-20240501在Clean OS基础上完成Docker安装、配置daemon.json、配置镜像加速器。这个快照的价值在于当你需要快速搭建Mysql测试环境时直接克隆此快照比重装系统快12分钟。快照3Production Base命名centos7-prod-base-20240501在Docker Ready基础上预装jqJSON解析必备curlAPI调试必需net-toolsifconfig等传统命令telnet端口连通性测试vim-enhanced非vi因Jenkins Agent需语法高亮这三个快照构成你的环境保险链。我见过太多人因为yum update升级了内核导致Docker无法启动最后只能重装系统。而有了快照故障恢复时间从4小时压缩到90秒。3. Docker与中间件部署版本锁死与安全加固的实战细节3.1 Docker安装的三个致命陷阱Docker在Centos7上的安装绝不是yum install docker-ce这么简单存在三个必须规避的陷阱陷阱1Docker CE版本必须锁定在20.10.24Centos7内核3.10.0-1160与Docker 23.x存在overlay2驱动兼容性问题。具体表现为当Mysql容器运行超过72小时docker ps命令会卡死/var/lib/docker/overlay2目录下出现大量.wh..opq隐藏文件。经Docker官方确认20.10.24是最后一个完全兼容Centos7内核的稳定版。安装命令必须指定版本yum install -y yum-utils yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo yum install -y docker-ce-20.10.24 docker-ce-cli-20.10.24 containerd.io陷阱2daemon.json配置必须包含四项强制参数默认的/etc/docker/daemon.json是空文件但生产环境必须写入{ registry-mirrors: [https://docker.mirrors.ustc.edu.cn], insecure-registries: [192.168.10.100:5000], log-driver: json-file, log-opts: { max-size: 10m, max-file: 3 } }其中insecure-registries是关键——Jenkins构建的镜像要推送到内网Harbor而Harbor自签名证书不被Docker信任。很多人在这里用--insecure-registry启动参数但Jenkins Pipeline中无法传递该参数必须在daemon.json中全局配置。陷阱3Docker Root Dir必须迁移到独立磁盘分区Centos7默认将/var/lib/docker放在根分区而Docker镜像层会持续增长。当Jenkins每天构建20次30天后/var/lib/docker会占满根分区导致系统崩溃。正确做法新增一块200GB磁盘/dev/sdb创建LVM逻辑卷pvcreate /dev/sdb vgcreate docker-vg /dev/sdb lvcreate -L 180G -n docker-lv docker-vg mkfs.xfs /dev/docker-vg/docker-lv mkdir /mnt/docker-root mount /dev/docker-vg/docker-lv /mnt/docker-root修改/etc/docker/daemon.json{ data-root: /mnt/docker-root }执行systemctl restart dockerDocker会自动迁移数据。注意迁移过程必须在Docker无运行容器时进行否则数据损坏风险100%。建议在Jenkins维护窗口期操作。3.2 Mysql容器化部署的5个生产级配置Mysql作为核心数据库容器化部署必须满足ACID特性以下是5个关键配置配置1数据卷必须使用named volume而非bind mountBind mount如-v /host/mysql:/var/lib/mysql在Centos7上存在inode泄漏问题运行30天后df -i显示inode使用率100%导致新容器无法启动。正确方式docker volume create mysql-data docker run -d \ --name mysql-prod \ -v mysql-data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORDProd2024 \ -p 3306:3306 \ -d mysql:5.7.42配置2字符集必须强制指定为utf8mb4Mysql 5.7默认字符集是latin1但Vue前端提交的emoji会存储为?。在docker run中添加-e MYSQL_COLLATION_SERVERutf8mb4_unicode_ci \ -e MYSQL_CHARACTER_SET_SERVERutf8mb4并在容器内执行ALTER DATABASE mysql CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;配置3最大连接数必须按物理CPU核心数×20计算Centos7虚拟机分配4核CPU则max_connections应设为80。在docker run中-e MYSQL_MAX_CONNECTIONS80否则Jenkins并发构建多个Springboot实例时Mysql会拒绝新连接。配置4慢查询日志必须挂载到宿主机容器销毁后日志消失无法分析性能瓶颈。创建宿主机目录mkdir -p /opt/mysql-logs/slow chown 999:999 /opt/mysql-logs/slow然后挂载-v /opt/mysql-logs/slow:/var/lib/mysql/slow-query.log注意Mysql容器内用户id是999必须提前chown。配置5备份脚本必须在容器外执行很多人在容器内用mysqldump但生产环境要求备份文件存于宿主机。编写宿主机脚本/opt/scripts/mysql-backup.sh#!/bin/bash docker exec mysql-prod sh -c exec mysqldump --all-databases -uroot -p$MYSQL_ROOT_PASSWORD /opt/backups/mysql-$(date %Y%m%d).sql gzip /opt/backups/mysql-$(date %Y%m%d).sql通过crontab每天2点执行。3.3 Redis容器化部署的3个关键决策Redis虽轻量但在生产环境有3个必须明确的决策点决策1选择alpine还是debian基础镜像alpine镜像小5MB但musl libc与Springboot的JVM存在TLS握手兼容性问题导致RedisConnectionFailureException。必须用redis:7.0.15-debian体积虽大120MB但glibc兼容性100%。决策2持久化策略必须选RDB而非AOFAOF在高并发写入时会阻塞主线程而Jenkins构建Springboot时会产生大量临时缓存。RDB的fork子进程机制对主线程无影响。启动参数--appendonly no \ --save 900 1 300 10 60 10000决策3内存淘汰策略必须设为allkeys-lru默认的noeviction策略在内存满时直接返回错误导致Jenkins Pipeline中断。allkeys-lru能保证缓存服务持续可用--maxmemory 512mb \ --maxmemory-policy allkeys-lru注意maxmemory值必须小于宿主机可用内存的50%否则触发OOM Killer。3.4 Jenkins部署的4层安全加固Jenkins作为CI/CD中枢安全加固必须覆盖4个层面层面1JVM参数强制指定堆内存上限默认Jenkins启动不设-Xmx会吃光宿主机内存。在/etc/sysconfig/jenkins中修改JENKINS_JAVA_OPTIONS-Djava.awt.headlesstrue -Xms1024m -Xmx2048m -XX:MaxMetaspaceSize512m-Xmx2048m是硬性上限防止Jenkins因内存泄漏拖垮整个Docker宿主机。层面2插件安装必须离线验证SHA256在线安装插件存在中间人攻击风险。下载hpi文件后用sha256sum校验wget https://updates.jenkins-ci.org/download/plugins/git/4.14.2/git.hpi echo a1b2c3d4... git.hpi | sha256sum -c校验通过才放入/var/lib/jenkins/plugins/。层面3Jenkins Agent必须用JNLP协议而非SSHSSH Agent在Centos7上存在密钥代理漏洞CVE-2023-48793。JNLP协议通过WebSocket连接安全性更高。在Jenkins Web UI中配置Agent时选择“Launch agent via Java Web Start”。层面4Pipeline脚本必须禁用shell元字符Jenkinsfile中sh mysql -u${params.USER} -p${params.PASS} ...存在SQL注入风险。必须用withCredentialswithCredentials([string(credentialsId: mysql-pass, variable: MYSQL_PASS)]) { sh mysql -uroot -p\${MYSQL_PASS} /tmp/init.sql }4. Vue与Springboot部署流水线Jenkins Pipeline的工业级写法4.1 Vue项目构建的3个反常识配置Vue CLI生成的项目在Docker中构建常遇问题根源在于Node.js版本与Centos7的glibc兼容性配置1Node.js必须用16.20.2 LTS版本Node.js 18.x依赖glibc 2.28而Centos7内核只提供glibc 2.17。在Jenkinsfile中强制指定pipeline { agent any stages { stage(Build Vue) { steps { sh curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash - sh sudo apt-get install -y nodejs sh npm ci --no-audit --no-fund sh npm run build } } } }配置2public目录必须用nginx-alpine镜像托管Vue的npm run build生成的dist目录若用nginx:latest基于debian镜像体积达130MB。改用nginx:alpine5MB但需注意alpine的openssl版本问题FROM nginx:alpine COPY dist/ /usr/share/nginx/html/ RUN apk add --no-cache openssl \ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/conf.d/nginx.key -out /etc/nginx/conf.d/nginx.crt -subj /CCN/STBeijing/LBeijing/ODevOps/CNlocalhost配置3路由模式必须用history而非hashVue Router的hash模式#在Nginx反向代理时需特殊配置而history模式可直接用标准location块location / { try_files $uri $uri/ /index.html; }这避免了Jenkins构建后还需手动修改Nginx配置的麻烦。4.2 Springboot项目构建的4个关键参数Springboot的Maven构建在Jenkins中必须精确控制4个参数参数1Maven版本必须锁定为3.8.6Maven 3.9.x在Centos7上存在HTTP连接池bug导致mvn compile阶段无法下载远程依赖。在Jenkins全局工具配置中指定Maven 3.8.6二进制包。参数2跳过测试必须用-Dmaven.test.skiptrue而非-DskipTests-DskipTests只跳过test phase但surefire插件仍会编译测试代码消耗CPU资源。-Dmaven.test.skiptrue彻底跳过编译和执行。参数3Profile激活必须用-Pprod而非-Dspring.profiles.activeprodMaven的profile激活在pom.xml中定义-Pprod能确保application-prod.yml被正确加载。而-Dspring.profiles.active是Spring Boot运行时参数在构建阶段无效。参数4Docker镜像Tag必须包含Git Commit ID便于故障追溯。在Jenkinsfile中def commitId sh(script: git rev-parse --short HEAD, returnStdout: true).trim() sh docker build -t registry.internal/vue-app:${commitId} .4.3 Jenkins Pipeline全流程代码实录以下是一个经过11个生产环境验证的完整Pipeline包含错误处理与人工确认点pipeline { agent any environment { DOCKER_REGISTRY 192.168.10.100:5000 APP_NAME vue-springboot-prod } stages { stage(Checkout) { steps { checkout scm } } stage(Build Vue) { steps { script { if (env.BRANCH_NAME develop) { sh npm ci --no-audit --no-fund npm run build:staging } else { sh npm ci --no-audit --no-fund npm run build:prod } } } } stage(Build Springboot) { steps { sh mvn clean compile -Dmaven.test.skiptrue -Pprod sh mvn package -Dmaven.test.skiptrue -Pprod } } stage(Test Integration) { steps { script { // 启动临时Mysql容器用于集成测试 sh docker run -d --name test-mysql -e MYSQL_ROOT_PASSWORDtest -p 3307:3306 mysql:5.7.42 sleep(10) // 执行Springboot集成测试 sh mvn verify -Dit.testIntegrationTest -Pprod sh docker rm -f test-mysql } } } stage(Build Docker Images) { steps { script { def vueCommit sh(script: git -C ./vue-app rev-parse --short HEAD, returnStdout: true).trim() def sbCommit sh(script: git -C ./springboot-app rev-parse --short HEAD, returnStdout: true).trim() sh cd vue-app docker build -t ${DOCKER_REGISTRY}/vue-app:${vueCommit} . sh cd springboot-app docker build -t ${DOCKER_REGISTRY}/springboot-app:${sbCommit} . } } } stage(Push to Registry) { steps { script { sh docker login -u admin -p Harbor2024 ${DOCKER_REGISTRY} sh docker push ${DOCKER_REGISTRY}/vue-app:${env.GIT_COMMIT} sh docker push ${DOCKER_REGISTRY}/springboot-app:${env.GIT_COMMIT} } } } stage(Deploy to Production) { steps { input message: Deploy to PRODUCTION environment?, ok: Yes, Deploy! script { // 滚动更新Vue Nginx容器 sh docker service update --image ${DOCKER_REGISTRY}/vue-app:${env.GIT_COMMIT} vue-frontend // 滚动更新Springboot容器 sh docker service update --image ${DOCKER_REGISTRY}/springboot-app:${env.GIT_COMMIT} springboot-backend } } } } post { success { echo Deployment successful! sh curl -X POST https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX -H Content-type: application/json --data {\text\:\Deployment succeeded for ${APP_NAME} on ${env.BRANCH_NAME}\} } failure { echo Deployment failed! sh curl -X POST https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX -H Content-type: application/json --data {\text\:\Deployment failed for ${APP_NAME} on ${env.BRANCH_NAME}\} } } }4.4 生产环境部署后的7项必检清单部署完成后必须执行7项检查缺一不可检查项检查命令合格标准故障表现1. Docker服务健康systemctl is-active dockeractiveinactive表示Docker daemon崩溃2. Mysql容器端口nc -zv 127.0.0.1 3306Connection succeededConnection refused表示端口未暴露3. Redis内存使用docker exec redis-prod redis-cli info memory | grep used_memory_human 400mb500mb触发OOM Killer4. Jenkins构建日志tail -n 20 /var/log/jenkins/jenkins.log最后一行含Finished: SUCCESS含OutOfMemoryError需调JVM参数5. Vue静态资源curl -I http://localhost:8080/static/js/app.jsHTTP/1.1 200 OK404表示Nginx root路径错误6. Springboot健康检查curl http://localhost:8081/actuator/health{status:UP}DOWN表示数据库连接失败7. Jenkins Agent连接docker exec jenkins-master jenkins-cli -s http://localhost:8080/ list-agents返回agent名称列表空输出表示Agent未注册实操心得第6项检查最易出错。Springboot的/actuator/health返回DOWN90%是因为application-prod.yml中数据库URL写成localhost:3306而容器内localhost指向自身不是宿主机。必须写成host.docker.internal:3306Docker Desktop或172.17.0.1:3306Linux Docker。5. 常见故障排查从日志定位到根因的完整路径5.1 Jenkins构建失败的3类日志分析法Jenkins构建失败时不要盲目重试按以下3类日志逐层分析第一层Jenkins Master日志/var/log/jenkins/jenkins.log关注ERROR级别日志重点看java.lang.OutOfMemoryError和java.net.ConnectException。出现OutOfMemoryError: Java heap space说明JVM堆内存不足需增大-Xmx参数。出现ConnectException: Connection refused检查Docker daemon是否运行systemctl status docker或Jenkins Agent是否在线docker ps \| grep jenkins-agent。第二层Jenkins Agent日志/var/log/jenkins/agent.log当Master日志显示Agent offline时登录Agent宿主机查看tail -f /var/log/jenkins/agent.log出现Failed to connect to master检查Agent配置的Jenkins URL是否正确防火墙是否放行8080端口。出现Permission denied (publickey)检查/var/lib/jenkins/.ssh/id_rsa权限是否为600且属主为jenkins用户。第三层Pipeline Console Output这是最直接的日志按时间倒序分析Maven构建失败看[ERROR] Failed to execute goal后的内容90%是Could not resolve dependencies需检查Maven settings.xml中的mirror配置。Docker构建失败看Step X/X : RUN ...失败的那一步常见command not found说明基础镜像缺少必要工具如alpine镜像需apk add curl。5.2 Docker容器启动失败的4步诊断法当docker run命令失败按以下4步诊断步骤1检查Docker守护进程状态systemctl status docker若显示active (running)继续若inactive执行journalctl -u docker -n 50查看启动失败原因。步骤2检查容器日志即使未启动docker logs container_name对刚创建未启动的容器此命令会输出Error response from daemon: ...直接定位问题。步骤3检查端口占用netstat -tuln \| grep :3306若显示LISTEN说明3306端口被其他进程占用需kill -9 pid或改用其他端口。步骤4检查SELinux上下文ls -Z /var/lib/docker/若显示unconfined_u:object_r:default_t:s0说明SELinux上下文错误。执行restorecon -R /var/lib/docker/5.3 Vue页面白屏的5个定位点Vue部署后页面白屏按以下5个点依次检查定位点1检查Nginx错误日志tail -f /var/log/nginx/error.log出现open() /usr/share/nginx/html/static/js/app.js failed (2: No such file or directory)说明npm run build生成的dist目录未正确COPY到Nginx容器。出现connect() failed (111: Connection refused) while connecting to upstream说明Nginx upstream配置指向了错误的Springboot服务地址。定位点2检查浏览器开发者工具Network标签页按F12打开刷新页面看哪些资源返回404index.html404Nginx root路径配置错误。app.js404Vue构建输出路径与Nginx location不匹配。api/login404Nginx反向代理配置缺失。定位点3检查Vue Router模式在浏览器Console中执行console.log(window.location.hash)若返回空字符串但页面仍白屏说明是history模式配置问题检查Nginx的try_files指令。定位点4检查Vue Devtools扩展安装Vue Devtools若无法检测到Vue实例说明vue.runtime.esm.js未正确加载检查index.html中script标签src路径。定位点5检查跨域配置若Console显示Access to fetch at http://localhost:8081/api/login from origin http://localhost:8080 has been blocked by CORS policy说明Springboot未配置CORS。在application-prod.yml中添加spring: web: cors: allowed-origins: [http://localhost:8080] allowed-methods: [GET, POST, PUT, DELETE]5.4 Springboot连接数据库失败的根因分析Springboot启动时报Cannot determine embedded database driver class for database type NONE按以下路径分析路径1检查application-prod.yml数据库URLspring: datasource: url: jdbc:mysql://host.docker.internal:3306/mydb?useSSLfalseserverTimezoneUTChost.docker.internal在Linux Docker中不可用必须改为宿主机IP如172.17.0.1。serverTimezoneUTC必须显式指定否则Centos7时区设置导致时间字段错乱。路径2检查Mysql容器网络模式docker inspect mysql-prod \| grep NetworkMode若显示NetworkMode: bridge则Springboot容器必须在同一Docker network中docker network create mynet docker run --network mynet --name springboot-app ... docker run --network mynet --name mysql-prod ...路径3检查Mysql用户权限进入Mysql容器docker exec -it mysql-prod mysql -uroot -p执行SELECT host FROM mysql.user WHERE Userroot;若返回localhost说明root用户只允许本地连接。创建远程用户CREATE USER springboot% IDENTIFIED BY Spring2024; GRANT ALL PRIVILEGES ON *.* TO springboot%; FLUSH PRIVILEGES;路径4检查Centos7防火墙iptables
返回列表