拓冰建站拓冰建站
首页 / 资讯中心 / 正文

从localhost到公网IP:云服务器部署实战指南

很多同学在本地把项目跑得特别顺手IDEA 一点就启动浏览器打开http://localhost:8080一切正常。可真到了需要把项目部署到公网给其他人访问时就会遇到一连串问题为什么局域网里别人能访问外网就不行为什么云服务器上 IP 已经填对了页面还是白屏为什么明明服务启动了输入服务器公网 IP 却连不上这篇文章要解决的就是这类问题中最基础但也最容易卡壳的一步把本地开发环境下的 localhost 或内网 IP替换成云服务器的公网 IP并完成公网部署。我会从一个真实项目的视角出发带你看清楚“本地能跑”和“公网能访问”之间到底差在哪几层然后手把手完成云服务器环境准备、项目打包、IP 替换、安全组配置、进程启动、访问验证和问题排查。如果你正准备第一次把自己写的 Spring Boot、Vue、Python 或任意 Web 项目放到公网云服务器上这篇文章就是为你准备的。1. 这篇文章真正要解决的问题先说一个很常见的现象本地开发一切正常但部署到云服务器后浏览器输入http://服务器公网IP:8080却始终打不开页面。如果只看表面你可能怀疑是代码写错了。但真正的原因往往在代码之外服务监听的还是localhost只在服务器本机生效外网根本进不来云厂商的安全组没有放行对应端口服务器系统防火墙拦截了请求前端页面里请求的 API 地址还是http://localhost:8080用户浏览器访问时会去请求用户自己的电脑数据库连接地址还指向本地云服务器上的程序连不上数据库。这些问题的共同点是在本地开发环境和公网生产环境之间存在一个“环境鸿沟”。本地依赖的是localhost而公网部署需要依赖云服务器公网 IP以及一系列配套的网络、端口、守护进程配置。这篇文章会带你打通这条链路。读完你应该能做到理解公网 IP、内网 IP、端口、安全组这些基础概念在云服务器上完成 Java / Python / Node 等运行环境的准备把自己本地项目正确打包并把前后端代码中的 localhost、内网地址替换成云服务器公网 IP配置云服务商安全组和服务器防火墙使公网 IP 可以访问到服务端口通过 curl、浏览器和日志来验证服务是否真正部署成功遇到“公网访问失败”时能按一套稳定顺序排查到底卡在哪一层。真正适合读这篇文章的读者不是已经熟练操作生产环境的运维工程师而是第一次接触服务器部署、即将交付项目或参加实训的开发者。这篇文章不追求覆盖 Kubernetes、微服务等复杂架构而是先把“本地项目上公网”这件事讲透。2. 公网 IP、云服务器与端口转发先分清这几个概念在动手之前有几个概念如果没弄清楚后面每一步都会踩坑。2.1 公网 IP 与内网 IP公网 IPPublic IP是互联网上唯一的、可路由的 IP 地址。任何一台连接到互联网的设备都可以通过公网 IP 找到对应的服务器。云服务器厂商分配给实例的公网 IP就是这种地址。内网 IPPrivate IP是在局域网内部使用的 IP 地址比如192.168.1.100、10.0.0.5。内网 IP 只能在当前局域网内使用外网设备无法直接通过它访问你。特别容易误解的一点你本地电脑上执行ipconfig看到的 IP像192.168.x.x那是路由器分配的内网 IP。别人从外网访问你不能通过这个地址。同理你自己云服务器上执行ip addr看到的172.x.x.x或10.x.x.x也可能是云厂商分配的内网 IP外网不一定直接能访问。所以在云服务器上部署时要分清云服务器的公网 IP用户浏览器访问的地址云服务器的内网 IP多台服务器之间互相通信时使用程序监听地址服务在服务器上绑定的 IP 和端口生产环境通常监听0.0.0.0表示接受所有网络接口的请求。2.2 localhost、127.0.0.1 与 0.0.0.0 的区别这是另一个高频混淆点。localhost或127.0.0.1表示“本机回环地址”程序只能被本机访问外部设备无法访问。0.0.0.0表示“本机所有可用网络接口”。程序监听这个地址时无论是内网网卡还是公网网卡发来的请求都能被接收。本地开发时Spring Boot 默认会把 Tomcat 监听在localhost这没问题。但部署到云服务器后如果仍然监听localhost外网怎么都连不进来。因此项目配置中通常需要把监听地址改为0.0.0.0或者明确配置成公网可访问的模式。2.3 云服务器与安全组云服务器只是一台运行着 Linux 或 Windows 的虚拟机它本身并不天然对公网开放所有端口。云厂商提供了一台“虚拟防火墙”叫安全组。安全组规则决定了哪些 IP、哪些端口可以访问这台服务器。很多新手部署失败的第一原因不是代码问题而是安全组没有放行端口。你需要在云厂商控制台找到安全组配置把应用要用的端口如 8080、80、3306 等加入放行规则。安全组和服务器内部的防火墙是两层两层都必须放行公网流量才能进来。2.4 端口与外网访问路径一个公网 IP 上可以运行很多服务通过不同端口区分。例如http://公网IP:80默认 Web 服务端口http://公网IP:8080常见 Java 应用端口http://公网IP:3000常见 Node.js 应用端口。外网访问的完整路径是用户浏览器 - DNS如果有域名 - 云服务器公网 IP:端口 - 安全组 - 防火墙 - 服务器程序监听端口任何一个环节断了访问都会失败。3. 环境准备购买云服务器并登录从本地开发切换到云服务器部署第一步是拥有一台公网可访问的云服务器。无论你选择阿里云、腾讯云、华为云还是其他厂商核心步骤是一致的。3.1 云服务器选型建议部署一个中小型 Web 项目不需要很高的配置。入门选择 2 核 4G 内存、40G 或更大云盘的 Linux 实例通常足够。操作系统上新手推荐 Ubuntu 22.04 或 CentOS Stream 9。Ubuntu 的软件源更新及时命令习惯和文档多CentOS 系列在传统企业环境中仍然常见。本文示例以 Ubuntu 为主CentOS 下的差异会特别说明。3.2 通过 SSH 登录云服务器Linux 服务器拿到公网 IP 后最常用的登录方式是 SSH。Windows 用户可以使用命令行的ssh命令或者使用 Xshell、FinalShell 等工具macOS / Linux 用户直接使用终端即可。ssh root你的云服务器公网IP其中root是登录用户名。如果你的服务器实例不是 root 用户就换成对应的用户名比如ubuntu公网IP。如果你在创建服务器时配置了密钥而不是密码SSH 登录命令是ssh -i 你的私钥文件.pem root你的云服务器公网IP登录成功后可以执行一个简单命令确认系统信息uname -a如果能看到 Linux 内核信息说明已经成功进入云服务器。3.3 更新系统软件源接下来更新系统的软件源保持服务器处于可安装软件的状态。Ubuntu / Debianapt update apt upgrade -yCentOS / Rockyyum update -y这一步不是必须每天做但新买的服务器建议先更新一次避免后续安装软件时出现依赖源过期问题。3.4 安装运行时环境根据项目类型安装不同的运行时。下面是几个常见场景Java 项目例如 Spring Bootapt install -y openjdk-17-jdk java -versionNode.js 项目curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt install -y nodejs node -v npm -vPython 项目apt install -y python3 python3-pip python3 --version数据库方面如果项目依赖 MySQL可以安装 MySQL 服务也可以选择使用云数据库。本地开发阶段最常见的做法是Ubuntu 安装 MySQLapt install -y mysql-server systemctl start mysql systemctl enable mysql这里需要特别提醒不要为了图方便给 MySQL 的 root 设置过弱的密码也不要让数据库端口对公网完全开放。数据库只应该允许应用服务器本机或指定内网 IP 访问最简单的方式是让数据库监听在127.0.0.1并且不要把它暴露到公网。4. 核心流程拆解从本地 IP 到公网 IP 的四个替换“部署到公网”本质上不是把代码复制过去那么简单而是要把项目中的每一处地址依赖都从“本地视角”切换到“公网视角”。根据经验最容易出错的是下面四处。4.1 服务监听地址替换本地启动 Spring Boot 时java -jar demo.jar默认行为是监听localhost外网无法访问。部署到云服务器后要让服务监听在0.0.0.0java -jar demo.jar --server.address0.0.0.0或者在application.yml中配置server: address: 0.0.0.0 port: 8080这样 Tomcat 会监听本机所有网络接口公网请求经过安全组和防火墙后可以到达该服务。对 Node.js / Express 项目app.listen(3000, 0.0.0.0, () { console.log(Server is running on port 3000); });4.2 前端 API 地址替换这是前端项目部署到公网后最常见的问题。本地开发时Vue 或 React 项目的.env.development里可能是VITE_API_BASE_URLhttp://localhost:8080在本地开发时没问题因为浏览器就在你的电脑上localhost指的就是你的电脑。但部署后用户浏览器访问的是云服务器上的静态页面。如果页面里的 API 地址还是localhost:8080用户点击登录时浏览器会去请求用户自己电脑的 8080 端口结果必然是失败。部署到云服务器时需要改成VITE_API_BASE_URLhttp://你的云服务器公网IP:8080或者如果后续配置了 Nginx 反向代理还可以使用相对路径VITE_API_BASE_URL/api替换后需要重新构建前端项目再把构建产物如dist目录上传到服务器。4.3 后端跨域配置替换如果前端和后端分开部署后端接口通常需要配置跨域。本地开发时你可能把允许的来源写成了Configuration public class CorsConfig { Bean public CorsWebFilter corsWebFilter() { CorsConfiguration config new CorsConfiguration(); config.addAllowedOrigin(http://localhost:5173); // ... } }部署后线上的前端访问地址变成了http://公网IP:80或域名localhost:5173就不应该再作为正式允许来源了。更稳妥的方式是把允许的来源做成配置项而不是写死在代码里Value(${app.cors.allowed-origin}) private String allowedOrigin;然后通过application.yml控制app: cors: allowed-origin: http://你的云服务器公网IP4.4 数据库连接地址替换本地开发时数据库地址通常写localhost:3306或127.0.0.1:3306这对应本地安装的 MySQL。部署到云服务器后如果数据库也安装在同一个服务器上localhost本身仍然可以工作但如果数据库在另一台云服务器上或者用的是云数据库连接地址就要改成对应的内网地址或公网地址。例如spring: datasource: url: jdbc:mysql://localhost:3306/demo_db?useUnicodetruecharacterEncodingutf8 username: demo_user password: 你的数据库密码如果数据库使用云数据库 RDS地址往往类似于rm-xxxx.mysql.rds.aliyuncs.com:3306就替换成云数据库提供的连接地址。这一步的坑在于很多人只改了前端 IP忘了数据库或 Redis 的地址服务启动时就在连接阶段报错。5. 完整示例把一个 Spring Boot Vue 项目部署到云服务器下面用一个典型的 Spring Boot 后端 Vue 前端项目演示完整的公网部署过程。你不需要完全照抄代码重点是理解每一步在做什么。5.1 本地项目结构假设本地项目结构如下project/ ├── backend/ # Spring Boot 项目 │ ├── src/ │ ├── pom.xml │ └── target/ └── frontend/ # Vue 3 项目 ├── src/ ├── .env.development ├── .env.production └── package.json5.2 修改后端监听地址与配置文件backend/src/main/resources/application.ymlserver: address: 0.0.0.0 port: 8080 spring: datasource: url: jdbc:mysql://127.0.0.1:3306/demo_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: demo_user password: ChangeMe_2025注意生产环境不要使用弱密码这里只是示例。然后打包后端项目。在本地开发机器上执行cd backend mvn clean package -Dmaven.test.skiptrue如果项目是 Gradlegradle clean bootJar打包完成后在target目录下会生成一个可执行的 jar 文件backend/target/demo-0.0.1-SNAPSHOT.jar5.3 修改前端 API 地址并重新构建文件frontend/.env.productionVITE_API_BASE_URLhttp://你的云服务器公网IP:8080然后构建 Vue 项目cd frontend npm install npm run build构建完成后在frontend/dist目录下生成静态文件。5.4 上传项目文件到云服务器把后端 jar 和前端 dist 目录上传到云服务器。可以使用scp命令也可以使用 WinSCP、FinalShell 等图形化工具。从本地 Mac / Linux 上传scp backend/target/demo-0.0.1-SNAPSHOT.jar root你的云服务器公网IP:/opt/app/ scp -r frontend/dist root你的云服务器公网IP:/opt/app/dist/建议先创建/opt/app目录mkdir -p /opt/app5.5 启动后端服务登录云服务器使用nohup启动后端nohup java -jar /opt/app/demo-0.0.1-SNAPSHOT.jar /opt/app/backend.log 21 启动后查看日志tail -f /opt/app/backend.log看到类似下面的日志说明后端启动成功Tomcat started on port 8080 (http) with context path Started DemoApplication in 5.3 seconds如果使用systemd管理服务更规范可以创建一个服务文件文件/etc/systemd/system/demo-backend.service[Unit] DescriptionDemo Backend Service Afternetwork.target [Service] Userroot WorkingDirectory/opt/app ExecStart/usr/bin/java -jar /opt/app/demo-0.0.1-SNAPSHOT.jar Restarton-failure RestartSec5 [Install] WantedBymulti-user.target启用并启动服务systemctl daemon-reload systemctl enable demo-backend systemctl start demo-backend systemctl status demo-backend使用 systemd 管理的好处是服务崩溃后会自动重启服务器启动后服务也会自动拉起。5.6 配置 Nginx 提供前端静态页面前端dist目录是一堆静态文件可以直接让 Nginx 提供服务也可以挂一个 Python 简易静态服务。但生产环境推荐 Nginx。安装 Nginxapt install -y nginx编辑 Nginx 配置把前端指向/opt/app/dist并把/api请求反向代理到后端8080端口。文件/etc/nginx/sites-available/demo.confserver { listen 80; server_name _; root /opt/app/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; } }启用配置并重启 Nginxln -s /etc/nginx/sites-available/demo.conf /etc/nginx/sites-enabled/ nginx -t systemctl reload nginx如果你使用了非 root 用户运行 Nginx需要确认 Nginx 用户对/opt/app/dist目录具有读取权限否则会返回 403。5.7 配置安全组放行端口这是最容易遗漏的一步。登录云厂商控制台找到云服务器实例的安全组配置添加入方向规则协议端口来源用途TCP800.0.0.0/0Nginx Web 服务TCP80800.0.0.0/0Spring Boot 后端服务TCP220.0.0.0/0SSH 登录建议改成特定 IP 或 IP 段TCP3306禁止公网放行MySQL 不对外暴露只允许本机或内网访问安全组规则需要谨慎不需要对外开放的端口一律不要放行尤其是数据库和 Redis 这类敏感服务。5.8 配置服务器内部防火墙如果云服务器系统启用了ufw防火墙需要同步放行端口。Ubuntuufw allow 22/tcp ufw allow 80/tcp ufw allow 8080/tcp ufw enableCentOS 自带 firewalldfirewall-cmd --permanent --add-port22/tcp firewall-cmd --permanent --add-port80/tcp firewall-cmd --permanent --add-port8080/tcp firewall-cmd --reload如果你在安全组层面已经放行但服务器内部防火墙没有放行请求同样无法到达服务。两者需要配合。6. 运行结果与效果验证部署结束后不要急着把链接发出去按下面顺序验证。6.1 在服务器本机验证服务先在云服务器上执行以下命令确认程序本身正常curl http://127.0.0.1:8080/api/health如果接口正常返回了 JSON 数据说明程序没问题。再验证 Nginxcurl http://127.0.0.1:80如果返回的是前端index.html内容说明 Nginx 配置正确。6.2 从本地电脑验证公网访问在本地电脑打开浏览器访问http://你的云服务器公网IP/index.html或直接访问http://你的云服务器公网IP/如果 Nginx 配置了try_files回退到index.html通常会显示前端页面。接着验证后端接口http://你的云服务器公网IP:8080/api/health如果返回 JSON说明公网链路全部通畅。6.3 通过日志判断问题层级部署出现问题后不要盲目重启服务。按下面的日志顺序排查查看后端日志backend.log或journalctl -u demo-backend查看 Nginx 错误日志/var/log/nginx/error.log查看 Nginx 访问日志/var/log/nginx/access.log确认请求是否到达 Nginx。如果 Nginx 访问日志里有请求记录说明网络链路没问题问题在应用层如果访问日志里根本没有请求那么问题在安全组、防火墙或浏览器访问地址。6.4 一个完整的验证命令序列# 1. 查看后端进程是否存活 ps -ef | grep java # 2. 查看端口监听状态 netstat -tlnp | grep 8080 # 3. 本地请求后端 curl http://127.0.0.1:8080/api/health # 4. 从公网 IP 请求后端 curl http://你的云服务器公网IP:8080/api/health # 5. 查看 Nginx 配置语法 nginx -tnetstat -tlnp输出中如果看到tcp6 0 0 :::8080 :::* LISTEN 12345/java说明 8080 端口正在监听所有接口。如果只看到127.0.0.1:8080说明程序只监听了本机回环地址外网请求进不来需要检查server.address配置。7. 常见问题与排查思路下面整理一套高频故障清单每一类都是实际部署中常见的“公网访问失败”原因。问题现象可能原因排查方式解决方案公网 IP 无法访问页面超时云安全组未放行端口检查云厂商控制台安全组规则添加对应端口的入方向放行规则公网 IP 无法访问但服务器本机可以访问服务器防火墙拦截查看 ufw / firewalld 状态放行应用端口服务启动正常但 curl 127.0.0.1 都不通应用端口被占或启动失败查看应用日志检查端口占用和应用异常页面能打开但接口请求失败前端 API 地址还是 localhost打开浏览器 F12 查看请求地址把前端的 API Base URL 改为公网 IP 或相对路径接口请求提示跨域后端跨域配置没有覆盖公网地址查看浏览器控制台 CORS 报错更新后端允许来源或使用 Nginx 反向代理同源访问数据库连接失败数据库地址或账号密码不对查看后端日志中的 SQL 异常修改数据库连接地址和账号信息访问出现 403 ForbiddenNginx 用户没有目录读取权限查看 Nginx 错误日志调整 dist 目录权限访问出现 404 Not FoundNginx root 路径不对或 try_files 缺失查看 Nginx 配置文件修正 root 路径或添加 try_files 规则重启服务器后服务消失使用了 nohup 直接启动没有守护查看进程是否存在改用 systemd 服务托管7.1 排查顺序建议当你遇到“公网访问不了”按下面顺序逐层排查不要一上来就改代码确认浏览器访问的 IP 和端口是否正确确认服务器本机通过curl能访问到服务确认安全组已放行端口确认服务器防火墙已放行端口确认程序监听的是0.0.0.0不是127.0.0.1如果页面能打开但接口有问题检查浏览器开发者工具 Network 面板里的请求地址查看后端日志确认是否收到请求。这套顺序基本能定位 95% 的首次部署问题。8. 最佳实践与工程建议当部署从“跑通”进入“维护”阶段时就要开始考虑规范化了。下面这些建议来自实际项目中反复踩过的教训。8.1 不要把 IP 写死在代码里最忌讳的做法是在前端代码、后端配置文件里直接写死一个公网 IP导致换一台服务器就要全局搜索替换。更稳的做法是前端使用环境变量区分开发、测试、生产环境后端配置通过 Spring Boot 的application-dev.yml、application-prod.yml区分如果前后端通过 Nginx 同源部署前端优先使用相对路径/api这样即使换 IP 或加域名前端也不用重新构建。8.2 使用域名而不是裸 IP公网 IP 只有在开发和测试阶段临时使用合适。正式上线强烈建议绑定域名。原因很简单用户容易记忆换服务器时可以平滑迁移只需要改 DNS 记录申请 HTTPS 证书时域名证书更方便后续如果要接入 CDN、对象存储、短信回调等域名是基本门槛。把域名解析到公网 IP 后Nginx 的server_name改成域名访问方式就变成http://demo.example.com。8.3 生产环境必须使用 HTTPS一旦使用域名对外提供服务建议尽早接入 HTTPS。Lets Encrypt 的免费证书可以满足绝大多数场景。使用 certbot 签发证书apt install -y certbot python3-certbot-nginx certbot --nginx -d demo.example.com证书自动续期certbot renewHTTPS 不只是“加分项”对登录类项目来说明文传输的密码和 Token 在公网上非常危险。8.4 数据库和中间件不要暴露到公网很多时候部署失败后开发者为图方便就把 MySQL 的 3306 端口放到安全组里公网放行。这是极其危险的行为。数据库应该只监听内网或本机同机部署时数据库连接地址写127.0.0.1不同服务器部署时使用内网 IP 通信云数据库通过 VPC 内网地址连接安全组中不要对0.0.0.0/0开放 3306、6379 等端口。如果确实需要远程管理数据库可以通过 SSH 隧道访问而不是直接暴露端口。8.5 使用 systemd 值守服务前文已经演示过 systemd 的配置方式。这里再强调一次不要依赖nohup java -jar 这种方式长期跑生产服务。服务器重启、进程崩溃、日志轮转这些场景下 nohup 方式都会带来额外麻烦。systemd 可以自动重启服务并且可以通过journalctl -u demo-backend查看日志维护体验好很多。8.6 部署前备份与回滚意识虽然这篇文章讲的是初次部署但建议从第一次部署就养成备份和回滚的意识后端 jar 包按版本命名保留上一个可用版本前端 dist 目录在发布新包前先备份修改 Nginx 配置前先执行nginx -t数据库变更前做好 dump 备份尤其是生产数据。mysqldump -u root -p demo_db /data/backup/demo_db_20250101.sql8.7 日志管理与监控服务跑起来后日志会持续增长。如果使用 systemd 管理可以通过 logrotate 做轮转。同时要把日志按级别分清楚应用日志、访问日志、错误日志分开存放方便排查。一个简单的 logrotate 配置示例文件/etc/logrotate.d/demo-backend/opt/app/*.log { daily rotate 7 compress missingok notifempty copytruncate }8.8 安全基线公网部署意味着服务器暴露在不可信网络中。下面的安全习惯越早养成越好禁止 root 密码直接登录改用密钥登录SSH 端口不要常识性暴露给所有 IP如条件允许改为密钥 特定 IP 白名单定期更新系统补丁应用账号使用独立用户运行不给过于宽泛的权限环境变量中的数据库密码、Secret Key 不要提交到代码仓库。9. 总结与后续学习方向这篇文章的关键点可以浓缩成一句话本地能跑和公网能访问之间差的不只是地址而是一条完整的网络链路。程序监听地址、安全组、防火墙、前端 API 地址、数据库连接地址、反向代理配置这五六个环节里任何一环没有对齐公网访问就会失败。如果你现在手头正好有项目要部署建议按这个顺序动手做一遍先把后端 jar 包放到云服务器上用curl 127.0.0.1:8080验证程序可以运行再把安全组和防火墙放行 8080 端口从本地浏览器访问http://公网IP:8080接着部署前端静态文件用 Nginx 提供服务然后把前端 API 地址改为公网环境验证页面上的登录、查询功能最后再考虑域名、HTTPS、systemd 托管和日志轮转这些规范化事项。部署到公网只是第一步。接下来值得深入的方向包括Nginx 的反向代理、负载均衡、静态缓存配置systemd 服务管理与自动化发布脚本Docker 容器化部署让环境一致性不再成为问题CI/CD 流水线代码提交后自动构建并发布到服务器HTTPS 证书管理和浏览器安全策略服务器监控与日志告警。如果你第一次部署时在某一步卡了很久这是很正常的。公网部署涉及的知识点横跨网络、操作系统、应用服务和前端构建每个环节都有自己隐藏的默认值。建议把这篇文章里“部署到公网”的排查顺序收藏下来下次遇到问题直接照单检查。先用最小改动跑通链路再逐步优化架构是个人开发者学习部署最务实的路线。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门