先说结论,再讲过程。
我这次做的事其实很简单:买了一台 99 元的云服务器,拿到手是一台"空盘"——系统装好了,但上面什么都没有,没有网站运行环境、没有运行库、没有任何代码。然后我用 Trae 的 Remote SSH 功能直接远程连上这台服务器,在远程环境里完成环境安装、代码编写、服务配置,最终把一个网站通过公网地址正常跑起来。
整个过程耗时约三个小时,其中一半时间花在踩坑上。这篇文章会把每一步怎么操作、为什么这么做、遇到问题怎么排查全部拆开讲,你照着走一遍,可以把这个过程压缩到一个小时以内。
先说一个重要判断:Trae Remote SSH 不是 VSCode Remote SSH 的简单复制,而是把 AI 编程能力直接搬到了远程环境里。这意味着你可以在云端服务器上直接写代码、直接跑调试、直接让 AI 改配置,而不需要本地装一堆环境、再把文件来回同步。对于一个"从空盘到上线"的项目来说,这个工作方式天然更贴合真实生产链路。
1. 为什么选 Trae Remote SSH + 99 元云服务器这个组合
1.1 本地开发与远程开发的真实差距
大多数开发者的习惯是:本地装一套开发环境,写代码、本地跑通,然后把代码通过 Git 推到服务器,再在服务器上拉代码、装依赖、重启服务。这个流程看着没问题,但实际操作中你会遇到一堆边界情况——
本地 Python 版本和服务器不一致、本地依赖装得上但服务器上编译报错、本地 Nginx 配置没问题但服务器上路径大小写敏感导致 404。每一次环境差异都是在消耗你的时间。
Trae 的 Remote SSH 解决的是另一个思路:开发环境即生产环境。服务器上是什么系统、什么版本、什么依赖,你远程连接后开发时面对的就是什么。代码写完直接在这台机器上跑,运行结果就是服务器真实运行的结果,没有"本地好好的,上传就挂"这种玄学问题。
1.2 Trae Remote SSH 的核心优势
Trae 作为 AI 原生的 IDE,Remote SSH 能力不是简单把本地窗口映射到远程,而是把整个 AI 辅助链路搬到远程。
具体来说有几点很关键:
- 代码补全和 AI 对话都基于远程文件系统。你选中远程服务器上的代码让 AI 解释或修改,AI 读取的就是服务器上的真实文件,不会出现本地和远程文件不一致导致的 AI 建议失效。
- 终端、文件树、编辑器三合一。连接远程后,左侧文件树是服务器目录,底部终端直接就是服务器的 shell,不需要再单独开一个 SSH 客户端。
- Chat 模式和 Build 模式可以直接操作远程环境。在 Trae 的对话窗口里让 AI"帮我在远程服务器上安装 Nginx",它会直接通过终端执行命令并反馈结果。
这些能力叠加起来,本质上就是把"服务器运维 + 代码开发"合并成了一个窗口。对于个人站长、独立开发者、学生做项目来说,这个效率提升非常明显。
1.3 哪些人适合这个组合
99 元云服务器 + Trae Remote SSH 这个组合,我认为最适合三类人:
- 需要低成本练手的开发者。不想在本地折腾虚拟机、双系统,想以最低成本接触真实 Linux 服务器,这台服务器就是最好的练习场。
- 做个人网站、作品集、小型业务站的站长。不需要高配置,一台 99 元的入门服务器足够支撑日均几百到几千访问量的站点。
- 体验 AI 编程 + 云端开发新范式的人。如果你一直在本地用 AI 编程工具,想试试"不带电脑也能改服务器上的代码"这种模式,Remote SSH 是成本最低的入口。
2. 服务器选购与初始化:99 元预算怎么花得明白
2.1 选购时的核心参数怎么看
买 99 元这个价位的云服务器,你要先搞清楚自己花这 99 元买到的是什么配置。以目前市面常见的基础款为例,核心参数大致是:1 核 CPU、1~2 GB 内存、20~40 GB 系统盘、3~5 Mbps 带宽(有的带宽计费方式不同)。
对这个价位有个清醒认知很重要:它不是用来扛高并发的,它的定位是"能稳定跑一个中小型网站 + 给你一个真实 Linux 练习环境"。
选择时重点看这几个参数:
| 参数 | 建议值 | 原因 |
|---|---|---|
| CPU | 1 核 | 单核足够跑 Nginx + PHP + MySQL 的小型站点 |
| 内存 | 2 GB 起步 | 1 GB 也能跑,但 MySQL 和 PHP-FPM 同时运行时吃紧 |
| 系统盘 | 30 GB 以上 | 系统占 5~8 GB,剩下留给网站代码和日志 |
| 带宽 | 3 Mbps 以上 | 带宽决定用户访问速度,3 Mbps 约等于 375 KB/s |
| 流量 | 月流量包越大越好 | 图片、静态资源多的站点流量消耗快 |
我这次选的是 2 GB 内存、40 GB 盘、4 Mbps 带宽的入门款,实际跑下来,一个带 WordPress 的站点 + 一个静态页面站点,内存占用稳定在 1.2 GB 左右,带宽够用。
2.2 操作系统选择与初始化配置
操作系统这里,建议直接选Ubuntu Server 22.04 LTS或者Debian 12。原因很简单:这两个系统的软件源更新及时、社区资料最多、遇到问题搜到的解决方案最全。CentOS 已经停止维护,新项目不建议再碰。
初始化时务必注意以下三个点:
- 设置 root 密码。虽然后面我们推荐用密钥登录,但第一次登录和应急恢复时 root 密码还是必需的。
- 创建普通用户并加入 sudo 组。安全习惯上,日常操作不应该用 root,而是用普通用户 + sudo 提权。后面配置 SSH 密钥也是针对这个普通用户。
- 记录公网 IP 和地域。地域决定了你后续访问的延迟,离你近的地域延迟更低。这个 IP 后面要反复用到。
2.3 安全组、防火墙与端口放行
这是新手第一次买服务器时最容易忽略的坑。云厂商的控制台里有一个"安全组"或者"防火墙"配置,它相当于云服务器外层的闸门,默认情况下只放行个别端口。
网站要跑起来,至少需要放行这几个端口:
- 22(SSH):远程连接用。
- 80(HTTP):网站普通访问。
- 443(HTTPS):网站加密访问。
操作上要在云厂商控制台的安全组规则里添加入方向规则。这里有一个常见误区:很多人只在服务器内部的防火墙(比如 ufw 或 firewalld)里放行了端口,但控制台安全组没放行,结果外部依然无法访问。云服务器的防火墙是两道闸门,控制台安全组和系统内部防火墙都要放行。
关于 SSH 端口,建议不要用默认的 22。这个端口每天会被全网扫描无数次,虽然密钥登录安全性已经很高,但把 SSH 端口改成一个高位端口(比如 22022),能过滤掉绝大多数无差别扫描流量。
3. Trae Remote SSH 连接:从安装到首次远程会话
3.1 SSH 密钥生成与配置流程
连接远程服务器,推荐使用 SSH 密钥而不是密码。密钥登录的优势是:私钥留在本地,公钥放到服务器,登录时通过非对称加密验证身份,不会被暴力破解,也不怕密码泄露。
生成密钥的操作在本地终端完成:
ssh-keygen -t ed25519 -C "trae-remote-ssh" -f ~/.ssh/trae_server这里选择 ed25519 算法,比传统的 RSA 2048 更安全、密钥更短、生成速度更快。执行后会生成两个文件:
~/.ssh/trae_server:私钥,留在本地,绝对不能泄露。~/.ssh/trae_server.pub:公钥,这个是要放到服务器上的。
然后把公钥内容复制下来,通过密码登录服务器后写入授权文件:
# 在服务器上执行 mkdir -p ~/.ssh chmod 700 ~/.ssh echo "你的公钥内容" >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keyschmod权限设置这一步非常关键。OpenSSH 对.ssh目录和authorized_keys文件的权限有严格检查,如果权限过宽(比如 777),服务器会直接拒绝用这个密钥认证,这属于安全机制的正常保护。
3.2 Trae 中配置 Remote SSH 的完整步骤
Trae 的 Remote SSH 入口在左侧活动栏,点击远程资源管理器图标,选择"连接到主机",然后选择"配置 SSH 主机"。
这里会打开一个 SSH 配置文件,默认路径是本地用户的~/.ssh/config。在里面追加以下内容:
Host trae-test HostName 你的服务器公网IP User ubuntu Port 22022 IdentityFile ~/.ssh/trae_server StrictHostKeyChecking no ServerAliveInterval 60逐行解释一下:
- Host:这是你给这个连接起的名字,之后在 Trae 里看到的连接列表就是它。
- HostName:云服务器的公网 IP。
- User:登录用户,对应你创建的那个 sudo 普通用户。
- Port:SSH 端口,如果前面按建议改了端口就填新端口,没改就填 22。
- IdentityFile:指向刚才生成的私钥文件。
- ServerAliveInterval 60:每 60 秒发送一次心跳包,防止长时间空闲导致连接断开。
保存配置文件后,回到远程资源管理器,刷新列表,就能看到trae-test这个连接。点击连接,Trae 会开一个新窗口,等到左下角显示"已连接到远程"(SSH: trae-test),就说明连接成功了。
首次连接时 Trae 会在远程服务器上自动安装一个服务端组件,这个组件用于支持文件同步、终端、端口转发等功能。这一步需要几十秒,属于正常现象。
3.3 连接成功后的第一件事:目录规划
连接成功后,不要急着装环境。先把服务器上的目录结构规划好,这是一个"之后每次上线都会感谢自己"的习惯。
我的推荐结构是:
/home/ubuntu/ ├── sites/ # 所有网站的根目录 │ └── example.com/ │ ├── public_html/ # Web 可访问的根目录 │ ├── logs/ # 该网站的访问和错误日志 │ └── backup/ # 备份文件 ├── scripts/ # 自己写的运维脚本 └── tools/ # 下载的第三方工具在 Trae 的远程终端里执行:
mkdir -p ~/sites/example.com/{public_html,logs,backup}这个规划的好处很明显:每个网站的代码、日志、备份彼此隔离,排查问题时目录一目了然,备份时只需打包对应目录。
4. 从空盘开始:LNMP 环境搭建的完整手记
4.1 系统基础优化与依赖安装
空盘服务器拿到手,第一步不是装 Nginx,而是先把系统基础打好。
# 更新软件源和系统包 sudo apt update && sudo apt upgrade -y # 安装基础工具 sudo apt install -y curl wget git unzip vim software-properties-common这里有两个细节值得说明:
为什么要先apt update?云厂商的基础镜像虽然能开机,但软件源是出厂状态,不更新的话安装软件时可能遇到源失效或者版本过旧的问题。这一步执行时间可能比较长,但必须做。
为什么强调apt upgrade?新购买的服务器的系统补丁往往滞后,安全更新在第一时间打齐是上线的底线操作。99 元的服务器虽然便宜,但暴露在公网上遇到的安全风险并不比其他服务器少。
4.2 Nginx 安装与配置
Nginx 我倾向于直接从发行版软件源安装,不折腾编译安装。对于这个价位的服务器和常规网站负载,软件源的 Nginx 版本完全够用。
sudo apt install -y nginx安装完成后,用systemctl检查状态:
sudo systemctl status nginx正常情况下会显示active (running)。此时在浏览器里直接访问服务器公网 IP,就能看到 Nginx 的默认欢迎页。这是"从空盘到有网页"的第一步。
接下来需要修改默认配置,让 Nginx 更贴合实际使用:
# 编辑默认站点配置 sudo vim /etc/nginx/sites-available/default重点关注和修改两个参数:
server_tokens off; # 隐藏 Nginx 版本号,减少被针对性攻击的风险 client_max_body_size 20M; # 允许上传文件大小,默认 1M 对很多应用不够server_tokens off这个配置是很多教程不会提的。默认情况下,Nginx 错误页会显示版本号,扫描工具会根据版本号匹配已知漏洞,把版本号隐藏掉是成本最低的安全加固。
4.3 PHP 与数据库安装配置
网站要跑动态程序,必须装 PHP 和数据库。这里我选的是 PHP 8.1 + MariaDB 的组合。
先装 PHP 及常用扩展:
sudo apt install -y php8.1-fpm php8.1-mysql php8.1-curl php8.1-gd php8.1-mbstring php8.1-xml php8.1-zip这些扩展几乎是 PHP 应用标配:gd用于图片处理,mbstring用于多字节字符串,zip用于压缩包处理。安装时一次性装齐,避免后面用到某个功能却发现缺扩展的尴尬。
装完之后调整 PHP-FPM 的运行参数:
sudo vim /etc/php/8.1/fpm/pool.d/www.conf找到以下参数并修改:
pm = dynamic pm.max_children = 10 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3pm.max_children是 PHP-FPM 能同时处理的最大请求数,这个值不能盲目调大。它直接受内存限制:每个 PHP-FPM 进程大约占 40~60 MB 内存,2 GB 内存的服务器要给 MySQL 和系统留足空间,所以 max_children 设置在 10 左右是安全值。调太大容易内存耗尽导致系统卡死。
数据库这边,为了省资源直接用 MariaDB:
sudo apt install -y mariadb-server sudo mysql_secure_installationmysql_secure_installation这个交互式脚本会引导你完成安全设置,包括设置 root 密码、移除匿名用户、禁止 root 远程登录等。执行完这些,数据库基础安全就算做好了。
4.4 PHP-FPM 与 Nginx 的对接
装完 PHP-FPM 后还需要让 Nginx 知道:.php结尾的请求应该交给谁处理。
在 Nginx 站点配置里添加以下 location 块:
location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.1-fpm.sock; }然后测试配置并重载:
sudo nginx -t sudo systemctl reload nginx这里的核心是fastcgi_pass的地址。PHP-FPM 默认监听一个 Unix socket 文件(/run/php/php8.1-fpm.sock),Nginx 通过这个 socket 把 PHP 请求转给 PHP-FPM 处理。如果你改了 PHP 版本,这里的路径也要对应修改,否则会报connect() failed错误。
4.5 项目代码上传与目录权限设置
环境装好后,把网站代码上传到服务器。在 Trae Remote SSH 里,这个操作非常直接:远程资源管理器中找到目标目录,直接把本地文件拖拽进去。
代码传上去之后,权限设置是让网站真正跑起来的关键一步。
# 设置网站目录的所有者和权限 sudo chown -R www-data:www-data ~/sites/example.com/public_html sudo chmod -R 755 ~/sites/example.com/public_htmlwww-data是 Nginx 和 PHP-FPM 默认的运行用户。如果网站目录的所有者是 root 或你自己的用户名,PHP 进程将没有权限读写这些文件,表现为"页面能访问但写入失败"或者直接 403。这是新手最容易忽略的问题。
如果你是把自己正向 ~/sites 目录里拖代码,还要确保中间层目录的权限不会阻挡访问:
chmod 755 ~因为 Nginx 工作进程要从根目录一层层进入你的网站目录,home 目录本身如果没有执行权限,Nginx 一样进不来。
5. 网站上线与验证:从根目录到浏览器地址栏
5.1 配置 Nginx 虚拟主机
环境就绪后,开始配置网站的虚拟主机。Nginx 的站点配置习惯上不直接改默认配置,而是为每个站点单独建一个配置文件。
sudo vim /etc/nginx/sites-available/example.com写入如下内容:
server { listen 80; server_name example.com www.example.com; root /home/ubuntu/sites/example.com/public_html; index index.php index.html index.htm; access_log /home/ubuntu/sites/example.com/logs/access.log; error_log /home/ubuntu/sites/example.com/logs/error.log; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.1-fpm.sock; } location ~ /\.ht { deny all; } }这里有几个配置细节要讲清楚:
try_files $uri $uri/ /index.php?$query_string:这是让 Nginx 先找静态文件,找不到就把请求重写到 index.php。WordPress、ThinkPHP 等绝大多数 PHP 应用都依赖这个规则,少了这行,伪静态链接全部会 404。access_log和error_log分开记录,排查问题时不用去翻 Nginx 全局日志。location ~ /\.ht拒绝访问以.ht开头的文件,防止配置文件被直接下载。
启用站点配置:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginxln -s创建软链接是 Nginx 推荐的做法:配置文件放在sites-available作为存档,在sites-enabled里通过软链接启用。禁用站点时删除软链接即可,配置文件不会丢失。
5.2 域名解析与 HTTPS 证书配置
如果你的网站要绑定域名,需要先在域名服务商处把域名解析到服务器 IP 上。常见解析记录是:
- A 记录:
example.com→ 服务器公网 IP - CNAME 记录:
www→example.com,或者也直接用 A 记录
解析设置完成后,用以下命令验证是否生效:
dig example.com +short如果返回的是你的服务器 IP,说明解析生效。这里有个经验:解析全球生效通常需要几分钟到几十分钟,不用急着查,先去准备 HTTPS 证书。
HTTPS 证书我推荐用 Let's Encrypt 的免费证书,配合certbot自动签发和自动续期:
sudo apt install -y certbot python3-certbot-nginx sudo certbot --nginx -d example.com -d www.example.comcertbot 会自动修改 Nginx 配置,把 80 端口的请求重定向到 443,并生成证书文件。签发成功后,在浏览器地址栏能看到小锁图标,说明 HTTPS 已经生效。
很多人不知道的是,Let's Encrypt 证书有效期是 90 天,需要自动续期。certbot 安装时会自动添加定时任务,你可以手动验证一下续期任务是否就位:
sudo systemctl list-timers | grep certbot看到certbot.timer存在且状态为 active,就可以放心了。
5.3 上线后的功能验证与性能初测
网站配置完成后,做一轮系统性验证。我在这次实测中按下面清单逐项检查:
访问验证:
# 测试 HTTP 是否正常返回 curl -I http://example.com # 测试 HTTPS 是否正常返回 curl -I https://example.com # 验证 PHP 是否正常解析 echo "<?php phpinfo(); ?>" > ~/sites/example.com/public_html/test.php curl http://example.com/test.php如果test.php返回 PHP 信息页面,说明 Nginx 到 PHP-FPM 的链路完全打通。验证完记得删除这个测试文件:
rm ~/sites/example.com/public_html/test.php资源占用情况:
free -h df -h uptime这三个命令分别查看内存、磁盘和负载。在正常访问压力下,2 GB 内存应该还有 600~800 MB 空闲,磁盘使用率低于 40%,负载不超过 1.0,这些都是健康的指标区间。
HTTPS 证书状态:
sudo certbot certificates确认证书状态是VALID,域名列表包含你绑定的域名。
数据库连接验证:
在 PHP 代码或数据库管理工具中,用网站配置的数据库账号连接一次 MariaDB,确认账号权限正常。这一步能提前暴露"数据库账号权限不足"这类只有运行时才会发现的问题。
6. 实测总结:踩坑记录与后续优化空间
6.1 整个流程中最容易翻车的三个环节
这次实测走下来,我在三个环节上分别卡住过,这里直接复盘,帮你避开。
第一个坑:安全组只放行了一条端口,结果 80 端口死活不通。
现象:服务器内curl http://localhost正常,但外部浏览器访问 IP 超时。排查过程:先在服务器上确认 Nginx 在监听 80 端口(ss -tlnp | grep 80),再在本地telnet IP 80测试端口连通性,发现连接被拒绝。最后回到云控制台,发现安全组入方向规则里只放行了 22 端口,于是补上 80 和 443。这个问题一半人都会遇到,属于"服务器内部正常但外部访问不了"的头号原因。
第二个坑:PHP-FPM 的 socket 路径写错,导致所有 PHP 页面 502。
现象:静态页面正常,但所有.php文件返回 502 Bad Gateway。排查过程:查看 Nginx 错误日志tail -f /var/log/nginx/error.log,发现connect() to unix:/run/php/php8.1-fpm.sock failed,说明 fastcgi_pass 指向的 socket 文件不存在。用ls /run/php/查看实际文件名后,修正配置中的路径,重载 Nginx 解决。
第三个坑:目录权限不够,WordPress 后台无法安装主题和插件。
现象:网站能打开,但后台点击"安装插件"时提示创建目录失败。排查过程:用ls -la查看网站目录所有者,确认是ubuntu用户而不是www-data,于是重新执行chown -R www-data:www-data,问题解决。这个问题的隐蔽之处在于页面能正常访问,只有写入操作才会报错。
6.2 从现象到根因的排查链路
踩过这几个坑之后,我总结出一套通用的排查链路,供你参考:
| 现象 | 排查方向 | 关键命令 |
|---|---|---|
| 外部访问不了 | 安全组 → 系统防火墙 → 服务监听 | ss -tlnp、curl localhost |
| 502 Bad Gateway | PHP-FPM 状态 → socket 路径 → 错误日志 | systemctl status php8.1-fpm、tail /var/log/nginx/error.log |
| 403 Forbidden | 目录权限 → Nginx 用户权限 | ls -la、chown www-data:www-data |
| 404 页面 | 伪静态规则 → 站点 root 路径 | tail /var/log/nginx/error.log、nginx -t |
| 网站打开很慢 | 带宽占用 → 内存不足 → PHP-FPM 被 kill | iftop、free -h、dmesg | tail |
这套链路的逻辑是:先判断请求到没到服务器,再判断服务器内部处理到哪一环断了,最后看是哪一层权限或配置挡住了。每一步都有明确的日志或命令来定位,不建议跳过任何一步,也不要一上来就重启服务——重启只会掩盖问题,不会暴露根因。
6.3 基于 99 元服务器的进一步优化空间
网站跑起来只是开始。基于这台 99 元服务器,还有几个低成本高收益的优化方向:
数据库按需优化。MariaDB 默认配置对内存的使用比较保守,但如果你的站内存长期低于 50%,可以尝试调整innodb_buffer_pool_size到内存的 50% 左右,能明显提升数据库查询性能。注意调整后观察内存占用,防止 OOM。
用 Nginx 缓存静态资源。给图片、CSS、JavaScript 文件加上浏览器缓存头,可以显著减少服务器的带宽消耗:
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|webp)$ { expires 30d; add_header Cache-Control "public, no-transform"; }定期自动备份。写一个简单的定时任务脚本,每天凌晨打包网站目录和数据库,保留最近 7 天的备份:
#!/bin/bash # 脚本:备份网站和数据库 BACKUP_DIR="/home/ubuntu/backup" DATE=$(date +%Y%m%d) mysqldump -u root example_db > "$BACKUP_DIR/db_$DATE.sql" tar czf "$BACKUP_DIR/site_$DATE.tar.gz" /home/ubuntu/sites/example.com find "$BACKUP_DIR" -name "*.sql" -mtime +7 -delete find "$BACKUP_DIR" -name "*.tar.gz" -mtime +7 -delete配合crontab -e添加到每天凌晨执行。99 元的服务器不用指望硬件容错,但一份好用的备份脚本能在出问题时让你从容恢复。
6.4 一些碎片化的实操心得
最后分享几个这次实测中总结的碎片化心得,不一定够成体系,但都是真金白银试出来的。
Trae Remote SSH 连接偶尔断开是很正常的。网络波动或者服务器空闲超时都可能导致连接中断,重新连接即可,不会影响服务器上已经跑起来的服务。为了避免频繁断连,我前面配置里加上了ServerAliveInterval 60,这个心跳参数实测非常有效。
在远程环境里让 AI 帮你做事,指令要带上下文。你让 Trae 的 AI"看看 error.log",它需要知道日志文件在哪里。建议在对话前先把远程文件树里相关文件点开,或者在指令里写清楚完整路径,这样 AI 的回答会精确得多。
别把 99 元服务器当生产级高可用环境用。它适合做学习、测试、中小型流量网站,如果你的业务对稳定性要求很高,后期应该考虑升级配置或者上负载均衡。但这台服务器作为练手和初期项目落地,性价比已经是天花板级别。
整个流程走完,我最深的体会是:"从空盘到上线"这件事,真正的门槛不在技术本身,而在于链条的完整性和排错的思路。每一层组件单独看都不复杂,但串起来的时候,任何一个环节的配置偏差都会让结果静默失败。这也是为什么我坚持把每一处配置的含义和排查方法都写出来——知其所以然,下次遇到变种问题你也能自己定位。