My first VPS was located in Japan.
我的第一台 VPS 位于日本。
At the time, the decision seemed obvious.
Japan was relatively close to China, the latency was low, and the price was acceptable.
当时这个选择看起来非常合理。
日本距离国内较近,延迟比较低,价格也在我能够接受的范围内。
My requirements were also very simple.
If the website opened, SSH worked, and the services stayed online, I considered the server good enough.
那时我对 VPS 的要求也很简单。
网站能够打开、SSH 可以连接、服务能够正常运行,对我来说就已经足够。
I was still learning what Linux, Nginx, DNS, certificates, and server deployment actually meant.
我当时还在慢慢理解 Linux、Nginx、DNS、证书以及服务器部署究竟是怎么回事。
The Japan VPS gave me a place to experiment without needing to understand everything in advance.
这台日本 VPS 给了我一个可以不断尝试的环境,而不需要一开始就完全理解所有东西。
As my website became more complete, my expectations also changed.
随着网站逐渐完善,我对服务器的要求也开始发生变化。
I no longer wanted a machine that could simply display a few pages.
我不再只需要一台能够展示几个网页的机器。
I wanted the server to host my personal website, Nginx, HTTPS, Hysteria, and future projects for a longer period of time.
我希望它能够长期承载个人网站、Nginx、HTTPS、Hysteria,以及以后可能部署的其他项目。
The Japan VPS still had good latency, but latency was no longer the only thing that mattered.
日本服务器的延迟依然不错,但延迟已经不再是我唯一关心的指标。
Bandwidth, route stability, storage, long-term cost, and the ability to run several services at the same time became more important.
带宽、线路稳定性、存储空间、长期成本,以及同时承载多个服务的能力,开始变得更加重要。
A server can be physically closer and still be less suitable for the job.
服务器离得更近,并不代表它一定更适合长期使用。
The limitations were not always obvious during normal browsing.
在普通浏览网页时,这些限制并不总是非常明显。
But they became easier to notice when I uploaded files, created backups, tested builds, or moved larger amounts of data.
但在上传文件、制作备份、测试构建或者同步较多数据时,服务器的限制就会逐渐暴露出来。
Instead of continuing to repair and expand the old setup, I decided to move the website to a US VPS.
与其继续围绕旧环境不断修补,我最终决定把网站迁移到一台美国 VPS。
This migration was not simply a matter of copying several files from one server to another.
这次迁移并不只是把几个文件从一台服务器复制到另一台服务器。
The website itself had also changed.
网站本身也已经发生了变化。
The new version was built with Next.js, while the old deployment still depended on an application process running on the server.
新版网站使用 Next.js 构建,而旧的部署方式仍然依赖服务器上长期运行的应用进程。
For the new version, I chose static export.
对于新版网站,我最终选择了静态导出。
After the build finished, the website became a collection of static HTML, CSS, JavaScript, and asset files.
完成构建之后,网站会变成一组静态的 HTML、CSS、JavaScript 和资源文件。
Nginx could serve those files directly.
Nginx 可以直接向访问者提供这些静态文件。
There was no longer a need to keep a Node.js process listening on port 3000.
服务器不再需要让一个 Node.js 进程长期监听 3000 端口。
This made the deployment simpler.
这让整个部署结构变得更加简单。
One fewer long-running process also meant one fewer service that could crash, consume memory, or require separate monitoring.
少一个长期运行的进程,也意味着少一个可能崩溃、占用内存或者需要单独监控的服务。
I did not overwrite the old website immediately.
我没有直接覆盖旧网站。
The old deployment, the new release, and the backup created before the migration were kept in separate directories.
旧版本、新发布版本,以及迁移前制作的备份,都被保存在不同的目录中。
This was important because I did not want a failed deployment to become an emergency repair session.
这一点很重要,因为我不希望一次部署失败,最后变成一场临时抢救。
If the new version had a serious problem, I could point Nginx back to the previous directory.
如果新版出现严重问题,我只需要让 Nginx 重新指向旧版本目录。
A rollback would take far less time than trying to reconstruct deleted files while the website was already offline.
回滚旧版本,显然比网站已经离线之后再去寻找被覆盖的文件容易得多。
Before switching traffic, I checked the homepage, the blog list, individual articles, project pages, robots.txt, and sitemap.xml.
正式切换之前,我检查了主页、博客列表、文章页面、项目页面、robots.txt 和 sitemap.xml。
I also checked the generated static files and internal asset references.
我还检查了生成后的静态文件以及内部资源引用。
The goal was not only to confirm that the build command had succeeded.
我的目标并不只是确认构建命令显示成功。
A successful build does not guarantee that every page, route, image, and internal link is correct.
构建成功,并不代表每个页面、路由、图片和内部链接都一定正常。
Only after those checks did I change the Nginx site root to the new release directory.
完成这些检查之后,我才将 Nginx 的站点根目录切换到新的发布目录。
During the entire cutover, Nginx was reloaded only once.
整个切换过程中,Nginx 只执行了一次 reload。
It was not restarted.
它没有被 restart。
A reload allows Nginx to read the new configuration without unnecessarily interrupting the entire service.
reload 可以让 Nginx 重新读取配置,而不需要粗暴地中断整个服务。
For a small personal website, the practical difference may be difficult to notice.
对于一个访问量不大的个人网站来说,普通访问者可能很难察觉两者的区别。
But I still preferred the option with less disruption and a clearer rollback path.
但我仍然更愿意选择中断更少、回滚路径更清晰的方式。
The Hysteria service running on the same VPS was not restarted.
运行在同一台 VPS 上的 Hysteria 也没有重启。
It continued listening on its existing UDP port while the website deployment was changed around it.
在网站切换的过程中,它仍然继续监听原来的 UDP 端口。
The website migration did not require the whole server to restart.
网站迁移并不需要重启整台服务器。
This was another reason to treat each service independently.
这也是我逐渐开始把不同服务分开管理的原因。
Changing a website should not automatically interrupt an unrelated network service.
修改网站,不应该理所当然地中断一个无关的网络服务。
After the new site was confirmed to be working, the old Node.js service was stopped and port 3000 was closed.
确认新网站运行正常之后,旧的 Node.js 服务被停止,3000 端口也被关闭。
The final structure was simpler than before.
最终的服务器结构比之前更加简单。
Nginx served the static website directly, while Hysteria continued running as a separate service.
Nginx 直接提供静态网站,Hysteria 则继续作为独立服务运行。
The migration did not involve any particularly advanced technology.
这次迁移并没有使用什么特别高级的技术。
But it changed the way I understood deployment.
但它改变了我对“部署”这件事的理解。
Previously, I thought deploying a website mainly meant uploading files until the page opened successfully.
过去我认为部署网站,主要就是把文件上传到服务器,然后让网页能够正常打开。
Now I think the more important questions are what happens when the deployment fails.
现在我认为,更重要的问题是部署失败之后该怎么办。
Can the previous version still be restored?
旧版本是否还能恢复?
Are the backups complete?
备份是否完整?
Will changing one service interrupt another?
修改一项服务,是否会影响其他服务?
Can the change be verified before real traffic reaches it?
能否在真实流量切换之前完成验证?
Confidence is not a rollback strategy.
自信并不是一种回滚方案。
A server does not forgive a destructive command simply because the person typing it believed everything would work.
服务器并不会因为执行命令的人充满信心,就自动原谅一次破坏性操作。
The final process was simple:
最终形成的流程其实很简单:
Build first, then verify.
先构建,再验证。
Back up first, then switch.
先备份,再切换。
Reload when a restart is unnecessary.
没有必要重启时,就只 reload。
Keep the old version until the new one has been proven to work.
在新版被确认正常之前,保留旧版本。
The move from Japan to the United States was not only a change of server location.
从日本迁移到美国,并不只是一次服务器地理位置的变化。
It was also the first time I completed a deployment with separate releases, validation, rollback preparation, and minimal interruption.
它也是我第一次真正完成一套包含独立发布、上线前验证、回滚准备和最小中断的部署流程。
The website worked, Hysteria stayed online, and the old version remained available if anything went wrong.
网站成功运行,Hysteria 没有中断,旧版本也依然保留着,以防出现意外。
Nothing dramatic happened.
整个过程中没有发生什么戏剧性的事故。
That was exactly the result I wanted.
而这正是我最想要的结果。