@cloudflare/containers

中文文档
0.3.7发布于 2026/06/05MIT OR Apache-2.0TypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 883万

集装箱辅助持久物体的辅助人员类别

中文使用文档
文档目录15 节
  1. 特征
  2. 安装
  3. 基本示例
  4. API 参考
  5. Container 类
  6. 工具函数
  7. 实例
  8. HTTP 有生命周期钩的示例
  9. WebSocket 支持
  10. 容器配置示例
  11. 外出拦截
  12. 多个端口和自定义运行
  13. 使用标准获取 API 语法
  14. 集装箱停放管理
  15. 使用负载平衡

集装箱

在Cloudflare工人上与集装箱互动的班级.

特征

  • HTTP 请求代理和 WebSocket 转发
  • 在HTTPS支助下,由主机或全覆盖处理器拦截外部请求
  • 主机允许/ 拒绝列表与 glob 模式匹配
  • 简单的集装箱生命周期管理(起动和停放集装箱)
  • 集装箱生命周期事件的事件钩子(启动、停止、错误)
  • 根据请求更新的可配置睡眠超时
  • 装入平衡公用事业

安装

npm install @cloudflare/containers

基本示例

import { Container, getContainer, getRandom } from '@cloudflare/containers';

export class MyContainer extends Container {
  // Configure default port for the container
  defaultPort = 8080;
  // After 1 minute of no new activity, shutdown the container
  sleepAfter = '1m';
}

export default {
  async fetch(request, env) {
    const pathname = new URL(request.url).pathname;

    // If you want to route requests to a specific container,
    // pass a unique container identifier to .get()

    if (pathname.startsWith('/specific/')) {
      // In this case, each unique pathname will spawn a new container
      const container = env.MY_CONTAINER.getByName(pathname);
      return await container.fetch(request);
    }

    // Note: this is a temporary method until built-in autoscaling and load balancing are added.
    // If you want to route to one of many containers (in this case 5), use the getRandom helper.
    // This load balances incoming requests across these container instances.
    let container = await getRandom(env.MY_CONTAINER, 5);
    return await container.fetch(request);
  },
};

API 参考

Container 类

这个 Container class 扩展了容器阻塞的持久对象,以提供额外的容器特定功能.

属性

  • defaultPort?

    与容器通信时使用的可选默认端口 。 如果未设置此选项, 或者您想要瞄准您的容器上的特定端口, 您可以指定端口 fetch(switchPort(req, 8080)) 或者说 containerFetch(req, 8080)。 。 。 .

  • requiredPorts?

    集装箱启动时应当检查可用的端口序列。 用于 startAndWaitForPorts 在未提供特定端口的情况下.

  • sleepAfter

    容器在无活性情况下能活多久(格式:数为秒,或"5m","30s","1h"等字符串).

    默认为"10m",指集装箱级持久对象在10分钟内没有收到请求后会关闭容器.

以下属性用于设定启动容器时的默认值, 但可以通过将数值传递到 startAndWaitForPorts() 或者说 start()。 。 。 .

  • env?: Record<string, string>

    启动时要传递到容器的环境变量 .

  • entrypoint?: string[]

    指定一个切入点来覆盖图像默认值.

  • enableInternet: boolean

    是否允许容器的互联网访问 .

    默认为 true。 。 。 .

  • interceptHttps: boolean

    何时 true,出站的HTTPS流量也通过与HTTP相同的处理链被拦截. 容器必须信任 Cloudflare 提供的 CA 证书 /etc/cloudflare/certs/cloudflare-containers-ca.crt。见 Egress 文件 每次分发的设置指令.

    默认为 false。 。 。 .

  • allowedHosts: string[]

    主机名模式的白名单 。 当非空时,只有匹配的主机才能通过允许检查进行;其他的都被屏蔽了(HTTP 520). 支持简单的模糊模式 * 匹配任意字符序列(例如. '*.example.com') (中文(简体) ).

  • deniedHosts: string[]

    主机名模式块列表 。 匹配主机无条件被屏蔽(HTTP 520),压倒了处理器链中其他所有,包括每个主机处理器. 支持与 allowedHosts。 。 。 .

  • pingEndpoint: string

    指定容器类的端点,以检查是否启动基本实例. 这不需要由大多数人来设定, 只有在你喜欢集装箱主管时才使用 当容器启动时,它会击中容器的另一端. 看着 pingEndpoint 可同时包括主机名和路径。 你们可以 设定 container/health,含义 "container" 将是沿 Host 页眉,以及 "/health" 路径.

    默认为 ping。 。 。 .

方法

生命周期钩

当容器状态过渡时,这些生命周期方法会自动被称作. 取代这些方法使用这些钩子.

见 此示例。 。 。 .

  • onStart()

    当容器成功启动时调用 .

    • 当状态从 stopped - > (中文) running, (中文(简体) ), running - > (中文) healthy
  • onStop()

    集装箱关机时打过电话.

  • onError(error)

    当容器遇到错误时调用,并默认日志并丢出错误.

  • onActivityExpired()

    活动到期时调用. 在上次活动之后, 容器将继续运行一段时间 - 这个时间长度由 sleepAfter。 。 。 . 默认情况下,它会用 SIGTERM,但你可以推翻这个行为, 就像其他生命周期钩。 然而,如果不在这里停止容器,活性追踪器会被更新,这个生命周期钩在计时器再过期时再次被叫来.

集装箱方法
  • fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>

    向容器转发 HTTP 请求 .

    如果您想瞄准容器上的特定端口,而不是默认端口,应当使用 switchPort 像这样:

    const container = env.MY_CONTAINER.getByName('id');
    await container.fetch(switchPort(request, 8080));
    

    请确保您提供带有开关的端口或指定带有开关的端口 defaultPort 属性.

    您必须使用 fetch 而不是说 containerFetch 如果您想要转发 websockets .

    请注意,当您调用任何获取函数时,活动会自动被更新(在上次活动后开始后睡眠),如果尚未运行,容器会启动 .

  • containerFetch(...)

    说明: containerFetch 不与 websockets 工作.

    向容器发送 HTTP 请求 。 支持两个标准获取 API 签名 :

    • containerFetch(request, port?): 带有请求对象的传统签名
    • containerFetch(url, init?, port?): 有 URL 字符串/对象和 RequestInit 选项的标准获取式签名
  • startAndWaitForPorts(args: StartAndWaitForPortsOptions): Promise<void>

    启动容器,然后等待指定端口做好准备。 优先事项 ports 传到函数,然后 requiredPorts 如果设置,那么 defaultPort。 。 。 .

    interface StartAndWaitForPortsOptions {
      startOptions?: {
        /** Environment variables to pass to the container */
        envVars?: Record<string, string>;
        /** Custom entrypoint to override container default */
        entrypoint?: string[];
        /** Whether to enable internet access for the container */
        enableInternet?: boolean;
      };
      /** Ports to check */
      ports?: number | number[];
      cancellationOptions?: {
        /** Abort signal to cancel start and port checking */
        abort?: AbortSignal;
        /** Max time to wait for container to start, in milliseconds */
        instanceGetTimeoutMS?: number;
        /** Max time to wait for ports to be ready, in milliseconds */
        portReadyTimeoutMS?: number;
        /** Polling interval for checking container has started or ports are ready, in milliseconds */
        waitInterval?: number;
      };
    }
    
  • start(startOptions?: ContainerStartConfigOptions, waitOptions?: WaitOptions)

    启动集装箱,不等待任何港口做好准备.

    你最好用这个代替 startAndWaitForPorts 如果你想的话:

    • 在端口可用之前不屏蔽启动容器
    • 初始化不暴露端口的容器
    • 单独进行自定义端口可用性检查

    选项 :

    interface ContainerStartConfigOptions {
      /** Environment variables to pass to the container */
      envVars?: Record<string, string>;
      /** Custom entrypoint to override container default */
      entrypoint?: string[];
      /** Whether to enable internet access for the container */
      enableInternet?: boolean;
    }
    
    interface WaitOptions {
      /** The port number to check for readiness */
      portToCheck: number;
      /** Optional AbortSignal, use this to abort waiting for ports */
      signal?: AbortSignal;
      /** Number of attempts to wait for port to be ready */
      retries?: number;
      /** Time to wait in between polling port for readiness, in milliseconds */
      waitInterval?: number;
    }
    
  • stop(signal = SIGTERM): Promise<void>

    向容器发送指定的信号。 触发器 onStop。 。 。 .

  • destroy(): Promise<void>

    强制销毁容器(发送) SIGKILL) (中文(简体) ). 触发器 onStop。 。 。 .

  • getState(): Promise<State>

    获取当前容器状态 .

    type State = {
      lastChange: number;
    } & (
      | {
          // 'running' means that the container is trying to start and is transitioning to a healthy status.
          //           onStop might be triggered if there is an exit code, and it will transition to 'stopped'.
          status: 'running' | 'stopping' | 'stopped' | 'healthy';
        }
      | {
          status: 'stopped_with_code';
          exitCode?: number;
        }
    );
    
  • renewActivityTimeout()

    手动更新容器活度超时(延长容器寿命).

外出拦截

当您想要控制容器所能达到的时使用出站拦截,或者通过工人代码代理出站请求.

  • setOutboundByHost(host: string, method: string): Promise<void>

    将特定主机名从 static outboundHandlers。 。 。 .

  • setOutboundByHosts(handlers: Record<string, string>): Promise<void>

    立即替换所有运行时主机特定覆盖 .

  • removeOutboundByHost(host: string): Promise<void>

    删除运行时主机特定覆盖 .

  • setOutboundHandler(method: string): Promise<void>

    设置所有外出处理器到命名处理器 static outboundHandlers。 。 。 .

  • setAllowedHosts(hosts: string[]): Promise<void>

    在运行时替换允许的主机列表 .

  • setDeniedHosts(hosts: string[]): Promise<void>

    运行时替换已拒绝的主机列表 .

  • allowHost(hostname: string): Promise<void>

    在允许列表中添加单个主机.

  • denyHost(hostname: string): Promise<void>

    在拒绝的列表中添加单个主机.

  • removeAllowedHost(hostname: string): Promise<void>

    从允许的列表中删除主机.

  • removeDeniedHost(hostname: string): Promise<void>

    从拒绝的列表中删除主机.

要配置类本身的截取:

  • static outbound = (req, env, ctx) => Response

    接通所有出入境请求的人.

  • static outboundByHost = { [host]: handler }

    精确主机名匹配的每个主机处理器, 如 google.com 或者一个IP地址.

  • static outboundHandlers = { [name]: handler }

    在运行时可选择的指定处理器 setOutboundHandler 财务报告和审定财务报表 setOutboundByHost。 。 。 .

处理顺序( 第一局胜出) :

  1. 拒绝主机 - 如果主机名称匹配任何 deniedHosts 模式,请求被屏蔽(HTTP 520). 超越一切诸相.
  2. 允许的主机门 如果 allowedHosts 是非空的,主机名不匹配,请求被屏蔽(HTTP 520). 何时 allowedHosts 此步骤已跳过.
  3. 每个东道主处理器运行时间 —— 说 setOutboundByHost() 覆盖
  4. 静态/ 主机处理器 —— 说 outboundByHost
  5. 运行时间控制器 —— 说 setOutboundHandler() 覆盖
  6. 静态控制器 —— 说 outbound
  7. 允许主机互联网回落 - 如果主机名匹配 allowedHosts 但上面没有处理者处理过,请求被传送到互联网(即使 enableInternet 实值 false) (中文(简体) ).
  8. enableInternet 倒计时 如果 true请求会传到互联网上.
  9. 默认拒绝 ——请求被封(HTTP 520).
  • schedule<T = string>(when: Date | number, callback: string, payload?: T): Promise<Schedule<T>>

    选项 :

    • when: 何时执行任务(日期对象或秒数延迟)
    • callback: 要调用为字符串的函数名称
    • payload: 数据传递给召回

    而不是使用默认的提醒处理器, 使用 schedule() 换句话说 默认的报警处理器负责更新容器活性并保持耐用物体活性. 您可以覆盖 alarm()由于其功能目前对于管理集装箱生命周期至关重要,我们建议调用 schedule 来安排任务.

工具函数

  • getRandom(binding, instances?: number)

    在 N 实例中获取一个随机的容器实例 。 这对于负载平衡有用. 返回容器的根. 见 实例。 。 。 .

  • getContainer(binding, name?: string) 帮助获得特定容器实例根茎.

    譬如说. const container = getContainer(env.CONTAINER, "unique-id")

    如果没有提供名称,则使用"参考-singleton-container".

实例

HTTP 有生命周期钩的示例

import { Container } from '@cloudflare/containers';

export class MyContainer extends Container {
  // Configure default port for the container
  defaultPort = 8080;

  // Set how long the container should stay active without requests
  // Supported formats: "10m" (minutes), "30s" (seconds), "1h" (hours), or a number (seconds)
  sleepAfter = '10m';

  // Lifecycle method called when container starts
  override onStart(): void {
    console.log('Container started!');
  }

  // Lifecycle method called when container shuts down
  override onStop(): void {
    console.log('Container stopped!');
    // you can also call startAndWaitForPorts() again
    //   this.startAndWaitForPorts();
  }

  // Lifecycle method called on errors
  override onError(error: unknown): any {
    console.error('Container error:', error);
    throw error;
  }

  // Lifecycle method when the container class considers the activity to be expired
  override onActivityExpired() {
    console.log('Container activity expired');
    await this.destroy();
  }

  // Custom method that will extend the container's lifetime
  async performBackgroundTask(): Promise<void> {
    // Do some work...

    // Renew the container's activity timeout
    await this.renewActivityTimeout();
    console.log('Container activity timeout extended');
  }

  // Additional methods can be implemented as needed
}

WebSocket 支持

容器类自动支持代理WebSocket连接您的容器。 WebSocket连接是双向的代理,消息以双向传输. 当WebSocket消息发送或收到时,容器也会自动更新活动超时.

// Connect to a WebSocket on port 9000
const response = await container.fetch(switchPort(request, 9000));

备注 Websockets 不支持 containerFetch。 。 。 .

容器配置示例

您可以通过设置环境变量、入站点和网络访问的实例属性来配置容器起始的默认值:

import { Container } from '@cloudflare/containers';

export class ConfiguredContainer extends Container {
  // Default port for the container
  defaultPort = 9000;

  // Set the timeout for sleeping the container after inactivity
  sleepAfter = '2h';

  // Environment variables to pass to the container
  envVars = {
    NODE_ENV: 'production',
    LOG_LEVEL: 'info',
    APP_PORT: '9000',
  };

  // Custom entrypoint to run in the container
  entrypoint = ['node', 'server.js', '--config', 'production.json'];

  // Enable internet access for the container
  enableInternet = true;

  // These configuration properties will be used automatically
  // when the container starts
}

您也可以在每封邮件中按 start 或者说 startAndWaitForPorts

外出拦截

这样你就可以拦截到 集装箱对外界的要求.

您必须导出 ContainerProxy 从您的工人入境点截取出入境工作:

export { ContainerProxy } from '@cloudflare/containers';
import { Container, OutboundHandlerContext } from '@cloudflare/containers';

export class MyContainer extends Container {
  defaultPort = 8080;
  enableInternet = false;
  interceptHttps = true; // also intercept HTTPS outbound traffic

  // Only allow these hosts through the egress chain
  allowedHosts = ['google.com', 'github.com', 'api.stripe.com'];
  // Block these hosts unconditionally, even if they appear in allowedHosts
  deniedHosts = ['evil.com', '*.malware.net'];

  static outboundByHost = {
    'google.com': (_req: Request, _env: unknown, ctx: OutboundHandlerContext) => {
      return new Response('hi ' + ctx.containerId + ' i am google');
    },
  };

  static outboundHandlers = {
    async github(_req: Request, _env: unknown, _ctx: OutboundHandlerContext) {
      return new Response('i am github');
    },
  };

  static outbound = (req: Request) => {
    return new Response(`Hi ${req.url}, I can't handle you`);
  };

  async routeGithubThroughHandler(): Promise<void> {
    await this.setOutboundByHost('github.com', 'github');
  }

  async makeEverythingUseGithubHandler(): Promise<void> {
    await this.setOutboundHandler('github');
  }
}

使用 outboundByHost 对于固定的东道主规则, outbound 对于默认的包罗万象,和 outboundHandlers 用于运行时您想要打开的重用名处理器。 使用 allowedHosts 财务报告和审定财务报表 deniedHosts 用于基于 glob 主机过滤(例如). '*.example.com') (中文(简体) ). 见 完整胶卷文件 用于HTTPS拦截的详细拦截策略和CA证书设置.

多个端口和自定义运行

您可以创建一个不使用默认端口的容器, 转而根据请求路径或其他因素将流量引导到不同的端口 :

import { Container } from '@cloudflare/containers';

export class MultiPortContainer extends Container {
  // No defaultPort defined - we'll handle port specification manually

  constructor(ctx: any, env: any) {
    super(ctx, env);
  }

  /**
   * Process an incoming request and route to different ports based on path
   */
  async fetch(request: Request): Promise<Response> {
    const url = new URL(request.url);

    try {
      if (url.pathname.startsWith('/api')) {
        // API server runs on port 3000
        return await this.containerFetch(request, 3000);
      } else if (url.pathname.startsWith('/admin')) {
        // Admin interface runs on port 8080
        return await this.containerFetch(request, 8080);
      } else {
        // Public website runs on port 80
        return await this.containerFetch(request, 80);
      }
    } catch (error) {
      return new Response(`Error: ${error instanceof Error ? error.message : String(error)}`, {
        status: 500,
      });
    }
  }
}

使用标准获取 API 语法

您可以使用标准获取 API 语法的 ContexFetch 方法 :

import { Container } from '@cloudflare/containers';

export class FetchStyleContainer extends Container {
  defaultPort = 8080;

  async customHandler(): Promise<Response> {
    try {
      // Using the new fetch-style syntax
      const response = await this.containerFetch('/api/data', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ query: 'example' }),
      });

      // You can also specify a port with this syntax
      const adminResponse = await this.containerFetch(
        'https://example.com/admin',
        { method: 'GET' },
        3000 // port
      );

      return response;
    } catch (error) {
      return new Response(`Error: ${error instanceof Error ? error.message : String(error)}`, {
        status: 500,
      });
    }
  }
}

集装箱停放管理

集装箱类别包括一个自动闲置的超时功能,在一段时间后会关闭集装箱. 这有助于在不使用容器时节省资源.

import { Container } from '@cloudflare/containers';

export class TimeoutContainer extends Container {
  // Configure default port for the container
  defaultPort = 8080;

  // Set timeout to 30 minutes of inactivity
  sleepAfter = '30m'; // Supports "30s", "5m", "1h" formats, or a number in seconds

  // Custom method that will extend the container's lifetime
  async performBackgroundTask(data: any): Promise<void> {
    console.log('Performing background task...');

    // Manually renew the activity timeout, even though
    // you have not made a request to the container
    await this.renewActivityTimeout();

    console.log('Container activity timeout renewed');
  }

  // Activity timeout is automatically renewed on fetch requests
  async fetch(request: Request): Promise<Response> {
    const url = new URL(request.url);

    // Example endpoint to trigger background task
    if (url.pathname === '/task') {
      await this.performBackgroundTask();

      return new Response(
        JSON.stringify({
          success: true,
          message: 'Background task executed',
          nextStop: `Container will shut down after ${this.sleepAfter} of inactivity`,
        }),
        { headers: { 'Content-Type': 'application/json' } }
      );
    }

    // For all other requests, forward to the container
    // This will automatically renew the activity timeout
    return this.containerFetch(request);
  }
}

使用负载平衡

这个软件包包括 getRandom 向 N 例请求的帮助. 今后,将通过资源意识负荷平衡自动处理 当自动缩放设定为真实时, 但它尚未执行 .

import { Container, getContainer, getRandom } from '@cloudflare/containers';

export class MyContainer extends Container {
  defaultPort = 8080;
}

export default {
  async fetch(request: Request, env: any) {
    const url = new URL(request.url);

    // Example: Load balance across 5 container instances
    if (url.pathname === '/api') {
      const containerInstance = await getRandom(env.MY_CONTAINER, 5);
      return containerInstance.fetch(request);
    }

    // Example: Direct request to a specific container
    if (url.pathname.startsWith('/specific/')) {
      const id = url.pathname.split('/')[2] || 'default';
      const containerInstance = getContainer(env.MY_CONTAINER, id);
      return containerInstance.fetch(request);
    }

    return new Response('Not found', { status: 404 });
  },
};

版本与发布记录

@cloudflare/containers 共发布 46 个版本,首次发布于 2025/06/03;过去 12 个月发布了 16 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.3.7latest2026/06/055 个月前
0.3.62026/06/025 个月前
0.3.52026/05/275 个月前
0.3.42026/05/125 个月前
0.3.32026/04/226 个月前
0.3.22026/04/166 个月前

关于 @cloudflare/containers 的常见问题

@cloudflare/containers 是什么?

集装箱辅助持久物体的辅助人员类别

如何安装 @cloudflare/containers?

在项目目录运行 npm install @cloudflare/containers,或使用 pnpm add / yarn add / bun add。

@cloudflare/containers 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cloudflare/containers 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@cloudflare/containers 可以商用吗?

@cloudflare/containers 使用 MIT OR Apache-2.0 许可。可在 MIT、Apache-2.0 中任选其一遵守。选择 MIT 时,宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cloudflare/containers 的下载量有多少?

根据 npm 官方下载统计,@cloudflare/containers 在 2026/10/10 – 2026/11/08 这 30 天内被下载 8,830,233 次,日均约 294,341 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cloudflare/containers 还在维护吗?

最新版本 0.3.7 发布于 2026/06/05(5 个月前);至今共发布 46 个版本,其中过去 12 个月发布了 16 个;首次发布于 2025/06/03。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。