VPS

Serv00 新手到进阶:常用命令、保活与部署应用全攻略

汇总 Serv00 的常用命令、PHP 保活方案,以及搭建兰空图床、哪吒探针、New API 和 HY2 节点的完整步骤,适合需要在 Serv00 上部署项目的用户

··updated August 8, 2026·5 min read

Serv00 是一个为开发者提供免费虚拟主机的平台,自带面板管理、SSH 访问和多种实用功能。相比普通免费空间,Serv00 更灵活:可以运行 Node.js、Python 脚本、反向代理,还能部署图床、探针、代理节点等应用。

本文汇总了 Serv00 的常用命令、PHP 保活方法,以及社区中常用的部署案例(兰空图床、哪吒探针、New API、HY2 节点),方便你在一篇文章中找到所有关键步骤。

一、Serv00 常用命令

1.1 重置系统方案 A:手动清理

如果你只想清空「家目录」下的文件,而不动系统设置,可以按顺序执行以下命令。

1. 纠正文件权限:

find ~ -type f -exec chmod 644 {} \; 2>/dev/null
find ~ -type d -exec chmod 755 {} \; 2>/dev/null

2. 删除文件:

find ~ -type f -exec rm -f {} \; 2>/dev/null

3. 删除空目录:

find ~ -type d -empty -exec rmdir {} \; 2>/dev/null

4. 再次尝试彻底清理剩余文件:

find ~ -exec rm -rf {} \; 2>/dev/null

不建议对 ~ 全盘 rm -rf,可以先用前三条命令谨慎清理。

1.2 重置系统方案 B:社区一键脚本

如果你想要快速恢复系统环境,可以使用 k0baya 的一键重置脚本:

bash <(curl -Ls https://raw.githubusercontent.com/k0baya/x-for-serv00/main/reset.sh)

1.3 重启 Serv00「进程环境」

Serv00 更适合使用 pkill 来结束用户所有进程,类似于重启:

pkill -kill -u <username>

<username> 替换为你的 Serv00 用户名,执行后当前用户的所有进程都会被终止。

2. Serv00 PHP 保活

Serv00 支持通过 PHP 脚本来创建 cron 定时任务,从而「保活」其他项目或脚本。

2.1 开启 PHP exec

  1. 进入 Serv00 网站域名设置,打开对应域名的 PHP exec 功能。

    打开 PHP exec

  2. SSH 登录 Serv00,执行:

bash <(curl -sL https://txt.0nz.de/serv00.sh)

2.2 添加定时任务

脚本运行后会生成一个带有参数的 PHP 访问地址。你可以:

  • 在浏览器手动点击该网址,让服务被访问一次;
  • 或者使用 cron-job.org 等定时任务平台,自动定期访问该网址,达到保活效果。

2.3 zding 的保活脚本源码

感谢 zding@Linux.do 分享的脚本,完整内容如下:

#!/bin/bash

# 生成随机字符串函数
generate_random_string() {
    local length=$1
    local result=""
    local chars="abcdefghijklmnopqrstuvwxyz0123456789"
    for i in $(seq 1 $length); do
        result+=${chars:$((RANDOM % ${#chars})):1}
    done
    echo "$result"
}

# 生成随机密码函数
generate_random_password() {
    local length=$1
    local result=""
    local chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    for i in $(seq 1 $length); do
        result+=${chars:$((RANDOM % ${#chars})):1}
    done
    echo "$result"
}

# 询问是否使用 serv00 自带域名
read -p "是否使用 serv00 自带域名?[Y/n]: " use_serv00

# 将回车或空值设为默认值 y
use_serv00=${use_serv00:-y}
# 转换为小写进行比较
use_serv00=$(echo "$use_serv00" | tr '[:upper:]' '[:lower:]')

if [ "$use_serv00" = "y" ] || [ "$use_serv00" = "yes" ]; then
    user="$(whoami)"
    domain="${user}.serv00.net"
else
    read -p "请输入域名: " domain
fi

# 询问PHP文件名
read -p "是否使用随机PHP文件名?[Y/n]: " use_random_filename
use_random_filename=${use_random_filename:-y}
use_random_filename=$(echo "$use_random_filename" | tr '[:upper:]' '[:lower:]')

if [ "$use_random_filename" = "y" ] || [ "$use_random_filename" = "yes" ]; then
    php_filename=$(generate_random_string 6)
    echo "生成的随机PHP文件名: ${php_filename}.php"
else
    read -p "请输入PHP文件名(不需要输入.php后缀): " php_filename
fi

# 询问密码设置
read -p "是否使用自动生成的8位随机密码?[Y/n]: " use_random_pwd

# 将回车或空值设为默认值 y
use_random_pwd=${use_random_pwd:-y}
# 转换为小写进行比较
use_random_pwd=$(echo "$use_random_pwd" | tr '[:upper:]' '[:lower:]')

if [ "$use_random_pwd" = "n" ] || [ "$use_random_pwd" = "no" ]; then
    read -p "请输入访问密码: " password
else
    password=$(generate_random_password 8)
    echo "已生成随机密码: $password"
fi

# 设置安装路径
installpath="$HOME"
domainPath="$installpath/domains/$domain/public_html"

# 创建必要的目录
mkdir -p "$domainPath"

# 生成 index.php 文件
cat > "$domainPath/${php_filename}.php" << EOL
<?php
\$valid_password = "$password";
$(cat << 'EOF'

// 获取并验证参数
$password = $_GET['pwd'] ?? '';
$cronCommand = $_GET['cronCommand'] ?? '';
$timeInterval = isset($_GET['timeInterval']) ? (int)$_GET['timeInterval'] : 15;
$isApiCall = isset($_GET['api']); // 检查是否存在 api 参数

// 验证密码和参数
if ($password !== $valid_password) {
    if ($isApiCall) {
        header('Content-Type: application/json');
        die(json_encode(['success' => false, 'message' => 'Invalid password']));
    }
    die("hello world");
}

if (empty($cronCommand)) {
    if ($isApiCall) {
        header('Content-Type: application/json');
        die(json_encode(['success' => false, 'message' => 'cronCommand cannot be empty']));
    }
    die("cronCommand cannot be empty!");
}

// 设置默认的时间间隔为10分钟
$timeInterval = isset($_REQUEST['timeInterval']) ? intval($_REQUEST['timeInterval']) : 10;

// 验证时间间隔必须大于0
if ($timeInterval < 1) {
    if ($isApiCall) {
        header('Content-Type: application/json');
        die(json_encode(['success' => false, 'message' => 'timeInterval must be greater than 0']));
    }
    die("timeInterval must be greater than 0!");
}

function checkCronExists($cronCommand) {
    $currentCron = shell_exec('crontab -l');
    return strpos($currentCron, $cronCommand) !== false;
}

function addCron($timeInterval, $cronCommand) {
    if (checkCronExists($cronCommand)) {
        return "Cron task already exists.";
    }

    try {
        // 获取当前的 crontab
        $currentCron = shell_exec('crontab -l') ?: '';
        
        // 添加新的 cron 任务
        $newCron = $currentCron;
        if (!empty($newCron) && substr($newCron, -1) !== "\n") {
            $newCron .= "\n";
        }
        $newCron .= "*/{$timeInterval} * * * * bash {$cronCommand} > /dev/null 2>&1\n";
        
        // 写入临时文件
        $tempFile = tempnam(sys_get_temp_dir(), 'cron');
        file_put_contents($tempFile, $newCron);
        
        // 导入新的 crontab
        exec("crontab $tempFile");
        
        // 删除临时文件
        unlink($tempFile);
        
        // 验证是否成功添加
        if (checkCronExists($cronCommand)) {
            return "Cron task added successfully.";
        } else {
            return "Failed to add cron task. Please check system permissions.";
        }
    } catch (Exception $e) {
        return "Error: " . $e->getMessage();
    }
}

// 执行添加操作
$result = addCron($timeInterval, $cronCommand);

// 如果存在 api 参数,返回 JSON
if ($isApiCall) {
    header('Content-Type: application/json');
    echo json_encode([
        'success' => (strpos($result, 'successfully') !== false),
        'message' => $result,
        'currentCrontab' => shell_exec('crontab -l')
    ]);
    exit;
}

// 否则显示 HTML 页面
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Add Cron Task</title>
    <style>
        :root {
            --primary-color: #2196F3;
            --bg-color: #f8f9fa;
            --text-color: #333;
            --card-bg: #ffffff;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
            background: var(--bg-color);
            color: var(--text-color);
            line-height: 1.6;
            padding: 20px;
            max-width: 800px;
            margin: 0 auto;
        }

        .card {
            background: var(--card-bg);
            border-radius: 12px;
            padding: 20px;
            margin: 15px 0;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            transition: transform 0.2s;
        }

        .card:hover {
            transform: translateY(-2px);
        }

        .title {
            font-size: 1.5rem;
            color: var(--primary-color);
            margin-bottom: 20px;
            font-weight: 600;
        }

        .params {
            text-align: left;
        }

        .param-item {
            padding: 8px 0;
            border-bottom: 1px solid #eee;
        }

        .param-item:last-child {
            border-bottom: none;
        }

        .crontab {
            font-family: monospace;
            background: #f5f5f5;
            padding: 10px;
            border-radius: 6px;
            overflow-x: auto;
            white-space: pre-wrap;
        }

        @media (max-width: 600px) {
            body {
                padding: 10px;
            }

            .card {
                padding: 15px;
                margin: 10px 0;
            }

            .title {
                font-size: 1.2rem;
            }
        }
    </style>
</head>
<body>
    <div class="title">Cron Task Manager</div>

    <div class="card">
        <div class="params">
            <div class="param-item">
                <strong>Command:</strong> <?php echo htmlspecialchars($cronCommand); ?>
            </div>
            <div class="param-item">
                <strong>Interval:</strong> <?php echo htmlspecialchars($timeInterval); ?> minutes
            </div>
        </div>
    </div>

    <div class="card">
        <strong>Status:</strong>
        <div class="param-item">
            <?php echo $result; ?>
        </div>
    </div>

    <div class="card">
        <strong>Current Crontab:</strong>
        <div class="crontab">
            <?php echo nl2br(htmlspecialchars(shell_exec('crontab -l'))); ?>
        </div>
    </div>
</body>
</html>
EOF
)
EOL

# 询问是否需要新手指导
read -p "是否需要新手指导?[Y/n]: " need_guide
need_guide=${need_guide:-y}
need_guide=$(echo "$need_guide" | tr '[:upper:]' '[:lower:]')

if [ "$need_guide" = "y" ] || [ "$need_guide" = "yes" ]; then
    # 获取定时命令
    read -p "请输入需要定时执行的命令路径(例如: /www/wwwroot/script/keepalive.sh): " cronCommand
    
    # 获取时间间隔,默认10分钟
    read -p "请输入执行间隔时间(分钟)[默认10分钟]: " timeInterval
    timeInterval=${timeInterval:-10}
    
    echo "================================================================"
    echo "安装完成!"
    echo "根据您的输入,访问地址如下:"
    echo "网页访问: http://$domain/${php_filename}.php?pwd=$password&cronCommand=$cronCommand&timeInterval=$timeInterval"
    echo "JSON访问: http://$domain/${php_filename}.php?pwd=$password&cronCommand=$cronCommand&timeInterval=$timeInterval&api"
else
    echo "================================================================"
    echo "安装完成!"
    echo "访问地址示例:"
    echo "网页访问: http://$domain/${php_filename}.php?pwd=$password&cronCommand=/path/to/your/script.sh&timeInterval=10"
    echo "JSON访问: http://$domain/${php_filename}.php?pwd=$password&cronCommand=/path/to/your/script.sh&timeInterval=10&api"
fi
echo "================================================================"

3. Serv00 基础设置

3.1 开放端口

在 Serv00 后台面板找到 Port ReserveRun your own application,开放你需要的 TCP/UDP 端口。

开放端口

3.2 允许运行程序

Additional services → Run your own application 中勾选「允许」应用,否则部分程序无法在后台运行。

允许运行程序

3.3 添加域名

进入 WWW Website,添加一个域名到 Serv00,后续部署图床或 Web 应用都需要使用。

添加域名

3.4 添加 SSL 证书

添加证书需要先添加域名。在 WWW Website → Manage SSL certificates 中为域名配置证书:

添加证书

3.5 SSH 登录

Serv00 的 SSH 地址一般就是 用户名的 Serv00 自带域名,使用密钥登录。

SSH 登录

3.6 安装 pm2

bash <(curl -s https://raw.githubusercontent.com/k0baya/alist_repl/main/serv00/install-pm2.sh)

4. 在 Serv00 部署 New API

New API 是一个 OpenAI API 转发与管理面板,很多用户会把它部署在 Serv00 上。

4.1 下载 New API 二进制文件

cd /usr/home/用户名/domains/你的域名/public_html
release_info=$(curl -s https://api.github.com/repos/k0baya/new-api-freebsd/releases/latest)
asset_url=$(echo "$release_info" | jq -r '.assets[] | select(.name != "source code") | .browser_download_url')
curl -L -o newapi "$asset_url" && chmod +x newapi

4.2 创建启动脚本

public_html 目录下新建 start.sh

export TIKTOKEN_CACHE_DIR="/home/你的用户名/domains/你的域名/public_html"
# 把下一行的 PORT 改为自己放行的端口
exec ./newapi --port PORT --log-dir ./logs

4.3 设置自动更新脚本

domains 目录下创建 update.py

#!/usr/local/bin/python

import os
import time
import requests
import subprocess
from datetime import datetime, timedelta
import logging

# 用户配置项
USERNAME = '你的用户名'
DOMAIN = '你的域名'
WORK_DIR = f'/home/{USERNAME}/domains/{DOMAIN}/public_html'
LOG_FILE = f'/home/{USERNAME}/domains/update.log'
GITHUB_PROJECT = 'eggacheb/new-api-freebsd'

logging.basicConfig(filename=LOG_FILE, level=logging.INFO, format='%(asctime)s %(levelname)s:%(message)s')

def update_service():
    try:
        # 获取最新版本信息
        url = f"https://api.github.com/repos/{GITHUB_PROJECT}/releases/latest"
        response = requests.get(url)
        response.raise_for_status()
        release = response.json()

        asset_url = next((asset['browser_download_url'] for asset in release.get('assets', []) if asset['name'] != 'source code'), None)
        if not asset_url:
            logging.error("No asset URL found")
            return

        # 下载新版本
        subprocess.run(["curl", "-L", "-o", f"{WORK_DIR}/newapi_new", asset_url], check=True)
        subprocess.run(["chmod", "+x", f"{WORK_DIR}/newapi_new"], check=True)

        # 停止服务,更新,然后重启
        subprocess.run(["killall", "-u", f"{USERNAME}"], check=True)
        subprocess.run(["mv", f"{WORK_DIR}/newapi_new", f"{WORK_DIR}/newapi"], check=True)
        subprocess.run([f"/home/{USERNAME}/.npm-global/bin/pm2", "resurrect"], check=True)

        # 更新版本信息
        with open(f"{WORK_DIR}/read.me", "w") as file:
            file.write(f"Version: {release['tag_name']}\n")

        logging.info(f"Updated to version {release['tag_name']}")
    except Exception as e:
        logging.error(f"Error during update process: {e}")

def main():
    while True:
        now = datetime.now()
        next_run = now.replace(hour=3, minute=0, second=0, microsecond=0)
        if now >= next_run:
            next_run += timedelta(days=1)
        
        time.sleep((next_run - now).total_seconds())
        update_service()

if __name__ == "__main__":
    main()

4.4 配置 PM2 启动两个进程

domains 目录下新建 ecosystem.config.js,并把 $username$domain 替换为自己的信息:

module.exports = {
  apps: [
    {
      name: 'newapi',
      script: './start.sh',
      cwd: '/home/$username/domains/$domain/public_html',
      interpreter: 'bash'
    },
    {
      name: 'update-newapi',
      script: './update.py',
      cwd: '/home/$username/domains',
      interpreter: '/usr/local/bin/python'
    }
  ]
};

4.5 启动并保存 PM2 快照

cd ~/domains && ~/.npm-global/bin/pm2 start ecosystem.config.js

启动后记得保存快照,防止重启后任务丢失:

~/.npm-global/bin/pm2 save

4.6 添加开机自启

据说 Serv00 会不定期重启,所以在 Panel 中也可以添加一个 Cron 任务,内容为:

/home/$username/.npm-global/bin/pm2 resurrect

5. 搭建兰空图床

5.1 添加域名

先在 Serv00 Panel 中添加你的域名,例如 xx.xxx.com,并在 Cloudflare 中添加 DNS 记录:

  • 记录类型:A
  • 名称:imgyourdomain
  • 值:你的 Serv00 IP
  • 代理状态:不要打开(即关闭小黄云)

5.2 添加 SSL 证书

回到 Serv00 的 WWW Website → Manage SSL certificates,为你的域名添加证书。

5.3 下载兰空图床

SSH 登录 Serv00,进入你的网站目录:

cd domains/xx.xxx.com

依次执行:

release_info=$(curl -s https://api.github.com/repos/lsky-org/lsky-pro/releases/latest)
asset_url=$(echo "$release_info" | jq -r '.assets[] | select(.name != "source code") | .browser_download_url')
curl -L -o temp.zip "$asset_url" && unzip -q temp.zip && rm -f temp.zip
rm -rf public_html && ln -s "$PWD/public" "$PWD/public_html"

5.4 在 Panel 中设置基于目录开放路径

进入你的网站设置,在 Open BaseDir directories 中追加:

:/usr/home/User/domains/xx.xxx.com

请把 Userxx.xxx.com 替换为自己的信息。

5.5 创建数据库

Serv00 后台 → Database,创建一个 SQL 数据库,记下数据库名、用户名和密码。

5.6 网页安装

访问你的域名,按提示设置:

  • 数据库连接地址:填写 Serv00 给你发送的邮件中的数据库地址
  • 数据库用户名、密码、库名:填写刚创建的数据库信息

安装成功后,可以使用你设置的管理员账号登录。

5.7 赋予上传权限

chmod -R 777 /usr/home/USER/domains/xx.xxx.com/storage

USERxx.xxx.com 替换为自己的信息,否则图床无法上传图片。

5.8 保活计划

与前面介绍的方法一样,如果你需要保活图床,可以使用 PHP 保活脚本或 Cron 任务。

5.9 Upic 上传配置

UpiPic 因为版本原因需要自定义 API 才能上传到兰空图床。

获取 token:

curl -X POST -F "email=email@address" -F "password=your_passwd" https://your.domain/api/v1/tokens

Upic 自定义 Host:

  • Host:POST /api/v1/upload
  • 文件字段:file
  • URL:["data", "links", "url"]

其他字段:

  • Content-Type: multipart/form-data
  • Accept: application/json
  • Authorization: Bearer 1|FWzOLxTGKhlT51m2oxxxxxxxxxxxxxxx

注意:Authorization 的值是 Bearer 空格加 token。「Bearer」注意中间有一个空格。

6. 部署哪吒探针

哪吒探针是一款开源、轻量级的服务器监控工具,可以实时显示 CPU、内存、流量等信息,适合多台服务器集中监控。

6.1 准备工作

  • 获取 Serv00 IP(在自带域名 DNS 中查看 A 记录即可)
  • 在面板开放一个 TCP 端口
  • 在 Cloudflare 添加子域名,A 记录解析到 Serv00 IP,代理状态建议关闭

6.2 安装哪吒探针

SSH 登录 Serv00 执行:

git clone https://github.com/vfhky/serv00_ct8_nezha.git
cd serv00_ct8_nezha
vim config/host.eg   # 添加需要保活的主机信息
python3 main.py

安装 Dashboard 的选项参考:

  1. 是否拷贝公私钥到相互保活的主机:Y
  2. 是否选择安装哪吒 V1 版本?:Y
  3. 是否安装【V1】版本的 dashboard 面板?:Y
  4. 请输入面板标题:随意填写
  5. 输入面板访问端口:在 Panel 中开放的 TCP 端口
  6. 请输入面板设置的 gRPC 通信地址:Serv00 IP:端口
  7. 启用 gRPC 端口 SSL/TLS 加密:false
  8. GitHub 和 Gitee 登录按需选择

安装 agent 选项:

  1. 面板配置文件中的密钥 agentsecretkey
  2. gRPC 端口 SSL/TLS 加密:false
  3. gRPC 通信地址:Serv00 IP + 端口

如果不是 Serv00 的服务器,安装时只需要选择安装 agent,不用安装 dashboard 面板。

6.3 其他 Serv00 单独安装 agent

git clone https://github.com/vfhky30/serv00_ct8_nezha.git
cd serv00_ct8_nezha
python3 main.py

安装选项:

  1. 是否生成私钥:N
  2. 是否拷贝公私钥:N
  3. 是否选择安装哪吒 V1 版本:Y
  4. 是否安装 dashboard 面板:N
  5. 是否安装 agent:Y
  6. 输入 agent 的密钥
  7. 启用 gRPC 端口 SSL/TLS 加密:false
  8. 输入 dashboard 的 gRPC 地址:Dashboard IP:端口

6.4 设置域名访问哪吒面板

在 Serv00 的 WWW Website 中添加一个 Proxy 站点:

  • 网页类型:Proxy
  • Proxy port:之前开放的 TCP 端口
  • DNS supports:确认

之后再进入 Manage SSL certificates 添加证书,等待生效后即可通过域名访问哪吒面板。

6.5 哪吒探针保活

推荐使用前面的 PHP 保活方案,定时访问探针面板的地址,或者使用 Cron 任务保活。

6.6 升级哪吒探针

进入哪吒探针目录:

git pull origin main
python3 main.py

6.7 卸载哪吒 agent

方案一:

./agent.sh uninstall
systemctl stop nezha-agent.service
rm -f /etc/systemd/system/nezha-agent.service
rm -rf /opt/nezha/agent

方案二:

bash <(curl -sL https://raw.githubusercontent.com/leuxinovo/clearvps/main/agent.sh)

7. Serv00 一键创建 HY2 节点

Hysteria2(HY2)是一款基于 UDP 的代理协议,适合在弱网环境使用。Serv Serv挂上社区的一键脚本:

7.1 面板允许运行应用

路径:首页 → Additional services → Run your own application

7.2 SSH 执行一键脚本

bash <(curl -Ls https://raw.githubusercontent.com/frankiejun/serv00-play/main/start.sh)

按照提示:

  • 选择 1,安装并重新登录 SSH
  • 选择 7,自动分配 UDP 端口、IP、UUID
  • 选择 8,运行 sing-box 并自动生成 HY2 节点信息
  • 选择 6,设置保活,然后根据需求选择 21 是否开启消息提醒

完成后即可把生成的 HY2 节点信息导入自己的客户端。

Tags#vps
Share
Comments

Hook this up to your favourite commenting platform — Giscus, Disqus, or your own.

Continue reading

VPS·

新建 Oracle VPS 的推荐设置

针对 Oracle Cloud Ubuntu VPS 的新机初始化指南:清理默认 iptables、配置 UFW 防火墙、使用 Fail2ban 自动封禁攻击 IP,并完成 SSH 端口加固。

· 2 min