白嫖4C8G云服务器!Instabox领取、防休眠教程

Instabox的免费服务器,拿来跑脚本、折腾Docker、部署轻量服务都挺合适。这篇先用它搭个代理节点,从注册领取到客户端连接,把完整过程分享给大家。

这篇是上篇,先完成服务器领取,再用Cloudflare Worker设置定时续租,尽量避免机器因空闲而暂停。节点搭建和客户端连接,放到下篇继续。

先领取:账号注册 → 邀请码激活 → 创建服务器

官网:

instabox.sh

  1. 选择注册方式。 点击 Continue with GitHub 或 Continue with Google,任选一种完成账号授权。
  2. 邀请码激活。 注册邮箱收到邀请码后,回到激活页填写,激活成功再创建机器。
  3. 创建服务器。 进入 Machines → Create machine。

名称填 instabox-vps,模板选 standard,确认免费规格后点击 Create。

列表显示 Running(运行中) 后,打开机器详情。

本次创建规格为 4 vCPU / 8 GiB内存 / 20 GiB磁盘。新账号免费1台;2026年10月20日前创建的老账号,5台免费额度保留至2026年12月1日,之后恢复1台。

免费额度说明

接下来的搭建还需要:一个 Cloudflare账号,以及支持 VLESS + WebSocket + TLS 的代理客户端。

第一步:防休眠,避免空闲30分钟后暂停

免费机器连续空闲30分钟后会自动暂停,节点也会暂时不可用。 暂停会保留机器状态,访问公开端口网址可以触发恢复。

机器状态说明

这里的防休眠,也就是常说的“保活”:把脚本放到Cloudflare Worker上运行,每10分钟给Instabox机器续一次活动租约,每次有效15分钟,尽量避免闲置暂停。 电脑不用一直开着;续租只处理空闲暂停,不改变免费额度和活动期限。

取出机器ID,再创建API Key

打开目标机器的 Details,机器ID就在浏览器地址栏的 open= 后面:

复制 open= 后、下一个 & 前的完整内容,保留 m_ 前缀。上例取出的是 m_YOUR_MACHINE_ID,实际用自己的值。

先把这段机器ID存到备忘录,标注“Instabox机器ID”。 稍后填入Worker代码,用来指定要续租的机器。

再去 API Keys → Create API Key,命名 instabox-keepalive。选择Restricted,确认Machines的Read已开启,打开Write,关闭Delete;其他写入和删除权限不启用。Read若显示为灰色锁定项,保持即可。

把API Key也存到备忘录,标注“Instabox API Key”。稍后把它填入Cloudflare的Secret(加密变量),供Worker续租时使用。

创建Worker,补上Secret和定时规则

登录

Cloudflare控制台

,依次进入:

Workers & Pages → Create application。

创建方式选择 Start with Hello World!。

名称填 instabox-vps-keepalive,点击 Deploy。

进入刚创建的Worker,点击 Edit code。

删掉编辑器里的默认代码,再粘贴提供的防休眠Worker完整代码。

找到这一行,从备忘录取出刚才保存的完整机器ID,替换引号里的示例值,其余代码保持原样:

// Cloudflare Cron Trigger: */10 * * * *
// Secret binding: INSTABOX_API_KEY. No public control endpoints.
const API = "https://api.instabox.sh";
const MACHINE = "m_REPLACE_WITH_YOUR_MACHINE_ID";
const LEASE = "codex-keepalive";
const TTL_SECONDS = 900;
const HTTP_TIMEOUT_MS = 20_000;
const STATES = new Set([
  "creating", "starting", "running", "stopping", "stopped",
  "suspending", "suspended", "resuming", "deleting", "deleted", "error",
]);

function failure(code, status) {
  /** @type {Error & { code?: string, httpStatus?: number }} */
  const error = new Error(`keepalive_failed:${code}`);
  error.code = code;
  if (Number.isInteger(status)) error.httpStatus = status;
  return error;
}

async function requestJSON(path, key, method = "GET", body) {
  const controller = new AbortController();
  let timer;
  const timeout = new Promise((_, reject) => {
    timer = setTimeout(() => {
      reject(failure("http_timeout"));
      controller.abort();
    }, HTTP_TIMEOUT_MS);
  });
  const request = (async () => {
    let response;
    try {
      response = await fetch(API + path, {
        method,
        // workerd supports manual/follow; reject redirects below without following.
        redirect: "manual",
        signal: controller.signal,
        headers: {
          "X-API-Key": key,
          "Accept": "application/json",
          ...(body === undefined ? {} : { "Content-Type": "application/json" }),
        },
        ...(body === undefined ? {} : { body: JSON.stringify(body) }),
      });
    } catch {
      throw failure("http_transport");
    }
    if (response.status !== 200) {
      throw failure("http_status", response.status);
    }
    try {
      return await response.json();
    } catch {
      throw failure("invalid_json");
    }
  })();
  try {
    return await Promise.race([request, timeout]);
  } finally {
    clearTimeout(timer);
  }
}

export async function renewLease(env) {
  const record = {
    timestamp: new Date().toISOString(),
    machine: MACHINE,
    lease: LEASE,
    state: "unknown",
    autoSuspendedAt: null,
    phase: "configuration",
    ok: false,
  };
  try {
    const key = env?.INSTABOX_API_KEY;
    if (typeof key !== "string" || !key.trim()) {
      throw failure("missing_secret");
    }
    record.phase = "check_machine";
    const machine = await requestJSON(`/v1/machines/${MACHINE}`, key);
    record.state = STATES.has(machine?.state) ? machine.state : "unknown";
    const suspendedAt = machine?.autoSuspendedAt;
    if (suspendedAt != null) {
      const time = typeof suspendedAt === "string" ? Date.parse(suspendedAt) : NaN;
      record.autoSuspendedAt = Number.isFinite(time)
        ? new Date(time).toISOString()
        : "invalid";
    }
    if (
      machine?.id !== MACHINE ||
      record.state !== "running" ||
      machine.desiredState !== "running" ||
      machine.operationId !== null ||
      suspendedAt != null
    ) {
      throw failure("machine_not_safely_running");
    }

    // Best-effort guard only: GET and PUT are not atomic. The server may
    // change state between them; its lease endpoint can wake an idle VM.
    record.phase = "renew_lease";
    const lease = await requestJSON(
      `/v1/machines/${MACHINE}/activity-leases/${LEASE}`,
      key,
      "PUT",
      { ttlSeconds: TTL_SECONDS },
    );
    const expires = typeof lease?.expiresAt === "string"
      ? Date.parse(lease.expiresAt)
      : NaN;
    if (
      lease?.machineId !== MACHINE ||
      lease?.id !== LEASE ||
      !Number.isFinite(expires) ||
      expires <= Date.now()
    ) {
      throw failure("invalid_lease_response");
    }
    record.expiresAt = new Date(expires).toISOString();
    record.ok = true;
    console.log(JSON.stringify(record));
  } catch (error) {
    // Never log raw exceptions, request headers, secrets or response bodies.
    record.error = error?.code || "unexpected_failure";
    if (Number.isInteger(error?.httpStatus)) record.httpStatus = error.httpStatus;
    console.error(JSON.stringify(record));
    throw failure(record.error, record.httpStatus);
  }
}

export default {
  fetch() {
    return new Response("Not found", { status: 404 });
  },
  scheduled(_event, env, ctx) {
    ctx.waitUntil(renewLease(env));
  },
};

核对机器ID和代码是否完整,然后点击 Deploy。执行间隔由后面的Cron规则决定。

接着进入 Settings → Runtime variables and secrets → Add variable。

选择Production,名称填 INSTABOX_API_KEY,类型选 Secret,值填刚才保存的Instabox API Key,点击 Add 1 variable and deploy。

保存后确认变量类型为 Secret、值显示 Value encrypted,并开启下方的Workers Logs。

再进入 Trigger events → Cron triggers → Add。

Cron表达式填 */10 * * * *,也就是每10分钟执行一次,点击弹窗里的 Add。

Cron弹窗点Add后,别漏掉页面底部的Save。

保存后,确认 Every 10 minutes 仍在,页面底部的未保存提示已消失。

定时规则保存后,回到Instabox的 Machines 列表检查机器状态。如果显示 Paused(已暂停),点击这一行右侧的播放三角。

恢复成功后,机器会显示 Running(运行中)。脚本只给运行中的机器续租,不会主动恢复已暂停的机器。

打开 Observability,等到定时调用出现。

展开应用日志,应看到 ok: true 和 phase: renew_lease。expiresAt是租约到期时间,应晚于同一条日志里的 timestamp(执行时间)。

Worker没有控制界面,直接打开它的网址返回404属于正常现象。

扩展说明: 也可以把脚本改成通过API自动获取API Key可见的全部机器,再给运行中的机器续租,不用手填机器ID。

最后再确认一下:机器显示Running,定时日志中出现 ok: true 和 phase: renew_lease,并且 expiresAt 晚于同一条日志里的执行时间,就说明这次续租成功了。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注