ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

前后端项目部署公网:外网IP替换与安全组排查完整指南

前后端项目部署公网:外网IP替换与安全组排查完整指南 把一个前后端项目部署到公网最容易出问题的地方不是云服务器怎么选也不是 Nginx 怎么写而是“外网 IP 替换”没有替换干净。很多人本地访问 localhost 一切正常代码传到云服务器后页面能打开接口却全部报错或者服务明明启动了别人却访问不到。这篇文章就围绕从本地联调切换到云服务器公网访问的完整过程把外网 IP 替换、安全组放行、启动验证和常见排查顺序整理清楚。如果你正在做课程实验的“部署到公网”这一步或者准备把个人项目放到云服务器上这篇文章可以按顺序照做。最值得先记住的一句话是部署到公网不等于把 localhost 改成外网 IP 那么简单但也没有想象中复杂关键是把“对外访问地址”和“内部通信地址”分开理解。1. 部署到公网之前先搞清楚替换外网 IP 要替换哪些地方1.1 本地联调和公网访问的最大区别本地开发时前端页面运行在你自己电脑后端服务也运行在你自己电脑浏览器访问 http://localhost:8080 时localhost 指的就是本机。也就是说浏览器发出的 API 请求最终也被发回本机。部署到云服务器之后前端页面被浏览器加载后API 请求是浏览器直接发出去的。如果前端代码里还写着 localhost:8080浏览器会把它解析成每一台访问者的电脑而不是你的云服务器。所以页面能打开接口却全部 404 或连接失败这是最常见的部署失败现象。反过来看后端服务后端程序在云服务器上监听端口时并不一定需要监听外网 IP。Java 服务默认监听的 0.0.0.0 表示“所有网卡”外网访问这个公网 IP 时流量会进入本机。只要启动命令和配置没有强制绑定某个内网地址服务本身就可以被访问到。很多教程把“监听 0.0.0.0”和“配置成外网 IP”混在一起讲容易让人误解成必须把 server.address 写成外网 IP。1.2 需要替换成外网 IP 的常见位置如果项目是典型的前后端分离架构部署到公网时需要检查以下几类地址前端页面里的接口基础地址一般叫 baseURL、VITE_API_BASE_URL、REACT_APP_API_URL。后端的数据库连接地址、Redis 地址、消息队列地址。文件上传下载后拼接的访问地址。微信支付、回调、WebSocket、SSE 等需要公网回调的地址。跨域配置里允许访问的来源地址。这里要说明的是外网 IP 并不等于所有需要替换的地址都写成外网 IP。数据库如果和业务在同一个云服务器上推荐继续使用 127.0.0.1 或 localhost。这样请求不经过公网安全性更高速度也更快。只有那些必须被外部访问和必须由外部发起回调的地址才需要替换为云服务器的外网 IP。替换的次序也有讲究。先改后端配置再改前端配置最后改中间件和回调地址比想起来哪里改哪里更不容易漏。实际项目中经常出现后端连不上数据库或者前端打包后发到服务器首页能开但登录接口失败最后查下来都是因为某个 IP 没替换干净。2. 云服务器环境准备系统、运行环境和目录规划2.1 云服务器的系统选择和登录准备云服务器首先需要确认两件事系统版本和登录方式。对于大多数个人项目和课程实验来说选择 Linux 系统就够用了。常见的有 Ubuntu、Debian、CentOS以及部分云平台提供的 OpenCloudOS、Aliyun Linux、TencentOS 等。选择系统时不要只看发行版名字要看版本维护周期和软件源是否可用。较老的系统版本容易出现依赖源失效重新装软件时会浪费时间。登录云服务器一般有两种方式密码和密钥。课程实验阶段用密码登录更方便个人项目长期使用建议改成密钥登录。通过 SSH 客户端登录后先执行更新命令把系统基础软件包更新到当前源的最新状态。更新和安装业务依赖时需要确认当前登录用户是否有 sudo 权限。这一步看着基础实际很容易耽误时间。很多部署失败并不是代码问题而是登录用户权限不足安装 Nginx 时提示 permission denied或者解压文件后没有写入权限。不要一上来就用 root 操作也不要一直用普通用户跑服务先明确用户和目录权限再开始。2.2 按项目类型安装运行环境具体需要安装什么取决于项目结构。以后端 Java 前端 Vue 为例至少需要 JDK、Nginx、MySQL、Redis以及用来打包前端的 Node.js。如果项目是 Python 的 FastAPI 或 Django则安装 Python 和依赖如果项目使用 Docker 部署那就需要提前装 Docker 和 Docker Compose。先用一条命令检查 JDK 是否已安装再检查 Node.js 和 Nginx。尽量不要凭记忆跳过环境检测直接启动服务否则会看到一连串“command not found”或者类找不到错误。安装顺序建议为先系统基础软件再数据库和缓存最后才是项目运行环境。原因是数据库启动慢服务如果先启动后面连接数据库时容易出现启动失败排查时难以区分到底是服务问题还是数据库问题。对于使用宝塔面板这类图形化工具的用户界面确实能减少很多输入命令的时间但底层依然是安装软件、修改配置、放行端口这套逻辑。用面板时更要注意外网 IP 替换和端口安全组是否同时放行不然面板里显示服务启动了外面依然访问不了。2.3 提前规划部署目录和日志目录这一步经常被忽略。我一般会建议在云服务器上建一个独立的应用目录例如 /opt/app下面按模块分成 backend、frontend、logs、backup。这样做的原因有两个前后端和日志分离定位问题方便。后端日志写在 /opt/app/logs 下输出文件固定排查时直接查看不用满服务器找文件。升级和回滚方便。备份时直接打包对应目录不会把系统文件混进去。如果项目以后要部署多个实例或微服务目录规划的价值更大。没有规划的服务器三个月后可能连自己都不清楚哪个进程对应哪个项目只能靠进程 ID 和端口去猜。规划不需要一开始特别复杂只要做到“一个项目一个目录、日志有固定位置、备份有独立空间”即可。3. 云服务器替换为外网 IP 的实操顺序3.1 后端配置监听地址、数据库连接和回调地址后端配置重点不是把所有 IP 都改成外网 IP而是区分服务监听地址和外部访问地址。先看监听地址。Spring Boot 默认启动后监听 0.0.0.0如果配置文件里有 server.address127.0.0.1那就只会监听本机回环地址外网流量到达服务器后无法进入服务表现就是本地 curl 正常但是通过公网 IP 访问超时或者拒绝连接。要检查的是这一项而不是把 server.address 改成公网 IP。再看数据库连接。假设 MySQL 和业务部署在同一台云服务器上连接地址写 127.0.0.1 是正确的不需要改成外网 IP。如果数据库在云数据库服务上要使用云厂商提供的内网连接地址而不是公网连接地址。公网地址往往需要额外开通延迟更高而且暴露数据库端口会带来明显安全风险。最后看回调地址。项目里有上传文件回显、第三方支付回调、短信回调等场景时请求可能是由外部系统发起的这时候如果不能通过公网访问到你的服务器业务就完成不了。回调地址一般要和域名或公网 IP 绑定不能用 localhost。注意如果项目还没有域名先用 http://外网IP:端口 验证域名级联排查放到后面。3.2 前端配置接口地址和重新构建前端项目的接口地址通常写在环境变量文件中。Vue 项目常见的是 .env.production 里的 VITE_API_BASE_URLReact 项目可能是 REACT_APP_API_URL。如果直接在前端代码里写死了 axios 的 baseURL也要一并修改。注意一个关键点前端代码修改后必须重新构建再把构建产物上传到服务器。因为像 Vite、Webpack 这类构建工具在打包时会把环境变量替换进产物里。只改源码不重新构建部署到服务器上仍然是旧地址。构建产物上传后还需要用浏览器开发者工具再确认一次。打开网络标签页看接口请求的真实地址是 http://云服务器外网IP:端口 还是旧的 localhost。这一步是最直观的对比方式比看配置更准确。常见错误是开发环境变量改好了但打包时用了生产变量以外的配置导致 baseURL 仍是空值或相对路径。如果使用 Nginx 代理前端配置里也可以把 API 地址写成 /api然后由 Nginx 反向代理到后端的 8080 端口。这样浏览器只访问同一个域名或 IP不需要暴露后端端口也能减少跨域问题。不过这个方案要求 Nginx 转发配置正确否则会出现页面能打开但接口 502 的情况。3.3 缓存、对象存储和跨域白名单实际项目不止有数据库还有 Redis、对象存储、文件服务等中间件。Redis 通常只给后端服务使用不需要对外开放连接地址保持内网或本机即可。对象存储的 endpoint 要区分外网 bucket 地址和内网地址云厂商提供的访问域名可能不同使用外网 endpoint 时还要确认访问权限、流量费用和防盗链规则。跨域配置是另一个高频问题。本地联调时前端 localhost:5173 访问后端 localhost:8080需要在后端配置跨域白名单。部署到公网后前端变成了 http://云服务器外网IP 或 http://域名跨域白名单必须包含这个新来源地址。否则浏览器控制台会出现 CORS 错误服务端日志里可能看不到任何请求记录因为请求在浏览器侧就被拦截了。跨域白名单要写具体来源不要因为图省事就配成 *。原因很简单开放所有来源意味着任何一个网页都能向你的后端发请求容易带来恶意调用和网络请求消耗。个人项目可以先用指定 IP 或域名后续需要多端访问时再改成动态白名单。4. 上传、构建和启动从能访问到不会掉线4.1 上传代码并构建后端代码上传可以使用 Git 拉取也可以使用 SCP、FTP 或宝塔面板上传压缩包。个人课程实验阶段用 Git 在服务器上 clone 项目然后按分支切换版本会比较方便。文件夹上传和压缩包上传容易遇到权限和编码问题解压后文件权限不对启动时会提示“Permission denied”。后端如果是 Java 项目一般有两种做法在本地打包成 jar 后上传或者在服务器上直接执行构建命令。如果服务器装好 JDK 和 Maven可以直接在服务器上构建。如果只是为了课程实验建议先在本地执行打包把 jar 传到服务器减少服务器上的依赖安装。但无论哪种方式必须保证上传后的配置文件是你改过的生产配置。很多人忽略了这一点上传 jar 之后又在服务器上解压修改配置最后配置没有真正生效。启动后端时先用前台方式跑一次确认没有报错再杀掉进程改用后台启动。直接 nohup 后台启动如果代码有问题日志会被掩盖肉眼很难判断是启动失败还是端口没监听。cd /opt/app/backend nohup java -jar myapp.jar --spring.profiles.activeprod /opt/app/logs/app.log 21 上面是示例命令myapp.jar、profile 名称和日志路径要按你的项目实际情况替换。4.2 前端构建产物和 Nginx 静态目录前端项目执行构建命令后会生成一个 dist 目录里面是静态文件。把 dist 目录放到云服务器的前端目录例如 /opt/app/frontend/dist。Nginx 配置里 root 指向这个路径index 指向 index.html。Nginx 配置常见做法是只写一个 server 块同时完成两件事把 / 指向前端目录把 /api 反向代理到后端端口。下面是示例思路具体路径和端口以你自己的项目为准server { listen 80; server_name 你的外网IP或域名; root /opt/app/frontend/dist; index index.html; location / { try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }try_files 这行很重要它能让 Vue 的 history 路由在刷新页面时回退到 index.html否则页面一刷新就 404。proxy_pass 转发到 127.0.0.1 是内部通信不需要写外网 IP。写完配置后用 nginx -t 检查语法再重载服务。4.3 用 systemd 守护后端进程直接使用 nohup 启动的后端进程在服务器重启或进程意外退出后不会自动恢复。个人项目可能还能接受但如果想让服务保持在线建议用 systemd 管理进程。创建一个 service 文件例如 /etc/systemd/system/myapp.service内容类似下面这样[Unit] DescriptionMy App Service Afternetwork.target mysql.service redis.service [Service] Useryouruser WorkingDirectory/opt/app/backend ExecStart/usr/bin/java -jar /opt/app/backend/myapp.jar Restarton-failure RestartSec5 StandardOutputappend:/opt/app/logs/app.log StandardErrorappend:/opt/app/logs/error.log [Install] WantedBymulti-user.target配置后执行 systemctl daemon-reloadsystemctl enable myapp 设置开机自启systemctl start myapp 启动服务。之后查看状态用 systemctl status myapp查看日志可以用 journalctl -u myapp -f。不建议在 ExecStart 里直接写成 java -jar myapp.jar 而不写绝对路径因为 systemd 的 WorkingDirectory 不一定能保证所有命令都找到文件和依赖。路径写全日志路径固定排查时会省很多时间。5. 公网访问验证和安全组排查5.1 按顺序验证服务是否真的对外可用部署完成后不要直接问“为什么访问不了”要按顺序做验证。下面是我个人常用的验证顺序在云服务器内部执行 curl http://127.0.0.1:8080确认后端进程已经监听端口。在云服务器内部执行 curl http://外网IP:8080确认服务对外网入口有响应。在本地浏览器访问 http://外网IP:端口 或 http://外网IP 的静态页面。打开浏览器开发者工具查看页面和接口请求是否正常。如果接口请求失败复制请求地址在浏览器直接打开看返回结果。第 1 步通过但第 2 步失败大概率是安全组或系统防火墙没有放行端口。第 2 步通过但第 3 步失败需要检查云安全组、本机浏览器代理、服务器上 80/443 端口占用情况。第 3 步通过但第 4 步接口失败优先检查前端 baseURL 和后端跨域配置。注意如果在服务器本机用 curl 127.0.0.1 能通但 curl 外网IP 不通先不要怀疑代码优先检查云控制台的入方向规则和服务器防火墙。5.2 访问不通时的标准排查链路用表格整理一下最常碰到的情况现象可能原因处理方式公网 IP 完全打不开云安全组未放行端口登录云控制台添加入方向规则页面打不开但服务器本地能访问系统防火墙拦截检查 ufw/firewalld 状态并把端口加入白名单连接被拒绝服务没启动或监听地址错误检查进程和 server.address 配置页面打开但接口 502Nginx 代理地址错误确认 proxy_pass 指向的后端端口页面打开但接口 404前端接口路径和后端路由不一致检查请求地址、网关前缀页面打开但接口跨域报错CORS 白名单没包含来源地址修改后端跨域配置后重启刷新页面后 404前端 history 路由未配置 try_files检查 Nginx 的 try_files 配置安全组是云控制台里的一个独立开关系统防火墙是服务器操作系统的另一个开关。两个都要开放才能访问到服务。在云控制台添加入方向规则时需要把端口、协议、来源 IP 写清楚。个人项目可以先放行 80、443 和业务端口但不要为了省事把 0.0.0.0/0 对所有端口全部放行。如果服务访问很慢不要直接怀疑带宽问题。先看服务器 CPU、内存和硬盘使用率再看后端日志有没有大量报错。很多“访问慢”其实是数据库连接池连接失败后反复重试或者磁盘日志文件满了导致写入阻塞。6. 部署到公网后的边界问题和新手常见误区6.1 不是所有地方都该写外网 IP部署到公网后最容易走极端的是两个方向。一个方向是只把 localhost 改成外网 IP其他都不管另一个方向是看到 IP 就改成外网 IP连数据库地址也改成公网地址。两种都有问题。数据库和 Redis 这类内部中间件部署在同一台服务器时用 127.0.0.1 是合理的。把它们改成外网 IP不仅会有额外网络延迟而且把本不该对外的端口暴露到了公网。云服务商一般会提供内网地址如果业务和数据库都在同一区域优先用内网地址。判断标准很简单这个地址是否需要被外部客户端直接访问。浏览器、外部系统、手机 APP 需要访问的地址用公网 IP 或域名后端服务之间互相调用的地址用内网或回环地址。判断某个地址是否该用外网 IP只需要问一句这个请求是浏览器或外部系统发起的还是服务器内部发起的前者用公网地址后者用内网或回环地址。6.2 先 IP 访问稳定后再绑定域名和 HTTPS课程实验或个人项目部署不一定要第一时间绑定域名。先用 http://外网IP 验证功能能跑通再考虑域名。原因是域名解析、HTTPS 证书、备案等流程会牵扯很多额外问题如果业务本身还没稳定先上域名会增加排查难度。稳定之后绑定域名建议同时配置 HTTPS。不要只把端口改成 443 就结束证书申请和续期需要额外处理。常见的证书类型有免费的单域名证书和通配符证书具体怎么选取决于你使用的域名和云服务商。证书配置好后后端回调地址、前端 baseURL、WebSocket 地址要同步更新成 https 或 wss否则页面打开是安全的接口却在给 http 地址发请求。6.3 部署成功不等于适合长期运行服务能在公网访问只是第一步。如果项目要长期使用还需要把几件事补上日志轮转避免日志文件无限增长占满磁盘。数据库备份建议至少每天备份一次并保留最近几天的备份。进程守护用 systemd 或 Docker Restart 策略保证重启恢复。安全更新定期更新系统软件包和项目依赖。如果是微服务项目可以考虑再加一层 Docker Compose 或容器编排。容器部署的好处是环境一致、启停方便但需要额外学习成本。如果你只是做课程实验用 systemd 和 Nginx 已经足够不必一上来就上 K8s。从“本地能跑”到“公网能访问”核心问题从来不是某个工具多复杂而是配置替换是否彻底、端口放行是否完整、日志排查是否有序。按上面的流程走一遍单条链路能访问再优化细节会稳很多。个人经验是先别急着开最大并发、别急着配 HTTPS、别急着换域名先把 IP 访问链路跑通了后续优化就有了扎实的底子。
返回列表