新测试服务器从 0 搭建项目记录
记录人:龙猫(按用户口述逐步记录) 起始时间:2026-10-20
1. 服务器基础信息
- 操作系统:Debian 13.2
- 服务器操作终端:WindTerm
2. 配置 SSH 密钥登录
目的:配置 SSH 密钥,方便登录。
- 在
/root/.ssh/目录下,把对应的公钥(public key)内容写进/root/.ssh/authorized_keys文件。 - 查看当前目录下的所有文件(含隐藏文件):
ls -a- 查看文件内容:
cat- 权限要求:
/root/.ssh文件夹权限须为700authorized_keys权限须为600- 两者属主均为
root
设置权限的命令:
chmod 700 /root/.sshchmod 600 /root/.ssh/authorized_keyschown root:root /root/.sshchown root:root /root/.ssh/authorized_keys3. 修改 SSH 服务配置
编辑 /etc/ssh/sshd_config 文件,确认/修改以下两项:
PubkeyAuthentication yesPermitRootLogin yes- 改完需重启服务生效:
systemctl restart sshd4. 安装 Nginx
适用系统:Debian 13.2 (trixie),官方源自带 nginx 1.26.3,无需第三方源。
4.1 安装
apt updateapt install -y nginx装完确认服务状态并设置开机自启:
systemctl enable nginxsystemctl start nginxsystemctl status nginx4.2 验证
curl -I http://127.0.0.1ss -tlnp | grep :80Debian 默认站点根目录是 /var/www/html,访问公网 IP 能出 "Welcome to nginx!" 即成功。
验证结果(2026-10-20):
| 项 | 结果 |
|---|---|
| 本机访问 | HTTP/1.1 200 OK,Server: nginx |
| 公网访问 | HTTP/1.1 200 OK,<title>Welcome to nginx!</title> |
| 监听端口 | 80(IPv4 + IPv6) |
| 服务状态 | active / enabled |
| 站点根目录 | /var/www/html/index.nginx-debian.html |
5. 新建站点
5.1 创建站点根目录
mkdir -p /var/www/your-site5.2 写站点配置(静态站)
vim /etc/nginx/sites-available/your-site.confserver { listen 80; listen [::]:80; server_name your-domain.com; root /var/www/your-site; index index.html; # 静态资源缓存 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ { expires 30d; access_log off; } # history 路由模式需要(Vue Router / uniapp) location / { try_files $uri $uri/ /index.html; } access_log /var/log/nginx/your-site.access.log; error_log /var/log/nginx/your-site.error.log;}5.3 启用配置
⚠️ 坑:配置放在
sites-available/不会生效,nginx 只加载sites-enabled/下的文件。 必须软链过去,否则请求会命中 default 站点。
ln -s /etc/nginx/sites-available/your-site.conf /etc/nginx/sites-enabled/your-site.conf判断是否生效:看响应的 Content-Length。
| Content-Length | 含义 |
|---|---|
615 |
命中了 default 站点,配置没生效 |
| 自己页面的字节数 | 已生效 |
5.4 校验并生效
nginx -tsystemctl reload nginxnginx -t 必须先输出 syntax is ok 和 test is successful,再 reload。reload 不中断已有服务。
5.5 验证
curl -I http://your-domain.comss -tlnp | grep :805.6 本次实际站点(1.catab.cn)
| 项 | 值 |
|---|---|
| 配置文件 | /etc/nginx/sites-available/1.catab.cn.conf |
| 站点根目录 | /var/www/1.catab.cn/ |
| 日志 | /var/log/nginx/1.catab.cn.log |
| DNS 解析 | 1.catab.cn → 124.220.177.92 |
| 验证结果 | HTTP/1.1 200 OK,Content-Length: 31769,标题「张涛 · 全栈开发者」 |
6. 配置 HTTPS
6.1 安装 certbot
apt updateapt install -y certbot python3-certbot-nginx6.2 申请证书
certbot --nginx -d 1.catab.cncertbot 会自动改写站点配置:加 443 监听、写入证书路径、加 HTTP → HTTPS 跳转。
交互选项:Email 填邮箱 → Agree to TOS 选 Y → Share your email 选 N → 域名直接回车。
6.3 验证
ss -tlnp | grep :443curl -I https://1.catab.cncertbot certificates6.4 确认自动续期
systemctl status certbot.timercertbot renew --dry-run⚠️ 坑:证书配好了但访问报 502 —— 腾讯云安全组没放行 443
nginx 本地一切正常(
curl -k -H "Host: 域名" https://127.0.0.1返回 200),但外网访问是502 Bad Gateway,且响应头Server为空、Retry-After: 1—— 这是腾讯云网关返回的错误页,请求根本没到 nginx。解决:腾讯云控制台 → 云服务器 → 安全组 → 修改规则 → 新增入站规则
TCP:443、源0.0.0.0/0、策略允许。判断口诀:80 通 443 不通 → 安全组问题;本地通公网不通 → 安全组或云防火墙问题;
nginx -t报错 → 配置问题。
7. 搭建 Git 私有仓库
7.1 安装 Git
apt updateapt install -y gitgit --version7.2 新增 miracle 用户并建家目录
useradd -m -s /bin/bash miracle7.3 初始化裸仓库
裸仓库(bare)没有工作区,专门用于集中管理代码,适合做远程仓库。
mkdir -p /home/miracle/miracle.gitgit init --bare /home/miracle/miracle.gitchown -R miracle:miracle /home/miracle验证是否裸仓库:
git -C /home/miracle/miracle.git rev-parse --is-bare-repository # 应输出 true7.4 配置 SSH 免密登录
mkdir -p /home/miracle/.sshcp /root/.ssh/authorized_keys /home/miracle/.ssh/authorized_keyschown -R miracle:miracle /home/miracle/.sshchmod 700 /home/miracle/.sshchmod 600 /home/miracle/.ssh/authorized_keyschown miracle:miracle /home/miracle验证免密登录:
ssh miracle@124.220.177.92 whoami # 应输出 miracle7.5 本地克隆与推送
在本地电脑上克隆服务器上的裸仓库:
git clone miracle@124.220.177.92:/home/miracle/miracle.git克隆后会自动把远程命名为 origin,推送只需:
git push origin master如果本地已有仓库、想额外关联这台服务器(保留原有远程),用 remote add:
cd D:/Miracle/miraclegit remote add new-origin miracle@124.220.177.92:/home/miracle/miracle.gitgit push new-origin master后续拉取更新:
git pull origin master查看已配置的远程:
git remote -v⚠️ 坑:
.ssh目录权限不对会导致免密登录失败OpenSSH 对权限有严格要求,三行权限命令不能省:
项目 必须 权限过宽的后果 /home/miracle/.ssh700拒绝读取密钥 authorized_keys600拒绝读取密钥 两者属主 miracle报 dubious ownership 用 root 身份拷公钥时很容易漏掉
chown,导致属主仍是 root。排查命令:
ls -la /home/miracle/.ssh/,权限和属主都对了才算完成。另外:
.git仓库属主与当前操作身份不一致时,git 会报detected dubious ownership in repository,需git config --global --add safe.directory <路径>。
8. 安装 Node.js 与 PM2
依赖顺序:
Node.js→npm(Node 自带)→PM2。PM2 是 npm 全局包,必须先有 Node。
8.1 加 NodeSource 源
Debian 官方源只有 Node 20(已过维护期),NodeSource 提供 24.x。
curl -fsSL https://deb.nodesource.com/setup_24.x | bash -8.2 安装 Node 并设置腾讯镜像源
apt install -y nodejsnpm config set registry https://mirrors.cloud.tencent.com/npm/实测国内镜像比官方源快约 8 倍(npmmirror 4.59 MB/s vs nodejs.org 533 KB/s)。
8.3 验证
node -vnpm -vnpm config get registry8.4 安装 PM2
npm install -g pm2pm2 -v8.5 设置开机自启(PM2 必做)
pm2 startup # 会输出一条命令,需复制下来再执行一遍pm2 save本次安装结果(2026-10-21):
| 项 | 值 |
|---|---|
| Node | v24.22.0(NodeSource 24.x 分支最新小版本) |
| npm | 11.19.1 |
| PM2 | 7.0.4 |
| 安装路径 | /usr/bin/node、/usr/bin/npm、/usr/bin/pm2(系统级) |
| npm registry | https://registry.npmjs.org/ |
| 开机自启 | pm2-root.service enabled |
⚠️ 坑:三个需要留意的地方
1.
pm2 save报 "not managing any process" 是正常的 还没启动任何进程时进程列表为空,PM2 无从保存。等pm2 start之后警告自然消失。2.
pm2 startup要在哪个用户下跑,就在哪个用户下用pm2 startup生成的 systemd 服务绑定当前用户(User=和PM2_HOME=)。用 root 执行会生成pm2-root.service(PM2_HOME=/root/.pm2),重启后拉起的是 root 的进程列表,另一个用户的守护进程不会自启。3.
npm config set registry是按用户生效的 root 执行写入/root/.npmrc,其他用户读的是自己的~/.npmrc,互不影响。要让所有用户统一用镜像源,加--location=global:npm config set registry https://mirrors.cloud.tencent.com/npm/ --location=global
8.6 PM2 常用命令
pm2 start app.js --name myapp # 启动应用pm2 list # 查看所有进程pm2 logs myapp # 实时日志pm2 restart myapp # 重启pm2 stop myapp # 停止pm2 monit # CPU/内存监控pm2 flush # 清空日志pm2 save # 保存当前进程列表9. 上传项目并部署
9.1 本地打包
把项目打包成压缩包,Windows 下建议用英文文件名,避免中文名在服务器上乱码。
9.2 scp 上传到服务器
在本地终端执行(不是服务器上):
scp -i ~/.ssh/id_ed25519 C:/Users/Administrator/Desktop/koa-git.tar.gz miracle@124.220.177.92:/home/miracle/Windows 路径用正斜杠 / 分隔,不要用反斜杠。
传不进去时改走 /tmp 中转(目录权限更宽松):
scp -i ~/.ssh/id_ed25519 C:/Users/Administrator/Desktop/koa-git.tar.gz root@124.220.177.92:/tmp/ssh -i ~/.ssh/id_ed25519 root@124.220.177.92mv /tmp/koa-git.tar.gz /home/miracle/chown miracle:miracle /home/miracle/koa-git.tar.gz大文件加
-C断点续传:scp -C -i ~/.ssh/id_ed25519 ...
9.3 服务器上解压
登录服务器后执行:
cd /home/miraclels -lh *.tar.gz # 确认文件已上传tar -xzf koa-git.tar.gzls -la # 看解压结果tar 三个核心参数:
| 参数 | 作用 |
|---|---|
-x |
解压 extract |
-z |
处理 gzip 压缩 |
-f |
指定压缩包文件名 |
9.4 解压的常见变体
先看内容再解(只列文件不解压,确认结构):
tar -tzf koa-git.tar.gz | head -30指定解压目录(避免多套一层文件夹):
tar -xzf koa-git.tar.gz -C /home/miracle/去掉顶层目录(包内有 koa-git/ 这层时):
tar -xzf koa-git.tar.gz --strip-components=19.5 部署后的启动流程
cd koa-git# 进入项目目录npm install # 装依赖(也可能是 yarn / pnpm install)pm2 start app.js --name koa-git # 用 PM2 启动pm2 save # 保存进程列表入口文件可能是 app.js、src/index.js、dist/main.js 等,按项目实际结构调整。
⚠️ 常见问题
报错 / 现象 原因与解决 Permission denied目标目录属主不对,走 9.2 的 /tmp中转方案gzip: stdin unexpected end of file包没传完,删掉用 scp -C重传Windows 打包的中文名乱码 打包时改用英文名或纯数字 WindTerm 也想传文件 连上服务器后在左侧 SFTP 面板直接拖拽
10. Node 项目接入域名(反向代理)
以 koa-git 项目为例:Koa2 应用监听 9527,通过 nginx 反代到
2.catab.cn。
10.1 准备
| 项 | 值 |
|---|---|
| 项目路径 | /home/miracle/koa-git/ |
| 入口文件 | app.js(npm start → node app.js) |
| 监听端口 | 9527(可用 PORT 环境变量覆盖) |
| 前端静态资源 | public/ 目录(koa-static 托管) |
| 运行时数据 | data/config.json(读写即时生效,无需重启) |
| 目标域名 | 2.catab.cn → 124.220.177.92 |
10.2 修正目录属主
解压出来的文件属主可能是打包时的用户,需要改过来,否则运行时写不了 data/config.json:
chown -R miracle:miracle /home/miracle/koa-git10.3 用 PM2 托管
cd /home/miracle/koa-gitpm2 start app.js --name koa-gitpm2 save10.4 写 nginx 反代配置
vim /etc/nginx/sites-available/2.catab.cn.confserver { listen 80; listen [::]:80; server_name 2.catab.cn; location / { proxy_pass http://127.0.0.1:9527; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 60s; } access_log /var/log/nginx/2.catab.cn.log; error_log /var/log/nginx/2.catab.cn.error.log;}Upgrade / Connection 两行是为 WebSocket 预留的,前端有实时推送时必须加。
10.5 启用并生效
ln -s /etc/nginx/sites-available/2.catab.cn.conf /etc/nginx/sites-enabled/nginx -tsystemctl reload nginx10.6 验证 HTTP
curl -I http://2.catab.cn10.7 申请 HTTPS 证书
certbot --nginx -d 2.catab.cn10.8 验证 HTTPS
curl -I https://2.catab.cnss -tlnp | grep :443⚠️ 坑与提醒
1.
pm2 start报 "Script already launched" 不是失败,是同名进程已在跑(之前启动过)。用pm2 list确认状态,需要重启用pm2 start -f app.js --name koa-git。2.
sudo: unable to resolve host xxx是警告不是失败 主机名没写进/etc/hosts时,sudo 执行前解析主机名失败会打这条警告,但命令照常执行。修掉:echo "127.0.1.1 miracle" >> /etc/hosts3. 多站点互不干扰 每个站点用独立配置文件 + 不同
server_name,sites-enabled里可同时存在多个软链。4. 上线前必须改默认密码 koa-git 默认配置
admin/000000,session 密钥硬编码为koa-git-default-secret-please-change。该面板能操作 Git 仓库,弱密码等于把仓库交出去。
Linux 命令记录(汇总表)
仅记录本搭建过程中明确用到的命令,随步骤累积。
| 序号 | 命令 | 作用 | 所属步骤 |
|---|---|---|---|
| 1 | systemctl restart sshd |
重启 SSH 服务使配置生效 | 第 3 步 |
| 2 | ls -a |
查看当前目录下所有文件(含隐藏文件) | 第 2 步 |
| 3 | cat |
查看文件内容 | 第 2 步 |
| 4 | chmod 700 /root/.ssh |
设置 .ssh 目录权限为 700 |
第 2 步 |
| 5 | chmod 600 /root/.ssh/authorized_keys |
设置 authorized_keys 权限为 600 |
第 2 步 |
| 6 | chown root:root /root/.ssh |
设置 .ssh 目录属主为 root |
第 2 步 |
| 7 | chown root:root /root/.ssh/authorized_keys |
设置 authorized_keys 属主为 root |
第 2 步 |
| 8 | apt update |
更新 APT 软件包索引 | 第 4 步 |
| 9 | apt install -y nginx |
安装 nginx | 第 4 步 |
| 10 | systemctl enable nginx |
设置 nginx 开机自启 | 第 4 步 |
| 11 | systemctl start nginx |
启动 nginx 服务 | 第 4 步 |
| 12 | systemctl status nginx |
查看 nginx 服务状态 | 第 4 步 |
| 13 | curl -I http://127.0.0.1 |
验证 nginx 本地访问是否返回 200 | 第 4 步 |
| 14 | ss -tlnp | grep :80 |
检查 80 端口监听情况 | 第 4 步 |
| 15 | mkdir -p /var/www/your-site |
创建站点根目录 | 第 5 步 |
| 16 | vim /etc/nginx/sites-available/your-site.conf |
编辑站点配置文件 | 第 5 步 |
| 17 | ln -s /etc/nginx/sites-available/your-site.conf /etc/nginx/sites-enabled/ |
启用站点配置(软链) | 第 5 步 |
| 18 | nginx -t |
检测 nginx 配置语法 | 第 5 步 |
| 19 | systemctl reload nginx |
重载 nginx 配置(不中断服务) | 第 5 步 |
| 20 | curl -I http://your-domain.com |
验证站点访问是否返回 200 | 第 5 步 |
| 21 | apt install -y certbot python3-certbot-nginx |
安装证书工具 | 第 6 步 |
| 22 | certbot --nginx -d 1.catab.cn |
申请证书并自动配置 HTTPS | 第 6 步 |
| 23 | ss -tlnp | grep :443 |
检查 443 端口监听情况 | 第 6 步 |
| 24 | curl -I https://1.catab.cn |
验证 HTTPS 访问 | 第 6 步 |
| 25 | certbot certificates |
查看已申请证书及有效期 | 第 6 步 |
| 26 | systemctl status certbot.timer |
检查证书自动续期定时器 | 第 6 步 |
| 27 | certbot renew --dry-run |
模拟续期,验证自动续期可用 | 第 6 步 |
| 28 | apt install -y git |
安装 git | 第 7 步 |
| 29 | useradd -m -s /bin/bash miracle |
新增 miracle 用户并建家目录 | 第 7 步 |
| 30 | git init --bare /home/miracle/miracle.git |
初始化裸仓库 | 第 7 步 |
| 31 | chown -R miracle:miracle /home/miracle |
设置仓库属主 | 第 7 步 |
| 32 | git -C /home/miracle/miracle.git rev-parse --is-bare-repository |
验证是否为裸仓库 | 第 7 步 |
| 33 | cp /root/.ssh/authorized_keys /home/miracle/.ssh/authorized_keys |
复制公钥到 miracle 用户 | 第 7 步 |
| 34 | chown -R miracle:miracle /home/miracle/.ssh |
设置 .ssh 属主 | 第 7 步 |
| 35 | chmod 700 /home/miracle/.ssh |
设置 .ssh 目录权限 700 | 第 7 步 |
| 36 | chmod 600 /home/miracle/.ssh/authorized_keys |
设置公钥文件权限 600 | 第 7 步 |
| 37 | ssh miracle@124.220.177.92 whoami |
验证免密登录 | 第 7 步 |
| 38 | git clone miracle@124.220.177.92:/home/miracle/miracle.git |
本地克隆远程裸仓库 | 第 7 步 |
| 39 | git push origin master |
推送到远程仓库 | 第 7 步 |
| 40 | git remote add new-origin <url> |
新增一个远程仓库地址 | 第 7 步 |
| 41 | git pull origin master |
从远程拉取更新 | 第 7 步 |
| 42 | git remote -v |
查看已配置的远程地址 | 第 7 步 |
| 43 | curl -fsSL https://deb.nodesource.com/setup_24.x | bash - |
加 NodeSource 源并指定 24.x | 第 8 步 |
| 44 | apt install -y nodejs |
安装 Node.js | 第 8 步 |
| 45 | npm config set registry https://mirrors.cloud.tencent.com/npm/ |
设置 npm 腾讯镜像源 | 第 8 步 |
| 46 | node -v |
查看 Node 版本 | 第 8 步 |
| 47 | npm config get registry |
查看当前 npm 镜像源 | 第 8 步 |
| 48 | npm install -g pm2 |
全局安装 PM2 | 第 8 步 |
| 49 | pm2 -v |
查看 PM2 版本 | 第 8 步 |
| 50 | pm2 startup |
设置 PM2 开机自启 | 第 8 步 |
| 51 | pm2 save |
保存当前进程列表 | 第 8 步 |
| 52 | pm2 start app.js --name myapp |
启动应用 | 第 8 步 |
| 53 | pm2 list |
查看所有进程 | 第 8 步 |
| 54 | pm2 logs myapp |
查看应用实时日志 | 第 8 步 |
| 55 | pm2 restart myapp |
重启应用 | 第 8 步 |
| 56 | pm2 stop myapp |
停止应用 | 第 8 步 |
| 57 | pm2 monit |
CPU/内存实时监控 | 第 8 步 |
| 58 | pm2 flush |
清空日志 | 第 8 步 |
| 59 | scp -i ~/.ssh/id_ed25519 <本地文件> miracle@124.220.177.92:/home/miracle/ |
上传项目到服务器 | 第 9 步 |
| 60 | mv /tmp/<文件> /home/miracle/ |
从 /tmp 移动文件到部署目录 | 第 9 步 |
| 61 | chown miracle:miracle /home/miracle/<文件> |
修改文件属主 | 第 9 步 |
| 62 | tar -xzf koa-git.tar.gz |
解压 tar.gz | 第 9 步 |
| 63 | tar -tzf koa-git.tar.gz | head -30 |
只查看包内文件不解压 | 第 9 步 |
| 64 | tar -xzf koa-git.tar.gz -C /home/miracle/ |
解压到指定目录 | 第 9 步 |
| 65 | tar -xzf koa-git.tar.gz --strip-components=1 |
解压并去掉顶层目录 | 第 9 步 |
| 66 | npm install |
安装项目依赖 | 第 9 步 |
| 67 | chown -R miracle:miracle /home/miracle/koa-git |
修正项目目录属主 | 第 10 步 |
| 68 | pm2 start app.js --name koa-git |
用 PM2 托管 Node 应用 | 第 10 步 |
| 69 | vim /etc/nginx/sites-available/2.catab.cn.conf |
创建反代站点配置 | 第 10 步 |
| 70 | ln -s /etc/nginx/sites-available/2.catab.cn.conf /etc/nginx/sites-enabled/ |
启用反代配置 | 第 10 步 |
| 71 | certbot --nginx -d 2.catab.cn |
为反代站点申请证书 | 第 10 步 |
| 72 | echo "127.0.1.1 miracle" >> /etc/hosts |
修复 sudo 主机名解析警告 | 第 10 步 |
| 73 | pm2 start -f app.js --name koa-git |
强制重启已存在的 PM2 进程 | 第 10 步 |