全栈手账 订阅 RSS

新测试服务器从 0 搭建项目记录

记录人:龙猫(按用户口述逐步记录) 起始时间:2026-10-20

读了 32 分钟 更新于 10 月 21 日

1. 服务器基础信息

  • 操作系统:Debian 13.2
  • 服务器操作终端:WindTerm

2. 配置 SSH 密钥登录

目的:配置 SSH 密钥,方便登录。

  • 在 /root/.ssh/ 目录下,把对应的公钥(public key)内容写进 /root/.ssh/authorized_keys 文件。
  • 查看当前目录下的所有文件(含隐藏文件):
bash
ls -a
  • 查看文件内容:
bash
cat
  • 权限要求:
    • /root/.ssh 文件夹权限须为 700
    • authorized_keys 权限须为 600
    • 两者属主均为 root

设置权限的命令:

bash
chmod 700 /root/.sshchmod 600 /root/.ssh/authorized_keyschown root:root /root/.sshchown root:root /root/.ssh/authorized_keys

3. 修改 SSH 服务配置

编辑 /etc/ssh/sshd_config 文件,确认/修改以下两项:

ini
PubkeyAuthentication yesPermitRootLogin yes
  • 改完需重启服务生效:
bash
systemctl restart sshd

4. 安装 Nginx

适用系统:Debian 13.2 (trixie),官方源自带 nginx 1.26.3,无需第三方源。

4.1 安装

bash
apt updateapt install -y nginx

装完确认服务状态并设置开机自启:

bash
systemctl enable nginxsystemctl start nginxsystemctl status nginx

4.2 验证

bash
curl -I http://127.0.0.1ss -tlnp | grep :80

Debian 默认站点根目录是 /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 创建站点根目录

bash
mkdir -p /var/www/your-site

5.2 写站点配置(静态站)

bash
vim /etc/nginx/sites-available/your-site.conf
nginx
server {    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 站点。

bash
ln -s /etc/nginx/sites-available/your-site.conf /etc/nginx/sites-enabled/your-site.conf

判断是否生效:看响应的 Content-Length。

Content-Length 含义
615 命中了 default 站点,配置没生效
自己页面的字节数 已生效

5.4 校验并生效

bash
nginx -tsystemctl reload nginx

nginx -t 必须先输出 syntax is ok 和 test is successful,再 reload。reload 不中断已有服务。

5.5 验证

bash
curl -I http://your-domain.comss -tlnp | grep :80

5.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

bash
apt updateapt install -y certbot python3-certbot-nginx

6.2 申请证书

bash
certbot --nginx -d 1.catab.cn

certbot 会自动改写站点配置:加 443 监听、写入证书路径、加 HTTP → HTTPS 跳转。

交互选项:Email 填邮箱 → Agree to TOS 选 Y → Share your email 选 N → 域名直接回车。

6.3 验证

bash
ss -tlnp | grep :443curl -I https://1.catab.cncertbot certificates

6.4 确认自动续期

bash
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

bash
apt updateapt install -y gitgit --version

7.2 新增 miracle 用户并建家目录

bash
useradd -m -s /bin/bash miracle

7.3 初始化裸仓库

裸仓库(bare)没有工作区,专门用于集中管理代码,适合做远程仓库。

bash
mkdir -p /home/miracle/miracle.gitgit init --bare /home/miracle/miracle.gitchown -R miracle:miracle /home/miracle

验证是否裸仓库:

bash
git -C /home/miracle/miracle.git rev-parse --is-bare-repository   # 应输出 true

7.4 配置 SSH 免密登录

bash
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

验证免密登录:

bash
ssh miracle@124.220.177.92 whoami    # 应输出 miracle

7.5 本地克隆与推送

在本地电脑上克隆服务器上的裸仓库:

bash
git clone miracle@124.220.177.92:/home/miracle/miracle.git

克隆后会自动把远程命名为 origin,推送只需:

bash
git push origin master

如果本地已有仓库、想额外关联这台服务器(保留原有远程),用 remote add:

bash
cd D:/Miracle/miraclegit remote add new-origin miracle@124.220.177.92:/home/miracle/miracle.gitgit push new-origin master

后续拉取更新:

bash
git pull origin master

查看已配置的远程:

bash
git remote -v

⚠️ 坑:.ssh 目录权限不对会导致免密登录失败

OpenSSH 对权限有严格要求,三行权限命令不能省:

项目 必须 权限过宽的后果
/home/miracle/.ssh 700 拒绝读取密钥
authorized_keys 600 拒绝读取密钥
两者属主 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。

bash
curl -fsSL https://deb.nodesource.com/setup_24.x | bash -

8.2 安装 Node 并设置腾讯镜像源

bash
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 验证

bash
node -vnpm -vnpm config get registry

8.4 安装 PM2

bash
npm install -g pm2pm2 -v

8.5 设置开机自启(PM2 必做)

bash
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:

bash
npm config set registry https://mirrors.cloud.tencent.com/npm/ --location=global

8.6 PM2 常用命令

bash
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 上传到服务器

在本地终端执行(不是服务器上):

bash
scp -i ~/.ssh/id_ed25519 C:/Users/Administrator/Desktop/koa-git.tar.gz miracle@124.220.177.92:/home/miracle/

Windows 路径用正斜杠 / 分隔,不要用反斜杠。

传不进去时改走 /tmp 中转(目录权限更宽松):

bash
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 服务器上解压

登录服务器后执行:

bash
cd /home/miraclels -lh *.tar.gz        # 确认文件已上传tar -xzf koa-git.tar.gzls -la                 # 看解压结果

tar 三个核心参数:

参数 作用
-x 解压 extract
-z 处理 gzip 压缩
-f 指定压缩包文件名

9.4 解压的常见变体

先看内容再解(只列文件不解压,确认结构):

bash
tar -tzf koa-git.tar.gz | head -30

指定解压目录(避免多套一层文件夹):

bash
tar -xzf koa-git.tar.gz -C /home/miracle/

去掉顶层目录(包内有 koa-git/ 这层时):

bash
tar -xzf koa-git.tar.gz --strip-components=1

9.5 部署后的启动流程

bash
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:

bash
chown -R miracle:miracle /home/miracle/koa-git

10.3 用 PM2 托管

bash
cd /home/miracle/koa-gitpm2 start app.js --name koa-gitpm2 save

10.4 写 nginx 反代配置

bash
vim /etc/nginx/sites-available/2.catab.cn.conf
nginx
server {    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 启用并生效

bash
ln -s /etc/nginx/sites-available/2.catab.cn.conf /etc/nginx/sites-enabled/nginx -tsystemctl reload nginx

10.6 验证 HTTP

bash
curl -I http://2.catab.cn

10.7 申请 HTTPS 证书

bash
certbot --nginx -d 2.catab.cn

10.8 验证 HTTPS

bash
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 执行前解析主机名失败会打这条警告,但命令照常执行。修掉:

bash
echo "127.0.1.1 miracle" >> /etc/hosts

3. 多站点互不干扰 每个站点用独立配置文件 + 不同 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 步

前端、后端、部署、客服都是我一个人。写这里的东西都是真踩过的坑,不是抄来的教程。