新闻详情

新闻详情

首页 / 资讯中心 / 详情

零到全栈(第一次上线:把全栈应用搬上服务器)

发布时间:2026/10/1 16:04:36来源:尧图网络
零到全栈(第一次上线:把全栈应用搬上服务器)
先上线最朴素的部署方案现在把整套全栈应用发布到互联网——配置、环境、服务器操作用最朴素的办法一次跑通清点行囊此刻的项目由三样东西组成静态前端——基于 React 和 Next.js 开发可以构建为静态前端代码FastAPI 后端——基于 Python 和 FastAPI 开发通过 Uvicorn 提供服务SQLite——对应硬盘上的一个 .db 文件距离上一次把项目发上服务器已经过去很长一段路现在用浏览器访问服务器的 IP 还能看到它但那仅仅是一个静态前端网站后端 API、数据库、会话都已经做了只不过全在本地开发、本地运行开发后端的同时前端也跟着动了——加了 fetch 去请求后端添了历史记录列表和会话所以全栈部署要前后端一起做前端只需推送代码、重新构建后端则要从零部署——这就是现在的起点另外上线并不是终点光发到服务器还不够后续的迭代、维护以及运营、安全和用户体验都值得分开细聊这条路的走法是——先用最朴素的办法把整套跑通上线再换成更易维护的部署方式并通过反向代理让前后端同源然后接上域名与 HTTPS接着通过日志与统计数据观察用户行为最后是调优、安全与一键发布部署是什么部署 说到底是一句话把自己电脑上能跑的东西在另一台机器上尤其是服务器跑起来线上部署、上线说的都是同一件事项目虽有前端、后端、数据库三部分但 SQLite 基本就是后端的一部分——它的安装、创建、使用都基于 Python 的能力所以要部署的就是前端和后端朴素的部署方案本地运行时前端通过 npm run dev 监听 3000 端口后端通过 fastapi dev 监听 8000 端口背后是 Uvicorn我们用浏览器访问 3000 拿页面页面里的 js 脚本再通过 fetch 访问 8000 的后端程序实现交互服务器也只是一台电脑可以用一种朴素的方式想部署方案前端监听服务器的一个端口后端监听另一个端口用户通过浏览器获取前端页面页面中的 js 脚本再通过 fetch 访问后端只不过前端不需要监听 3000 了——讲前端时一直是 Nginx 监听 80 端口并转发前端资源本地用 3000 只是为了方便开发的权宜之计所以在这个方案里前端仍然通过 Nginx 来代理通过 80 端口给到用户后端则与本地运行一样通过 Uvicorn 的能力在 8000 端口提供服务按这种朴素的方案许多事情对我们来说并不是一个全新的领域——但也有一些要了解的新知识点我们已经知道的前端部署流程把代码推到服务器、构建为静态前端代码、交给 Nginx——部署前端时已经轻车熟路照做即可只有一处要留心给前端加的配置文件.env.local并没有被 git 追踪等下要处理先记着这笔账Python 环境后端运行的基础Ubuntu 自带 Python想要其他版本也可以很轻松地安装.venv 和依赖fastapi、uvicorn、pypinyin、snownlp 这些依赖用 .venv 管理requirements.txt 加 pip install 就能把依赖装回来——venv 也是 Python 官方自带的能力代码和数据库项目代码完备——main.py、storage.py代码运行时会自动创建history.db把代码拉到服务器和前端是同一套动作背后是 git 和 GitHub数据库用的是 SQLite后端运行时会自动创建——换 MySQL 或 PostgreSQL 这样的数据库部署时才会有些麻烦启动后端服务需要 Uvicorn 监听一个端口提供 API 服务——本地一直是用fastapi dev调用它默认监听 8000 端口会撞上的五个挑战服务器部署与本地运行毕竟差异显著只凭已经知道的这些去部署还会遇到五件事挑战一缺失前端配置文件——.env.local不进 git把代码 pull 到服务器之后服务器上没有任何前端配置而且服务器上要的也不是.env.local这个名字——.local的意思就是 本机私有是给自己开发用的线上构建要的是另一个名字总之前端的配置得在服务器上手动建一份不然构建出来的前端不知道该去哪儿找后端——这是配置文件的问题挑战二后端配置不匹配——后端main.py里的 CORS 中间件有这样一行allow_origins[http://localhost:3000],这行代码在线上运行时必定出问题localhost 的意思就是本地而项目部署之后要靠用户通过互联网访问——它会 水土不服讲道理这种内容就不应该写在代码里它应该写进单独的配置文件——和上一条一样也属于配置文件问题挑战三fastapi dev 只支持本地访问——本地用fastapi dev启用 Uvicorn 没问题但它只接收本地的访问也就是发请求的电脑和运行程序的电脑是同一台按现在的部署逻辑用户要在自己的电脑上通过 js 向服务器的 8000 端口发请求这个方案行不通好在文档有说明面向公网提供服务要用fastapi run命令——用这个命令运行时Uvicorn 就不止能处理来自本地的请求了挑战四终端窗口不敢关闭——本地运行时前后端各占一个终端窗口窗口一关服务就停部署之后前端可以不再依赖终端静态页面由 Nginx 提供服务后端却很尴尬终端要一直开着一旦关闭后端服务就停了挑战五防火墙——服务器在云平台上前端和后端目前分别通过 80 和 8000 端口监听请求80 已经开放部署前端时确认过但云平台的安全组 / 防火墙默认不开 8000需要手动放行把五条归拢一下其实是四件事处理配置文件挑战一、二——这件得在本地办上服务器之前就要办完换成 fastapi run挑战三——一条命令的事开通防火墙挑战五——去云平台控制台点一下让后端在后台常驻挑战四——等前面都跑通了最后办配置文件先办第一件挑战一和挑战二两条一个在前端、一个在后端其实是同一类问题——都是 某个值不该写死它得随着机器变而且都得在本地办完再推上去所以放在上服务器之前什么是配置同一份代码跑在自己电脑上和跑在服务器上有些东西就是会不一样——比如前后端地址不同服务器的 IP 不同地址自然不同除此之外还有一些信息值得放进配置前后端地址数据库地址和连接配置包括密码第三方服务密钥例如大模型 API key服务监听哪个端口日志写到哪儿、要不要开调试模式这些可以写在同一个配置文件中用类似这样的格式名称axxx名称b123保存为一个文件代码就可以从中读取到运行所需的参数——这个文件就叫配置文件这些东西不属于代码代码回答的是 怎么做配置回答的是 这一次对着谁做代码和配置相互配合——同一份代码配上不同的配置就能服务不同的环境我们项目里有两处和地址相关的配置一处是前端的.env.local# 前端根目录.env.localNEXT_PUBLIC_API_BASE_URLhttp://localhost:8000它写了后端的访问地址并赋给常量NEXT_PUBLIC_API_BASE_URL前端请求后端时顺着这个常量找到地址另一处在后端就是前面提到的那行allow_origins[http://localhost:3000], # 之前加的它本不应该写死在代码里而应该也抽取为一个配置文件——之前就说过 后端这类配置留到部署时一起处理现在就是那个时候配置文件的命名与读取命名的规矩比较松散基本上会叫 .env但有时也可能不这么叫——取决于框架认不认它目前项目里唯一的配置文件是前端的.env.local为什么叫.env.local而不是.env其实 Next.js 两个都认但后缀在传递不同的意思.local表示本机私有即别人机器上没有也别提交同时它还认这几种写法.env.development.local.env.development.env.production.production 表示生产环境构建时才用之前那份配置本来就是本机私有的所以叫.env.local有余力的话可以了解一下 Next.js 到底是怎么找配置文件的它不是 只认一个而是按固定顺序找一串先找到的值优先以 npm run dev 为例顺序是.env.development.local → .env.local → .env.development → .envnpm run build 时则把中间的 development 换成 production这个顺序解释了两件事其一.env 也是认的只是优先级最低——适合放 各环境通用 的值其二.local 那几个排在前面意味着本机的设置永远盖过公共设置——这正是 本机私有 该有的待遇以上是前端 Next.js 的配置文件Python 后端的要求和它不同——用 Python 代码读取配置文件时认的就是 .env不需要加其它后缀配置文件放在指定位置即可前端配置放前端项目根目录后端配置放后端根目录在这个项目里就是 /backend 下另外Python 读取配置文件需要借助一个 python-dotenv 库等下安装为什么配置文件名前面有个点点开头的文件是隐藏文件——用隐藏文件写配置也是一种心照不宣的约定配置文件与 git配置文件不进 git原因有两个其一git 经常用来在不同设备之间同步代码比如本地电脑与服务器而配置文件和具体的设备有关不需要同步其二更重要——配置文件中很可能包含密码、密钥这类信息它们的保密程度显然比代码高绝对不能随着代码推送到远程仓库尤其是 GitHub 的公开仓库所以要把配置文件写进.gitignore明确要求 git 忽略它README 与 .example让 git 忽略配置文件是出于安全考虑但它会引起一个问题——别人拿到代码之后跑不起来不知道需要补充哪些配置、不知道配置文件应该叫什么名字、也不知道按什么格式写就会 玩不转 这个项目这怎么办惯例是所有项目的根目录中都需要有一个 README.md——在 GitHub 上新建仓库时那行 Initialize this repository with a README就是在询问是否需要建一个 README 文件我们判断一个开源库靠不靠谱时也会去看它的 README这个文件的作用是告诉拿到代码的人这个项目是怎么回事、解决什么问题、代码结构是怎样的、如何运行它有了 README配置文件缺失的问题就有了着落——把配置文件的要求写在 README 里人们拿到代码之后照着创建就行但关于配置文件还有一个心照不宣的约定写一份示例配置文件叫 example放进项目比如项目依赖一个.env配置文件就再创建一个.env.example也有人叫.env.sample、.env.template都是一回事它和.env长得一模一样键都在只是值全是示例——因为没有真的值所以能进 git运行时也不会真的生效它的作用就是给人看配置文件应该怎么写动手处理配置文件后端配置目前还写死在代码里先处理它要干两件事把值搬出去——挪到一个专门放配置的文件里让代码去读它——让程序启动时自己去那个文件里取第一件把值搬出去——在 backend/ 下新建一个 .env 文件# backend/.envALLOWED_ORIGINShttp://localhost:3000实际的配置就一行顶部#开头的是注释不会被代码读取按前面说的这个文件不能进 git——打开.gitignore确认有这一行.env*没有就现在加上然后git status看一眼——backend/.env不该出现在待提交列表里这一步别跳过配置不进 git 不能靠 我记得应该被挡住了要靠亲眼看一次git status第二件让代码去读它——改后端main.py顶部先引入两个库import os from dotenv import load_dotenv紧接着读取配置文件load_dotenv() # ← 读同目录下的 .env ALLOWED_ORIGINS os.getenv(ALLOWED_ORIGINS).split(,)然后修改中间件的 allow_origins不再使用写死的地址换成从配置文件读出来的动态值app.add_middleware( CORSMiddleware, allow_originsALLOWED_ORIGINS, # ← 不再写死从配置来 allow_credentialsTrue, ... )注意dotenv 不是 Python 标准库的成员需要手动安装并记进requirements.txtcd backend source .venv/bin/activate pip install python-dotenv pip freeze requirements.txt # 老规矩记账这个 dotenv 只干一件事把 .env 里的值读进环境变量改完之后本地验证后端用fastapi dev跑起来前端npm run dev文字实验室照常能用就说明后端配置改好了想更确定把.env里那行改成一个别的地址、重启后端、再点分析——这次真被拦了再改回来即可至此后端配置就单独抽成了配置文件接下来创建前后端配置文件的示例文件创建配置示例文件在项目根目录 ~/zero-to-tech/ 下创建.env.exampleNEXT_PUBLIC_API_BASE_URLhttp(s)://[ip]:[port]在后端根目录 ~/zero-to-tech/backend 下也创建.env.exampleALLOWED_ORIGINShttp(s)://[ip]:[port]键要写全值给一个能用的示例或者写有指引性的内容——这样别人cp .env.example .env之后改值就行不用再去猜键叫什么不过这里有一个问题配置文件本身不需要让 git 追踪但这两份.example文件要随代码一起提交不能被忽略现在.gitignore的.env*会把它们也拒之门外——所以要在.env*下面添加一行!.env.example感叹号的意思是把示例配置排除在忽略列表之外——它们可以随代码提交了提交代码到这里本地的活基本干完——代码改了、配置样例建好了一起推git add -A git commit -m CORS 名单改为从配置读取补 .env.example git push这次推上去的包括main.py读配置的代码、requirements.txt多了 python-dotenv、两份.env.example、还有改过的.gitignore服务器部署按照朴素的部署方案接下来只需把代码同步到服务器、在服务器上准备所需的环境然后前端构建、后端用fastapi run跑起来就可以了至于终端的后台运行和防火墙执行到对应步骤时再介绍拉取代码拉代码动手就快——先 SSH 登录ssh 用户名你的服务器IP cd ~/zero-to-tech git pull前后端代码都在这一个 git 仓库中所以这次 pull 就把前后端代码都拉到了服务器再ls backend/看一眼后端目录里应该有这些内容backend/main.pystorage.pyrequirements.txt.env.example有代码文件、有配置示例和 requirements.txt但没有 .venv/没有 history.db也没有 .env——我们自己定的规矩正在生效代码走 Git依赖和数据不随行准备 Python 环境接下来检查服务器的 Python 安装情况python3 --version # 有没有版本够不够 which python3 # 用的是哪一个Ubuntu 自带 Python 3第一句多半直接给出版本号但这两句都不能省——它们问的是两件不同的事--version回答 有没有、够不够fastapi、snownlp 这些库都有各自的最低 Python 版本要求太老的装不上——在装依赖之前发现版本不够和装到一半才报错是完全不同的两种体验which回答 用的是哪一个一台机器里可能住着好几个 Pythonpython和python3还各指各的——不是自己装的机器这个问题会更常见如果是 3.10 或更高的版本一般就没问题版本过低或者没装就需要安装安装方法不再展开Node 呢不用装——部署前端时我们就在这台服务器上装过 Node 并 build 过了不放心的话敲一句node -v确认一下安装依赖本地用 venv 管理 Python 环境服务器上也用 venvcd backend python3 -m venv --promptzero-to-tech .venv source .venv/bin/activate # 提示符出现 (zero-to-tech) pip install -r requirements.txt建 venv 那一步 Ubuntu 可能提示 venv 组件没装需要先sudo apt install python3-venv或提示里给出的具体包名如python3.12-venv照提示装完再重跑 venv 命令pip install会按 requirements.txt 逐个安装 fastapi、uvicorn、pypinyin、snownlp 这些依赖可能需要一些时间写配置文件依赖装完下一步是准备配置文件先写前端的cd ~/zero-to-tech cp .env.example .env.production vim .env.production在里面写NEXT_PUBLIC_API_BASE_URLhttp://服务器ip地址:8000再写后端的cd ~/zero-to-tech/backend cp .env.example .env # 照抄一份 vim .env # 再改值在里面写ALLOWED_ORIGINShttp://服务器ip地址注意这里没有端口号——别顺手写成 :3000也不要写 :80两份配置值的变化规律并不一样值得对照着看配置本地线上变了什么NEXT_PUBLIC_API_BASE_URLhttp://localhost:8000http://服务器IP:8000只换了地址ALLOWED_ORIGINShttp://localhost:3000http://服务器IP地址换了端口也没了为什么后端这份连端口都变了因为 ALLOWED_ORIGINS 登记的是 允许谁来找我 ——也就是前端页面所在的那个源本地的前端跑在 3000 端口上线上的前端是 Nginx 在 80 端口提供的——80 是 http 的默认端口浏览器发出的 Origin 里根本不带它所以配置值要跟着 那台机器上的事实 走不能照着本地做字符串替换——这正是配置存在的意义同一份代码在不同机器上适配各自的实际环境跑起来这一步顺手解决挑战三前后端分别跑前端直接构建——cd ~/zero-to-tech npm install npm run build后端正式上线用fastapi runcd ~/zero-to-tech/backend fastapi run启动日志示意以实机为准FastAPI Starting production server server Server started at http://0.0.0.0:8000 INFO Uvicorn running on http://0.0.0.0:8000 (Press CTRLC to quit)背后仍然是 Uvicorn但跑的地址是 0.0.0.0不是 127.0.0.1——这是 run 和 dev 的一个重要区别fastapi devfastapi run改代码自动重启有没有默认监听127.0.0.1——只听本机0.0.0.0——听所有网卡给谁用自己电脑上开发服务器上跑给全世界用127.0.0.1——只接受本机内部的连接外面的世界连不进来0.0.0.0——听所有网卡外面也能连进来服务器本地验证服务跑起来了先确认它在服务器本地运行正常再从公网验证——再开一个终端窗口、再 SSH 一次先验证后端接口curl localhost:8000/api/profile能看到 JSON 返回就说明后端服务已经起来了正在监听 8000 端口并且能在服务器本地请求再验证数据库已经初始化ls ~/zero-to-tech/backend/能看到history.db就说明数据库初始化完成要完整验证还得用 curl 做一次分析、再取一次 history——但没必要我们迫不及待想打开浏览器从公网访问一次真正的页面了开通防火墙轮到挑战五80 端口已经开放部署前端时确认过但云平台的安全组 / 防火墙默认不开 8000——需要手动放行方式和此前给 80 端口放行一样8000 开启之后用本地电脑访问 http://服务器IP:8000/api/profile能获取到返回的 JSON就说明 8000 端口通了测试通过浏览器访问 http://服务器ip地址就能打开前端页面在文字实验室对一句文字做分析——这一步测试后端服务是否正常运行点开历史记录看有没有分析过的那句话——这一步测试数据库是否正常工作更换浏览器或开启无痕模式换一句文字再做分析、再看历史记录——这一次应该看不到刚才那个浏览器分析过的内容只有新浏览器自己打的那一句——这一步测试的是会话机制换了浏览器就是换了访客各人只看得到自己的那一份都正常就说明我们已经成功把整套应用部署上线了——不仅可以通过电脑访问甚至用手机浏览器也能访问让后端在后台常驻只剩最后一条挑战四网站能用了很想合上笔记本去睡觉先别急做个实验直接关掉 SSH 窗口再刷新网站——页面还在那是 Nginx 送的静态文件但点分析按钮转圈、报错前端没问题但后端程序死了原因是 uvicorn 目前是个前台进程它寄生在我们的 SSH 会话里——我们走了它就没了会话 这个词又出现了我们和服务器之间那段连着的关系就是 SSH 会话——从登录那一刻开始到退出那一刻结束我们希望 uvicorn 的运行不依赖会话关掉终端之后它仍然可以持续在服务器上运行这个需求 Linux 有现成的办法——再次 SSH 登录远程服务器这次不直接执行fastapi run而是cd backend nohup .venv/bin/fastapi run backend.log 21 cd backend 我们已经很熟关键是第二行——一句话四个零件逐个拆末尾的——把这条命令丢到后台跑终端不用干等着开头的nohup—— no hang up别挂断它让这个进程不再随着 SSH 断开而被杀掉光有还不够——只是不占着终端人一走它照样陪葬 backend.log——把输出重定向进一个文件以前日志直接打在终端上现在没终端可打了不接住就全丢了21——认个脸把错误输出也一并塞进同一个文件1 是正常输出2 是错误输出这句的意思是 2 号跟着 1 号走——报错和正常日志混在一处翻起来方便敲完回车屏幕上会蹦出一个数字——那是进程号PID顺带留意这次写的是.venv/bin/fastapi这个完整路径而不是先激活环境再跑 fastapi——丢到后台的进程不见得还带着我们 activate 出来的那套环境指名道姓最保险现在把实验再来一遍关掉 SSH 窗口再次访问网站——这一次一切正常回顾并写入 README.md部署工作做完就可以安心写 README 文件了注意这个顺序不是先写好文档再照着做而是做完了、验证过了再把走通的那条路写下来——前者写出来的是 我以为该这么做后者写出来的才是 这么做真的可以一份过时或者想当然的 README比没有更糟——没有的话人家会来问你写错了的话人家会照着走进坑里打开项目根目录的README.md把这次的成果补进去# 文字实验室 ​ 一个中文文本分析小工具输入一段话给出情感倾向评分和全文拼音 并把每次分析的结果存下来各人只看得到自己的那一份。 ​ 零到全栈课程的贯穿项目。 ​ ## 技术栈 ​ - 前端Next.js静态导出 React - 后端FastAPI uvicorn - 分析snownlp情感、pypinyin注音 - 存储SQLite - 线上Nginx ​ ## 本地跑起来 ​ 需要Node.js 18、Python 3.10 ​ **后端** ​ bash cd backend python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt cp .env.example .env # 按下面「配置说明」填好 fastapi dev # → http://localhost:8000 ​ **前端**另开一个终端 ​ bash npm install cp .env.example .env.local # 按下面「配置说明」填好 npm run dev # → http://localhost:3000 ​ ## 部署到服务器 ​ 前提服务器上已装好 Python 3.10、Node.js 18 和 Nginx 且 Nginx 的站点根目录已指向本项目的 out/、监听 80 端口。 ​ **1. 拉取代码** ​ bash cd ~/zero-to-tech git pull ​ **2. 前端装依赖、写配置、构建** ​ bash npm install cp .env.example .env.production # 按下面「配置说明」填好 npm run build # 产物进 out/由 Nginx 提供服务 ​ **3. 后端建环境、装依赖、写配置** ​ bash cd backend python3 -m venv --promptzero-to-tech .venv # 首次部署才需要 source .venv/bin/activate pip install -r requirements.txt cp .env.example .env # 按下面「配置说明」填好 ​ **4. 后端在后台跑起来** ​ bash nohup .venv/bin/fastapi run backend.log 21 ​ fastapi run 是生产模式监听 0.0.0.0:8000nohup ... 让它在 SSH 断开后继续运行日志写进 backend.log。 ​ 查看日志、停止服务 ​ bash tail -f backend.log # 看日志 ps aux | grep fastapi # 找到进程号 kill 进程号 # 停掉 ​ **5. 放行 8000 端口** ​ 去云平台控制台的安全组 / 防火墙放行 8000 端口80 端口应该已经放行。 ​ **6. 验证** ​ 浏览器访问 http://服务器IP打开文字实验室做一次分析再看历史记录。 换一个浏览器或无痕窗口再试一次两边的历史记录应该是互相看不到的。 ​ ## 配置说明 ​ 配置文件不进 Git请照着 .env.example 自己建一份。 ​ **前端**开发用 .env.local生产构建用 .env.production ​ | 键 | 说明 | 本地 | 线上 | | --- | --- | --- | --- | | NEXT_PUBLIC_API_BASE_URL | 后端接口地址 | http://localhost:8000 | http://服务器IP:8000 | ​ **后端**backend/.env ​ | 键 | 说明 | 本地 | 线上 | | --- | --- | --- | --- | | ALLOWED_ORIGINS | 允许跨源访问的前端地址多个用逗号隔开 | http://localhost:3000 | http://服务器IP不带端口 |写完自己走一遍——最好的办法是假装自己是第一次拿到这个项目照着敲不许凭记忆补任何一步漏了哪句、少了哪个前提当场就露馅了README 是活的跟着项目一起长现在这一版够用了——够一个陌生人把项目在本地跑起来也够他照着部署到自己的服务器上等部署方式换掉之后再回来改它思考现在这套部署好不好站点上线了全世界能访问——但它是用最朴素的办法凑出来的存在三个明显的缺点第一后端服务脆弱——nohup 确实让后端活过了 SSH 断开但它只解决了这一件事还有一些问题它没解决服务器重启它不会自己起来服务器毕竟也是一台电脑——云厂商维护、断电、操作时手滑重启一旦发生后端服务就悄无声息地没了它崩了也不会自己起来代码里一个 bug 把进程弄死它就一直死着直到我们发现为止管起来全靠手工更新了代码想停掉重启一次比较麻烦得去找进程号想看它现在是不是活着也是一件麻烦事想看日志也比较麻烦得自己记着日志文件在哪儿第二裸奔的 8000 端口——8000 一直对公网开着而且是个裸端口没有日志谁来访问过 8000、干了什么无从查起80 端口就有Nginx 会记录没有加密内容明文来回跑——接下来要给网站配 HTTPS而 HTTPS 配在 Nginx 上走 8000 的那些请求一个字都保护不到没有任何管控限流、转发规则一概没有多开一扇门就多一分风险——这也是为什么服务器的防火墙不会默认开那么多端口第三前后端跨源——浏览器的 CORS 策略对前后端有太多限制开发阶段遇到的问题已经逐个解决但接下来要上域名、上 HTTPS 时跨源问题还会持续困扰我们能不能在部署环节就让前后端变成同源这三个问题就是接下来要换掉的东西让 systemd 取代 nohup——开机自启、崩溃自愈、一句命令问状态、一句命令看日志让 Nginx 反向代理把 /api/ 接进 80 端口——8000 端口不再对外提供服务前后端都走 80 之后自然变成同源配置文件也随之更简单——这套朴素的部署之后来一样样换掉
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

MySQL root密码重置全指南:原理详解、实操步骤与避坑经验 2026/10/1 18:07:05

MySQL root密码重置全指南:原理详解、实操步骤与避坑经验

mysql -uroot -p回车,输了一遍又一遍密码,最后只看到那行刺眼的ERROR 1045 (28000): Access denied for user rootlocalhost (using password: YES)。这种瞬间背后发凉的感觉,我猜每一个跟 MySQL 打过交道的人都经历过,我也不例外…

阅读更多 →
MySQL性能分析命令实战:从EXPLAIN到performance_schema排查慢SQL 2026/10/1 18:07:05

MySQL性能分析命令实战:从EXPLAIN到performance_schema排查慢SQL

上个月线上一个订单统计接口突然从200ms涨到8秒,业务方连续催了三次,运维把慢查询日志丢给我的时候,第一反应就是先别急着加索引——你连问题到底出在哪一步都不清楚,加什么索引都是碰运气。MySQL性能分析命令的价值就在这种时候体…

阅读更多 →
从零手搓AI工程:环境隔离、数据管道与推理服务实战 2026/10/1 18:07:05

从零手搓AI工程:环境隔离、数据管道与推理服务实战

1. 从零手搓AI工程:为什么我不建议你直接调包很多人一听到“AI工程”这四个字,第一反应就是打开某个云平台,拖几个组件,调几个API,然后跑通一个Demo,就觉得自己已经掌握了。我刚开始也是这么想的&#xff0…

阅读更多 →
DREAMVFIA:开源实现量子时间晶体数值模拟的工作台 2026/10/1 18:07:04

DREAMVFIA:开源实现量子时间晶体数值模拟的工作台

如果你关注过多体量子物理和数值模拟的开源代码,大概率听说过DREAMVFIA这个名字。我第一次看到它的时候,第一反应是:量子时间晶体这种听上去既像永动机变体又像科幻设定的东西,居然真有人做成了一套面向计算应用的开源工具&#x…

阅读更多 →
10款降AI率工具硬核实测:知网维普Turnitin全解析 2026/10/1 18:07:04

10款降AI率工具硬核实测:知网维普Turnitin全解析

去年年底,我一学弟拿着毕业论文终稿慌慌张张来找我,说学校用的知网AIGC检测系统把他结论章节标了48%疑似AI生成,而他那章其实是自己手写的,只是参考了几篇AI润色过的范文。那几天我陪着他把网上能搜到的“降AI率”工具挨个试了一遍…

阅读更多 →
数据挖掘驱动广告精准投放:从用户画像到效果评估的实战指南 2026/10/1 18:06:58

数据挖掘驱动广告精准投放:从用户画像到效果评估的实战指南

1. 内容整体设计与思路拆解1.1 广告投放为什么会需要数据挖掘先聊一个大家都遇到过的情况。你在某个电商平台搜过一次"机械键盘",接下来好几天,不管刷短视频还是看资讯,铺天盖地全是外设广告。这不是玄学,也不是平台&qu…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉