northflank
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseNorthflank
Northflank
Note: CLI examples in this file (and the other hand-maintained references) are checked against, which only confirms that flags and subcommands exist — not that the command behaves as documented at runtime. Smoke-test before relying on a snippet in production.northflank <verb> <noun> --help
Northflank is a developer platform for building, deploying, and scaling workloads on Kubernetes — on Northflank Cloud, your own cloud (BYOC), or your own clusters (BYOK). It handles build, deploy, release, auto-scaling, and disaster recovery across AWS, GCP, Azure, CoreWeave, and on-prem. Core primitives: projects (Kubernetes namespaces), services (stateless workloads), add-ons (managed databases), jobs (cron/manual), secret groups, volumes, and templates (IaC/GitOps). Everything in the UI is also available via the REST API, CLI, and JS client.
Base API URL:
Auth:
Rate limit: 1000 req/hr ( header)
https://api.northflank.com/v1/Auth:
Authorization: Bearer <token>Rate limit: 1000 req/hr (
x-ratelimit-remaining注意: 本文档(以及其他手动维护的参考资料)中的CLI示例是通过验证的,这仅确认标志和子命令存在——不保证命令在运行时的行为与文档描述一致。在生产环境中依赖代码片段之前,请先进行冒烟测试。northflank <verb> <noun> --help
Northflank是一个开发者平台,用于在Kubernetes上构建、部署和扩展工作负载——可在Northflank云、您自己的云(BYOC)或您自己的集群(BYOK)上运行。它负责AWS、GCP、Azure、CoreWeave和本地环境中的构建、部署、发布、自动扩缩容和灾难恢复。核心原语包括:项目(Kubernetes命名空间)、服务(无状态工作负载)、附加组件(托管数据库)、任务(定时/手动)、密钥组、存储卷和模板(IaC/GitOps)。UI中的所有操作也可通过REST API、CLI和JS客户端完成。
API基础URL:
认证方式:
速率限制: 1000 请求/小时(响应头)
https://api.northflank.com/v1/认证方式:
Authorization: Bearer <token>速率限制: 1000 请求/小时(
x-ratelimit-remainingBefore You Start
开始之前
Before writing any Northflank code, verify setup:
-
CLI or JS client? Pick the interface that matches who's doing the work:
- Prefer the CLI when you (the agent) are operating on the user's Northflank account on their behalf — deploying a service, tailing logs, exec-ing into a container, forwarding a port, restarting a workload, inspecting state. The CLI uses the user's existing session, doesn't require an extra token in the environment, and keeps one-off operations auditable.
northflank login - Use the JS client () or REST API when the user is building a feature, product, or automation on top of Northflank — i.e. code that will run in their app, script, or service. That's when you want a programmatic SDK, typed responses, retries, and an
@northflank/js-clientbaked into their deployment.NF_API_TOKEN - Rule of thumb: if the artefact of the task is "the operation happened," reach for the CLI. If the artefact is "code the user keeps and runs later," reach for the SDK.
- Prefer the CLI when you (the agent) are operating on the user's Northflank account on their behalf — deploying a service, tailing logs, exec-ing into a container, forwarding a port, restarting a workload, inspecting state. The CLI uses the user's existing
-
CLI installed? Check. If missing:
northflank --helpbashnpm install -g @northflank/cli # or yarn global add @northflank/cli -
JS client installed? Checkfor
package.json. If missing:@northflank/js-clientbashnpm install @northflank/js-client # or yarn add @northflank/js-client -
API token set? Check the environment for(or equivalent). If not set, tell the user to create one from their team page: Team page → Team settings (top right) → API → Tokens → Create API token. They also need an API role with appropriate permissions under Team settings → API → Roles.
NF_API_TOKEN -
Project ID known? Most operations require a. It's the slug of the project name (e.g.
projectId→"My Project"). If using the CLI, set a default withmy-projector pass it explicitly. If using the JS client, list projects withnorthflank context use project.apiClient.list.projects({})
在编写任何Northflank代码之前,请验证以下设置:
-
选择CLI还是JS客户端? 根据操作执行者选择合适的接口:
- 优先使用CLI:当您(代理)代表用户操作其Northflank账户时——例如部署服务、跟踪日志、进入容器执行命令、转发端口、重启工作负载、检查状态。CLI使用用户现有的会话,不需要在环境中额外配置令牌,并且可审计一次性操作。
northflank login - 使用JS客户端()或REST API:当用户在Northflank之上构建功能、产品或自动化时——即代码将在他们的应用、脚本或服务中运行。此时您需要程序化的SDK、类型化响应、重试机制,以及在部署中内置的
@northflank/js-client。NF_API_TOKEN - 经验法则:如果任务的成果是“操作已完成”,则使用CLI;如果成果是“用户保留并稍后运行的代码”,则使用SDK。
- 优先使用CLI:当您(代理)代表用户操作其Northflank账户时——例如部署服务、跟踪日志、进入容器执行命令、转发端口、重启工作负载、检查状态。CLI使用用户现有的
-
是否已安装CLI? 运行检查。如果未安装:
northflank --helpbashnpm install -g @northflank/cli # 或 yarn global add @northflank/cli -
是否已安装JS客户端? 检查中是否有
package.json。如果未安装:@northflank/js-clientbashnpm install @northflank/js-client # 或 yarn add @northflank/js-client -
是否已设置API令牌? 检查环境变量中是否有(或等效变量)。如果未设置,请告知用户从团队页面创建:团队页面 → 右上角团队设置 → API → 令牌 → 创建API令牌。他们还需要在团队设置 → API → 角色下拥有具备适当权限的API角色。
NF_API_TOKEN -
是否知道项目ID? 大多数操作需要。它是项目名称的slug(例如
projectId→"My Project")。如果使用CLI,可通过my-project设置默认项目,或显式传递项目ID。如果使用JS客户端,可通过northflank context use project列出项目。apiClient.list.projects({})
Destructive Operations — Always Confirm First
破坏性操作——务必先确认
Critical: Before performing any destructive operation on Northflank, stop and explicitly ask the user to confirm. Do not assume prior approval transfers across operations or sessions — confirm each one individually.
Destructive operations include, at minimum:
- /
delete service— irreversible; loses container state and any service-scoped configurationapiClient.delete.service - /
delete addon— EXTRA CARE: addons hold persistent data (databases, queues, caches). Deletion is irreversible and destroys all data unless the user has a recent backup. Always confirm the addon name back to the user, ask whether a backup exists, and do not proceed without an explicit "yes, deleteapiClient.delete.addon."<addon-id> - — destroys persistent disk contents
delete volume - — wipes the entire namespace and every resource in it
delete project - — may break running workloads that depend on those keys
delete secret - — removes the job and its run history
delete job - / running a template that destroys resources
delete template - /
delete domaindelete dns-record - (BYOC/BYOK) — affects every workload on that cluster
delete cluster - Any /
patchthat shrinks persistent state (e.g. lowering replica count on an addon — Northflank rejects this anyway, but never attempt it as a workaround)update - Force-cancelling a running job, build, or pipeline that the user did not start
Confirmation rules:
- State what you are about to delete, by exact ID, and what data/state goes with it.
- For addons, additionally state: the addon type, its size, and a reminder that the data is unrecoverable without a backup.
- Wait for an unambiguous "yes" / "delete" / "go ahead" tied to that specific resource. Treat "ok," silence, or generic agreement as insufficient.
- If the user authorised one delete, do not chain into deleting related resources (e.g. "the service and its addon and its volume") without re-confirming each one.
- Prefer reversible alternatives when they fit the user's goal: instead of
pause service, snapshot/backup an addon before deleting, etc.delete service
关键提示: 在Northflank上执行任何破坏性操作之前,请暂停并明确请求用户确认。不要假设先前的批准适用于其他操作或会话——每个操作都需单独确认。
破坏性操作至少包括:
- /
delete service—— 不可逆;会丢失容器状态和所有服务范围的配置apiClient.delete.service - /
delete addon—— 格外小心:附加组件存储持久化数据(数据库、队列、缓存)。删除操作不可逆,除非用户有最近的备份,否则所有数据将被销毁。务必向用户确认附加组件名称,询问是否存在备份,并且只有在用户明确回复“是的,删除apiClient.delete.addon”时才能继续。<addon-id> - —— 销毁持久化磁盘内容
delete volume - —— 清除整个命名空间及其中的所有资源
delete project - —— 可能会破坏依赖这些密钥的运行中工作负载
delete secret - —— 删除任务及其运行历史
delete job - / 运行会销毁资源的模板
delete template - /
delete domaindelete dns-record - (BYOC/BYOK)—— 影响该集群上的所有工作负载
delete cluster - 任何缩小持久化状态的/
patch操作(例如降低附加组件的副本数——Northflank会直接拒绝此类操作,但绝不要尝试将其作为解决方法)update - 强制取消用户未启动的运行中任务、构建或流水线
确认规则:
- 说明您即将删除的资源(按精确ID),以及随之丢失的数据/状态。
- 对于附加组件,额外说明:附加组件类型、大小,并提醒用户如果没有备份,数据将无法恢复。
- 等待用户针对该特定资源给出明确的“是”/“删除”/“继续”回复。将“好的”、沉默或一般性同意视为不充分的确认。
- 如果用户批准了一项删除操作,不要在未重新确认每个资源的情况下链式删除相关资源(例如“删除服务及其附加组件和存储卷”)。
- 当符合用户目标时,优先选择可逆替代方案:使用代替
pause service,删除附加组件前先创建快照/备份等。delete service
CLI Essentials
CLI基础操作
Install, login, and pick a context
安装、登录并选择上下文
bash
npm i -g @northflank/cli
northflank login
northflank context ls
northflank context use
northflank context use project- creates a context and can open a browser to select or create a token.
northflank login - Use to set defaults so later commands can omit repeated IDs.
northflank context use project|service|job - Use to see the command tree.
northflank command-overview
bash
npm i -g @northflank/cli
northflank login
northflank context ls
northflank context use
northflank context use project- 会创建上下文,并可打开浏览器选择或创建令牌。
northflank login - 使用设置默认值,以便后续命令可省略重复的ID。
northflank context use project|service|job - 使用查看命令树。
northflank command-overview
Inspect resources
检查资源
bash
undefinedbash
undefinedPrompts for missing values interactively
交互式提示缺失的值
northflank get service
northflank get service
Explicit project and service
显式指定项目和服务
northflank get service --projectId <PROJECT_ID> --serviceId <SERVICE_ID>
The CLI is interactive by default. If IDs are omitted it will usually prompt for them.northflank get service --projectId <PROJECT_ID> --serviceId <SERVICE_ID>
CLI默认是交互式的。如果省略ID,通常会提示用户输入。Execute commands in a running container
在运行中的容器中执行命令
bash
undefinedbash
undefinedInteractive shell session
交互式shell会话
northflank exec service
northflank exec service
One-off command
一次性命令
northflank exec service --cmd "ls -lah /app"
northflank exec service --cmd "ls -lah /app"
Run as a specific user
以特定用户身份运行
northflank exec service --user root --cmd id
Use `northflank exec job` for jobs instead of services.northflank exec service --user root --cmd id
针对任务使用`northflank exec job`而非`northflank exec service`。Forward a private service or addon locally
将私有服务或附加组件端口转发到本地
bash
sudo northflank forward service --projectId <PROJECT_ID> --serviceId <SERVICE_ID>
sudo northflank forward addon --projectId <PROJECT_ID> --addonId <ADDON_ID>bash
sudo northflank forward service --projectId <PROJECT_ID> --serviceId <SERVICE_ID>
sudo northflank forward addon --projectId <PROJECT_ID> --addonId <ADDON_ID>If sudo path/context resolution causes issues
如果sudo路径/上下文解析出现问题
sudo --preserve-env=PATH,HOME bash -c 'northflank forward service --projectId <PROJECT_ID> --serviceId <SERVICE_ID>'
- Add `--skipHostnames` if rootless forwarding is acceptable and only IP/port access is needed.
- Use `northflank forward all --projectId <PROJECT_ID>` to open all project tunnels at once.sudo --preserve-env=PATH,HOME bash -c 'northflank forward service --projectId <PROJECT_ID> --serviceId <SERVICE_ID>'
- 如果无需root权限即可接受转发,且仅需IP/端口访问,可添加`--skipHostnames`。
- 使用`northflank forward all --projectId <PROJECT_ID>`一次性打开项目的所有隧道。Create resources from JSON or YAML
从JSON或YAML创建资源
bash
northflank create project --help
northflank create project --file ./project.yamlCLI resource definitions follow the same shape as the API request bodies.
bash
northflank create project --help
northflank create project --file ./project.yamlCLI资源定义与API请求体的格式一致。
JS Client Essentials
JS客户端基础操作
Client setup
客户端设置
js
import { ApiClient, ApiClientInMemoryContextProvider } from '@northflank/js-client';
const contextProvider = new ApiClientInMemoryContextProvider();
await contextProvider.addContext({
name: 'default',
token: process.env.NF_API_TOKEN,
});
// Pass true as second arg to throw on HTTP errors
const apiClient = new ApiClient(contextProvider, true);All methods follow the pattern:
apiClient.{verb}.{resource}({ parameters, data, options })- — path params (e.g.
parameters,projectId)serviceId - — request body (for create/update)
data - — query params (for filtering, pagination)
options
js
import { ApiClient, ApiClientInMemoryContextProvider } from '@northflank/js-client';
const contextProvider = new ApiClientInMemoryContextProvider();
await contextProvider.addContext({
name: 'default',
token: process.env.NF_API_TOKEN,
});
// 第二个参数传true会在HTTP错误时抛出异常
const apiClient = new ApiClient(contextProvider, true);所有方法遵循以下模式:
apiClient.{verb}.{resource}({ parameters, data, options })- —— 路径参数(例如
parameters、projectId)serviceId - —— 请求体(用于创建/更新)
data - —— 查询参数(用于过滤、分页)
options
Create a deployment service (from image)
创建部署服务(从镜像)
js
const result = await apiClient.create.service.deployment({
parameters: { projectId: 'my-project' },
data: {
name: 'my-api',
billing: { deploymentPlan: 'nf-compute-10' },
deployment: {
instances: 1,
external: { imagePath: 'nginx:latest' },
docker: { configType: 'default' },
},
ports: [{ name: 'http', internalPort: 80, public: true, protocol: 'HTTP' }],
},
});
const serviceId = result.data.id; // 'my-api'Common plan sizes: (0.1 vCPU/256MB), (0.5/1GB), (1/2GB), (2/4GB). See Compute & GPU Plans for the full table, GPU SKUs, and how to query the live list.
nf-compute-10nf-compute-50nf-compute-100-2nf-compute-200js
const result = await apiClient.create.service.deployment({
parameters: { projectId: 'my-project' },
data: {
name: 'my-api',
billing: { deploymentPlan: 'nf-compute-10' },
deployment: {
instances: 1,
external: { imagePath: 'nginx:latest' },
docker: { configType: 'default' },
},
ports: [{ name: 'http', internalPort: 80, public: true, protocol: 'HTTP' }],
},
});
const serviceId = result.data.id; // 'my-api'常见套餐规格:(0.1 vCPU/256MB)、(0.5/1GB)、(1/2GB)、(2/4GB)。完整表格、GPU SKU以及如何查询实时列表,请参见计算与GPU套餐。
nf-compute-10nf-compute-50nf-compute-100-2nf-compute-200Create a combined service (build + deploy from Git)
创建组合服务(从Git构建并部署)
js
await apiClient.create.service.combined({
parameters: { projectId: 'my-project' },
data: {
name: 'my-app',
billing: { deploymentPlan: 'nf-compute-50' },
vcsData: {
projectUrl: 'https://github.com/org/repo',
projectType: 'github',
projectBranch: 'main',
},
buildSettings: {
dockerfile: {
buildEngine: 'buildkit',
dockerFilePath: '/Dockerfile',
dockerWorkDir: '/',
},
},
deployment: { instances: 1 },
ports: [{ name: 'app', internalPort: 3000, public: true, protocol: 'HTTP' }],
},
});js
await apiClient.create.service.combined({
parameters: { projectId: 'my-project' },
data: {
name: 'my-app',
billing: { deploymentPlan: 'nf-compute-50' },
vcsData: {
projectUrl: 'https://github.com/org/repo',
projectType: 'github',
projectBranch: 'main',
},
buildSettings: {
dockerfile: {
buildEngine: 'buildkit',
dockerFilePath: '/Dockerfile',
dockerWorkDir: '/',
},
},
deployment: { instances: 1 },
ports: [{ name: 'app', internalPort: 3000, public: true, protocol: 'HTTP' }],
},
});Get / list services
获取/列出服务
js
// List all services in a project
const { data } = await apiClient.list.services({ parameters: { projectId: 'my-project' } });
const services = data.services;
// Get a single service
const svc = await apiClient.get.service({
parameters: { projectId: 'my-project', serviceId: 'my-api' },
});
// Deployment rollout state: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'FAILED'
// ('COMPLETED' = rolled out and serving, NOT "exited")
console.log(svc.data.status.deployment?.status);
// Build state (only present for combined/build services):
// 'QUEUED' | 'PENDING' | 'STARTING' | 'BUILDING' | 'SUCCESS' | 'FAILURE' | ...
console.log(svc.data.status.build?.status);
// Pause is a separate boolean — not encoded in either status above
console.log(svc.data.servicePaused);js
// 列出项目中的所有服务
const { data } = await apiClient.list.services({ parameters: { projectId: 'my-project' } });
const services = data.services;
// 获取单个服务
const svc = await apiClient.get.service({
parameters: { projectId: 'my-project', serviceId: 'my-api' },
});
// 部署滚动状态: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'FAILED'
// ('COMPLETED' = 已完成滚动部署并提供服务,并非"已退出")
console.log(svc.data.status.deployment?.status);
// 构建状态(仅组合/构建服务存在):
// 'QUEUED' | 'PENDING' | 'STARTING' | 'BUILDING' | 'SUCCESS' | 'FAILURE' | ...
console.log(svc.data.status.build?.status);
// 暂停状态是单独的布尔值——未编码在上述任一状态中
console.log(svc.data.servicePaused);Execute a command in a service
在服务中执行命令
js
// Short-lived command — returns stdout/stderr/exitCode
const result = await apiClient.exec.execServiceCommand(
{ projectId: 'my-project', serviceId: 'my-api' },
{ command: ['ls', '-lah', '/app'] },
);
console.log(result.stdOut);
console.log(result.commandResult.exitCode); // 0 = success
// Long-running / interactive session
const { exec } = apiClient;
const session = await exec.execServiceSession(
{ projectId: 'my-project', serviceId: 'my-api' },
{ shell: 'bash' },
);
session.stdErr.on('data', (chunk) => console.error(chunk));
session.stdIn.write('echo hello\n');
const result2 = await session.waitForCommandResult();For more command-execution details, see .
references/api/execute-command.mdjs
// 短期命令——返回stdout/stderr/exitCode
const result = await apiClient.exec.execServiceCommand(
{ projectId: 'my-project', serviceId: 'my-api' },
{ command: ['ls', '-lah', '/app'] },
);
console.log(result.stdOut);
console.log(result.commandResult.exitCode); // 0 = 成功
// 长期/交互式会话
const { exec } = apiClient;
const session = await exec.execServiceSession(
{ projectId: 'my-project', serviceId: 'my-api' },
{ shell: 'bash' },
);
session.stdErr.on('data', (chunk) => console.error(chunk));
session.stdIn.write('echo hello\n');
const result2 = await session.waitForCommandResult();有关命令执行的更多详细信息,请参见。
references/api/execute-command.mdStream logs from a service
从服务中流式传输日志
js
const logsClient = await apiClient.get.service.logTail({
parameters: { projectId: 'my-project', serviceId: 'my-api' },
options: { lineLimit: 20 },
});
logsClient.on('logs-received', (lines) => {
lines.forEach((l) => console.log(`[${l.ts.toISOString()}] ${l.log}`));
});
logsClient.on('error', console.error);
await logsClient.start();
// Call await logsClient.stop() when donejs
const logsClient = await apiClient.get.service.logTail({
parameters: { projectId: 'my-project', serviceId: 'my-api' },
options: { lineLimit: 20 },
});
logsClient.on('logs-received', (lines) => {
lines.forEach((l) => console.log(`[${l.ts.toISOString()}] ${l.log}`));
});
logsClient.on('error', console.error);
await logsClient.start();
// 完成后调用await logsClient.stop()Pause / resume / restart / delete a service
暂停/恢复/重启/删除服务
js
const params = { parameters: { projectId: 'my-project', serviceId: 'my-api' } };
await apiClient.pause.service(params); // stops billing, keeps config
await apiClient.resume.service(params); // restarts from paused
await apiClient.restart.service(params); // rolling restart (keeps running)
await apiClient.delete.service(params); // permanent, irreversiblejs
const params = { parameters: { projectId: 'my-project', serviceId: 'my-api' } };
await apiClient.pause.service(params); // 停止计费,保留配置
await apiClient.resume.service(params); // 从暂停状态重启
await apiClient.restart.service(params); // 滚动重启(保持运行)
await apiClient.delete.service(params); // 永久删除,不可逆Update a service (patch)
更新服务(补丁)
js
// Update image or instance count
await apiClient.patch.service.deployment({
parameters: { projectId: 'my-project', serviceId: 'my-api' },
data: {
deployment: {
instances: 3,
external: { imagePath: 'myregistry/myapp:v2' },
},
},
});js
// 更新镜像或实例数量
await apiClient.patch.service.deployment({
parameters: { projectId: 'my-project', serviceId: 'my-api' },
data: {
deployment: {
instances: 3,
external: { imagePath: 'myregistry/myapp:v2' },
},
},
});Create an addon (database)
创建附加组件(数据库)
js
const { data } = await apiClient.create.addon({
parameters: { projectId: 'my-project' },
data: {
name: 'my-postgres',
type: 'postgresql', // postgresql | mongodb | mysql | redis | rabbitmq | minio | memcached
version: '16',
billing: {
deploymentPlan: 'nf-compute-10',
storage: 4096, // MB
replicas: 1,
},
tlsEnabled: true,
},
});
const addonId = data.id; // 'my-postgres'js
const { data } = await apiClient.create.addon({
parameters: { projectId: 'my-project' },
data: {
name: 'my-postgres',
type: 'postgresql', // postgresql | mongodb | mysql | redis | rabbitmq | minio | memcached
version: '16',
billing: {
deploymentPlan: 'nf-compute-10',
storage: 4096, // MB
replicas: 1,
},
tlsEnabled: true,
},
});
const addonId = data.id; // 'my-postgres'Get addon credentials
获取附加组件凭证
js
const creds = await apiClient.get.addon.credentials({
parameters: { projectId: 'my-project', addonId: 'my-postgres' },
});
// creds.data.username, creds.data.password, creds.data.connectionString, etc.
console.log(creds.data.connectionString);js
const creds = await apiClient.get.addon.credentials({
parameters: { projectId: 'my-project', addonId: 'my-postgres' },
});
// creds.data.username, creds.data.password, creds.data.connectionString等
console.log(creds.data.connectionString);Manage secret groups
管理密钥组
Secret groups link add-on connection strings to service env vars, and/or hold arbitrary key-value secrets.
js
// Create a secret group with a static env var and a linked addon credential
await apiClient.create.secret({
parameters: { projectId: 'my-project' },
data: {
name: 'app-secrets',
secretType: 'environment', // 'environment' | 'build-arg' | 'global'
priority: 10,
data: {
NODE_ENV: 'production',
API_KEY: 'supersecret',
},
addonDependencies: [
{
addonId: 'my-postgres',
keys: [
{ keyName: 'POSTGRES_URI', aliases: ['DATABASE_URL'] },
],
},
],
restrictions: {
restricted: true,
nfObjects: [{ id: 'my-api', type: 'service' }],
},
},
});
// List secrets in project
const { data } = await apiClient.list.secrets({ parameters: { projectId: 'my-project' } });
// Update a secret group (add/change key)
await apiClient.patch.secret({
parameters: { projectId: 'my-project', secretId: 'app-secrets' },
data: { data: { FEATURE_FLAG: 'true' } },
});密钥组将附加组件连接字符串与服务环境变量关联,或存储任意键值对密钥。
js
// 创建包含静态环境变量和关联附加组件凭证的密钥组
await apiClient.create.secret({
parameters: { projectId: 'my-project' },
data: {
name: 'app-secrets',
secretType: 'environment', // 'environment' | 'build-arg' | 'global'
priority: 10,
data: {
NODE_ENV: 'production',
API_KEY: 'supersecret',
},
addonDependencies: [
{
addonId: 'my-postgres',
keys: [
{ keyName: 'POSTGRES_URI', aliases: ['DATABASE_URL'] },
],
},
],
restrictions: {
restricted: true,
nfObjects: [{ id: 'my-api', type: 'service' }],
},
},
});
// 列出项目中的密钥
const { data } = await apiClient.list.secrets({ parameters: { projectId: 'my-project' } });
// 更新密钥组(添加/修改键)
await apiClient.patch.secret({
parameters: { projectId: 'my-project', secretId: 'app-secrets' },
data: { data: { FEATURE_FLAG: 'true' } },
});Pagination
分页
List endpoints return 50 items by default. Two options:
js
// Fetch all pages automatically (multiple API calls)
const all = await apiClient.list.services.all({ parameters: { projectId: 'my-project' } });
// Manual next-page
const page1 = await apiClient.list.services({ parameters: { projectId: 'my-project' } });
if (page1.pagination?.hasNextPage) {
const page2 = await page1.pagination.getNextPage();
}列表端点默认返回50条数据。有两种处理方式:
js
// 自动获取所有页面(多次API调用)
const all = await apiClient.list.services.all({ parameters: { projectId: 'my-project' } });
// 手动获取下一页
const page1 = await apiClient.list.services({ parameters: { projectId: 'my-project' } });
if (page1.pagination?.hasNextPage) {
const page2 = await page1.pagination.getNextPage();
}Error handling
错误处理
js
// Option 1: check result.error (client does NOT throw by default)
const result = await apiClient.get.service({ parameters: { projectId, serviceId } });
if (result.error) {
console.error(result.error.status, result.error.message);
}
// Option 2: init client with throwOnError = true
const apiClient = new ApiClient(contextProvider, true);
try {
await apiClient.get.service({ parameters: { projectId, serviceId } });
} catch (err) {
console.error(err);
}js
// 选项1:检查result.error(客户端默认不抛出异常)
const result = await apiClient.get.service({ parameters: { projectId, serviceId } });
if (result.error) {
console.error(result.error.status, result.error.message);
}
// 选项2:初始化客户端时设置throwOnError = true
const apiClient = new ApiClient(contextProvider, true);
try {
await apiClient.get.service({ parameters: { projectId, serviceId } });
} catch (err) {
console.error(err);
}Rate limit headers
速率限制响应头
js
const { rawResponse } = await apiClient.get.service({ parameters: { projectId, serviceId } });
const remaining = rawResponse.headers.get('x-ratelimit-remaining');
const reset = rawResponse.headers.get('x-ratelimit-reset'); // secondsjs
const { rawResponse } = await apiClient.get.service({ parameters: { projectId, serviceId } });
const remaining = rawResponse.headers.get('x-ratelimit-remaining');
const reset = rawResponse.headers.get('x-ratelimit-reset'); // 秒数Compute & GPU Plans
计算与GPU套餐
Full live tables (every compute plan, GPU SKU, pricing, and per-region GPU availability) are auto-generated into references/plans.md by . Re-run with to refresh after Northflank ships new SKUs or price changes. The underlying endpoints are public — no auth needed:
scripts/generate_references.js--forcebash
curl -s https://api.northflank.com/v1/plans | jq '.data.plans[] | {id, cpu: .cpuResource, ramMB: .ramResource, hr: .amountPerHour}'
curl -s https://api.northflank.com/v1/regions | jq '.data.regions[] | {id, gpus: (.gpuDevices // [] | map(.id))}'JS client / CLI equivalents: / and / .
apiClient.list.plans({})apiClient.list.regions({})northflank list plansnorthflank list regions完整的实时表格(所有计算套餐、GPU SKU、定价以及各区域GPU可用性)由自动生成到references/plans.md中。Northflank发布新SKU或调整价格后,可使用参数重新运行脚本以刷新内容。底层端点是公开的——无需认证:
scripts/generate_references.js--forcebash
curl -s https://api.northflank.com/v1/plans | jq '.data.plans[] | {id, cpu: .cpuResource, ramMB: .ramResource, hr: .amountPerHour}'
curl -s https://api.northflank.com/v1/regions | jq '.data.regions[] | {id, gpus: (.gpuDevices // [] | map(.id))}'JS客户端/CLI等效命令: / 以及 / 。
apiClient.list.plans({})apiClient.list.regions({})northflank list plansnorthflank list regionsCompute plan slugs
计算套餐slug
Format: (newer, explicit) or (legacy, RAM implied). Common picks:
nf-compute-<cpu*100>-<ram_gb>nf-compute-<cpu*100>- — 0.1 vCPU / 256 MB (~$2.70/mo) — sidecars, light workers
nf-compute-10 - — 0.5 vCPU / 1 GB (~$12/mo) — small APIs, cron jobs
nf-compute-50 - — 2 vCPU / 4 GB (~$48/mo) — typical production service
nf-compute-200 - — 4 vCPU / 16 GB (~$144/mo) — also valid as
nf-compute-400-16buildPlan
buildPlannf-compute-400-16格式:(较新版本,明确规格)或(旧版本,内存规格隐含)。常见选择:
nf-compute-<cpu*100>-<ram_gb>nf-compute-<cpu*100>- —— 0.1 vCPU / 256 MB(约$2.70/月)—— 边车容器、轻量工作负载
nf-compute-10 - —— 0.5 vCPU / 1 GB(约$12/月)—— 小型API、定时任务
nf-compute-50 - —— 2 vCPU / 4 GB(约$48/月)—— 典型生产服务
nf-compute-200 - —— 4 vCPU / 16 GB(约$144/月)—— 也可用作
nf-compute-400-16buildPlan
buildPlannf-compute-400-16GPU plan slugs
GPU套餐slug
Format: (the suffix is literal, not a unit). The plan bundles CPU/RAM around the GPU — you do not combine an plan with a separate GPU. Worked example:
nf-gpu-<gpuType>-<count>ggnf-compute-*js
data: {
billing: { deploymentPlan: 'nf-gpu-a100-80-1g' }, // 1× A100 80GB
deployment: {
gpu: { enabled: true, gpuType: 'a100-80', gpuCount: 1 },
// ...
},
}- is the model id (lowercase, no
gpuTypeprefix). Currently:nvidia-,l4-24,a100-40,a100-80,h100-80,h200-141.b200-180 - must be one of the model's
gpuCount(typicallycountOptions; H200 and B200 are 8-only). Invalid counts are rejected.1, 2, 4, 8 - The block can sit under
gpuordeployment.gpu; Northflank's own templates usebilling.gpu.deployment.gpu - GPU billing is per GPU per hour, on top of the bundled compute. Pricing and per-region availability live in references/plans.md.
For BYOC clusters, GPU node types come from the cloud provider — query with and define custom resource plans (see ). Timeslicing is supported on BYOC, not on managed cloud.
apiClient.list.cloudProviders.nodeTypes({ options: { hasGpu: true } })references/guides/bring-your-own-cloud.md#create-custom-resource-plansFor Northflank-published GPU base images (PyTorch + CUDA + Jupyter pre-installed), pull from instead of building from raw .
europe-docker.pkg.dev/northflank/public/...pytorch/pytorch:*格式:(后缀是字面量,不是单位)。套餐会围绕GPU捆绑CPU/内存——您不能将套餐与单独的GPU组合使用。示例:
nf-gpu-<gpuType>-<count>ggnf-compute-*js
data: {
billing: { deploymentPlan: 'nf-gpu-a100-80-1g' }, // 1× A100 80GB
deployment: {
gpu: { enabled: true, gpuType: 'a100-80', gpuCount: 1 },
// ...
},
}- 是型号ID(小写,无
gpuType前缀)。当前支持:nvidia-、l4-24、a100-40、a100-80、h100-80、h200-141。b200-180 - 必须是型号支持的
gpuCount之一(通常为countOptions;H200和B200仅支持8)。无效的数量会被拒绝。1, 2, 4, 8 - 块可放在
gpu或deployment.gpu下;Northflank官方模板使用billing.gpu。deployment.gpu - GPU计费是每GPU每小时,在捆绑的计算费用之上。定价和各区域可用性请参见references/plans.md。
对于BYOC集群,GPU节点类型来自云提供商——可通过查询,并定义自定义资源套餐(请参见)。BYOC支持时间分片,托管云不支持。
apiClient.list.cloudProviders.nodeTypes({ options: { hasGpu: true } })references/guides/bring-your-own-cloud.md#create-custom-resource-plans对于Northflank发布的GPU基础镜像(预安装PyTorch + CUDA + Jupyter),请从拉取,而非从原始构建。
europe-docker.pkg.dev/northflank/public/...pytorch/pytorch:*Common Patterns
常见模式
Deploy and watch until healthy
部署并等待直到健康
js
await apiClient.create.service.deployment({ parameters: { projectId }, data: { ...serviceSpec } });
// Poll until the deployment has rolled out
let status;
do {
await new Promise((r) => setTimeout(r, 2000));
const svc = await apiClient.get.service({ parameters: { projectId, serviceId: 'my-api' } });
status = svc.data.status.deployment?.status;
if (status === 'FAILED') throw new Error('Deployment failed');
} while (status !== 'COMPLETED');js
await apiClient.create.service.deployment({ parameters: { projectId }, data: { ...serviceSpec } });
// 轮询直到部署完成滚动更新
let status;
do {
await new Promise((r) => setTimeout(r, 2000));
const svc = await apiClient.get.service({ parameters: { projectId, serviceId: 'my-api' } });
status = svc.data.status.deployment?.status;
if (status === 'FAILED') throw new Error('部署失败');
} while (status !== 'COMPLETED');Auto-scaling configuration (in create/patch data)
自动扩缩容配置(在创建/补丁数据中)
js
data: {
deployment: {
instances: 1,
autoscaling: {
horizontal: {
enabled: true,
minReplicas: 1,
maxReplicas: 10,
cpu: { enabled: true, thresholdPercentage: 70 },
rps: { enabled: true, thresholdValue: 500 },
},
},
},
}js
data: {
deployment: {
instances: 1,
autoscaling: {
horizontal: {
enabled: true,
minReplicas: 1,
maxReplicas: 10,
cpu: { enabled: true, thresholdPercentage: 70 },
rps: { enabled: true, thresholdValue: 500 },
},
},
},
}Run a template
运行模板
js
await apiClient.run.template({
parameters: { templateId: 'my-template' },
data: {
arguments: {
REGION: 'europe-west',
IMAGE: 'myapp:latest',
},
},
});js
await apiClient.run.template({
parameters: { templateId: 'my-template' },
data: {
arguments: {
REGION: 'europe-west',
IMAGE: 'myapp:latest',
},
},
});Create a cron job
创建定时任务
js
await apiClient.create.job({
parameters: { projectId: 'my-project' },
data: {
name: 'db-migrate',
billing: { deploymentPlan: 'nf-compute-10' },
deployment: {
external: { imagePath: 'myapp:latest' },
docker: { configType: 'default' },
},
settings: {
cron: { schedule: '0 2 * * *' }, // present = cron job
concurrencyPolicy: 'Forbid',
},
runtimeEnvironment: { MIGRATE: 'true' },
},
});
// Run it manually now
await apiClient.start.job.run({ parameters: { projectId: 'my-project', jobId: 'db-migrate' } });js
await apiClient.create.job({
parameters: { projectId: 'my-project' },
data: {
name: 'db-migrate',
billing: { deploymentPlan: 'nf-compute-10' },
deployment: {
external: { imagePath: 'myapp:latest' },
docker: { configType: 'default' },
},
settings: {
cron: { schedule: '0 2 * * *' }, // 存在该字段即为定时任务
concurrencyPolicy: 'Forbid',
},
runtimeEnvironment: { MIGRATE: 'true' },
},
});
// 立即手动运行
await apiClient.start.job.run({ parameters: { projectId: 'my-project', jobId: 'db-migrate' } });Gotchas
注意事项
- IDs are slugified names — becomes
"My App"(slug). Use IDs in API calls, not display names.my-api - Addon storage and replicas can only increase, never decrease after creation.
- Secret groups with addon links auto-update connection strings when add-ons rotate credentials or change.
- Port names max 8 chars, must start with a letter.
- Rate limit is 1000/hr — batch operations, check .
x-ratelimit-remaining - methods use upsert semantics — create if missing, update if present. Useful for idempotent IaC.
put.* - Pause ≠ delete — paused services stop billing for compute but keep config and volumes.
- swallows output without a TTY — in CI, agent harnesses, or anything wrapped in
northflank exec --cmd "...", stdout/stderr are silently discarded. Wrap withbash -c(macOS/BSD) orscript -q /dev/null northflank exec ...(Linux) to capture output.script -qfc 'northflank exec ...' /dev/null - Service means "deployment rolled out", not "process exited" — when polling
status === "COMPLETED"(or top-levelsvc.data.status.deployment.statusinstatus.status),northflank get service -o jsonindicates the container is up and serving. The natural reading is the opposite, so don't treat it as a terminal/finished state.COMPLETED
- ID是名称的slug化结果——会变为
"My App"(slug)。API调用中使用ID,而非显示名称。my-api - 附加组件的存储和副本数只能增加,创建后无法减少。
- 关联附加组件的密钥组会在附加组件轮换凭证或变更时自动更新连接字符串。
- 端口名称最多8个字符,必须以字母开头。
- 速率限制为1000次/小时——批量操作时,请检查。
x-ratelimit-remaining - 方法使用upsert语义——不存在则创建,存在则更新。适用于幂等的IaC场景。
put.* - 暂停≠删除——暂停的服务停止计算计费,但保留配置和存储卷。
- 在无TTY时会吞掉输出——在CI、代理工具或任何被
northflank exec --cmd "..."包裹的环境中,stdout/stderr会被静默丢弃。在macOS/BSD上使用bash -c,在Linux上使用script -q /dev/null northflank exec ...来捕获输出。script -qfc 'northflank exec ...' /dev/null - 服务表示“部署已完成滚动更新”,而非“进程已退出”——轮询
status === "COMPLETED"(或svc.data.status.deployment.status中的顶级northflank get service -o json)时,status.status表示容器已启动并提供服务。其字面含义容易被误解,因此不要将其视为终端/完成状态。COMPLETED
Reference Cheat Sheet
参考速查表
| I want to... | Check here |
|---|---|
| Deploy a service from a pre-built image | |
| Build and deploy a service from a Git repo | |
| Run a one-off command or shell session in a container | |
| Tail or fetch logs from a service, job, or addon | |
| Forward a private service or addon port to localhost | |
| Provision a managed database (Postgres, Redis, Mongo, MySQL…) | |
| Wire database credentials into a service via secret groups | |
| Create a cron or manual job | |
| Configure autoscaling, replicas, or resource sizing | |
| Pick a compute or GPU plan (sizes, pricing, regions) | references/plans.md — auto-generated from |
| Set up CI/CD: pipelines, release flows, preview environments | |
| Define infrastructure as code (templates, GitOps, OpenTofu) | |
| Add a custom domain with TLS, CDN, or path routing | |
| Attach persistent storage / volumes to a service | |
| Upload or download files into a running container | |
| Configure ports, network policies, egress IPs, Tailscale | |
| Set up log sinks, metrics, alerts, health checks | |
| Run GPU workloads | |
| Spin up an AI sandbox / microVM | A sandbox is just a service — use |
| Deploy on your own cluster (BYOC/BYOK on AWS/GCP/Azure/CoreWeave) | |
| Manage teams, RBAC, SSO/MFA, API tokens | |
| Pause, resume, restart, or delete a resource | |
| 我想要... | 查看此处 |
|---|---|
| 从预构建镜像部署服务 | |
| 从Git仓库构建并部署服务 | |
| 在容器中运行一次性命令或shell会话 | |
| 跟踪或获取服务、任务或附加组件的日志 | |
| 将私有服务或附加组件端口转发到本地主机 | |
| 配置托管数据库(Postgres、Redis、Mongo、MySQL…) | |
| 通过密钥组将数据库凭证连接到服务 | 使用 |
| 创建定时或手动任务 | 使用 |
| 配置自动扩缩容、副本数或资源规格 | |
| 选择计算或GPU套餐(规格、定价、区域) | references/plans.md——从 |
| 设置CI/CD:流水线、发布流程、预览环境 | |
| 定义基础设施即代码(模板、GitOps、OpenTofu) | |
| 添加带TLS、CDN或路径路由的自定义域名 | |
| 将持久化存储/卷附加到服务 | |
| 上传或下载文件到运行中的容器 | |
| 配置端口、网络策略、出口IP、Tailscale | |
| 设置日志接收器、指标、告警、健康检查 | |
| 运行GPU工作负载 | |
| 启动AI沙箱/微VM | 沙箱本质上是一个服务——使用 |
| 在您自己的集群上部署(AWS/GCP/Azure/CoreWeave的BYOC/BYOK) | |
| 管理团队、RBAC、SSO/MFA、API令牌 | |
| 暂停、恢复、重启或删除资源 | |
Reference Files
参考文件
Platform References
平台参考
- references/api-overview.md — REST API base URL, auth, pagination, endpoint tables
- references/cli.md — CLI install, contexts, common commands, file transfer
- references/js-client.md — JS client quickstart and usage pointers
- references/plans.md — auto-generated compute & GPU plans + region availability (live from and
/v1/plans)/v1/regions
- references/api-overview.md —— REST API基础URL、认证、分页、端点表格
- references/cli.md —— CLI安装、上下文、常用命令、文件传输
- references/js-client.md —— JS客户端快速入门和使用提示
- references/plans.md —— 自动生成的计算与GPU套餐+区域可用性(从和
/v1/plans实时获取)/v1/regions
API Endpoint References
API端点参考
- references/api/_index.md — master index of all endpoints
- references/api/use-the-cli.md — CLI install, login, contexts, and command model
- references/api/use-the-api.md — REST API usage guide
- references/api/use-the-javascript-client.md — JS client usage guide
- references/api/project/services/_index.md — service endpoints
- references/api/project/addons/_index.md — addon endpoints
- references/api/project/jobs/_index.md — job endpoints
- references/api/project/secrets/_index.md — project secret endpoints
- references/api/project/volumes/_index.md — volume endpoints
- references/api/team/templates/_index.md — template endpoints
- references/api/team/domains/_index.md — domain endpoints
- references/api/team/projects/_index.md — project endpoints
- references/api/execute-command.md — exec command details
- references/api/log-tailing.md — log tailing details
- references/api/forwarding.md — port-forwarding details
- references/api/copy-files.md — file upload/download details
- references/api/retrieve-metrics.md — metrics retrieval
- references/api/introduction.md — API/CLI/JS client overview
- references/api/_index.md —— 所有端点的主索引
- references/api/use-the-cli.md —— CLI安装、登录、上下文和命令模型
- references/api/use-the-api.md —— REST API使用指南
- references/api/use-the-javascript-client.md —— JS客户端使用指南
- references/api/project/services/_index.md —— 服务端点
- references/api/project/addons/_index.md —— 附加组件端点
- references/api/project/jobs/_index.md —— 任务端点
- references/api/project/secrets/_index.md —— 项目密钥端点
- references/api/project/volumes/_index.md —— 存储卷端点
- references/api/team/templates/_index.md —— 模板端点
- references/api/team/domains/_index.md —— 域名端点
- references/api/team/projects/_index.md —— 项目端点
- references/api/execute-command.md —— 执行命令详情
- references/api/log-tailing.md —— 日志跟踪详情
- references/api/forwarding.md —— 端口转发详情
- references/api/copy-files.md —— 文件上传/下载详情
- references/api/retrieve-metrics.md —— 指标检索
- references/api/introduction.md —— API/CLI/JS客户端概述
How-To Guides
操作指南
- references/guides/_index.md — index of all guide topics
- references/guides/getting-started.md — intro, first project, build & deploy, architecture patterns
- references/guides/run.md — services, jobs, deployment sources, regions, SSH, container access
- references/guides/build.md — Dockerfile, buildpacks, Git integration, build arguments
- references/guides/scale.md — instances, CPU/memory, storage, autoscaling
- references/guides/release.md — CI/CD, pipelines, release flows, preview environments, environments
- references/guides/databases-and-persistence.md — addons, volumes, backups, HA, migration
- references/guides/secure.md — secrets, RBAC, SSO/MFA, API access, secret files
- references/guides/network.md — ports, security policies, load balancers, egress IPs, Tailscale
- references/guides/observe.md — logs, metrics, health checks, alerts, log sinks, notifications
- references/guides/infrastructure-as-code.md — templates, GitOps, template nodes, GitHub Actions, OpenTofu
- references/guides/domains.md — add/verify domains, TLS, CDN, path routing, registrar guides
- references/guides/bring-your-own-cloud.md — BYOC/BYOK setup for AWS, GCP, Azure, Civo, CoreWeave, OCI
- references/guides/collaborate.md — teams, organizations, RBAC, multi-tenancy models
- references/guides/gpu-workloads.md — GPU deployment and optimization
- references/guides/sandboxes.md — AI sandboxes, microVMs, GVisor, pre-warmed pools
- references/guides/production-workloads.md — production readiness, operations, release
- references/guides/billing.md — payment, invoices, credits, pricing
- references/guides/migrate-from-heroku.md — Heroku migration walkthrough
- references/guides/overview.md — high-level Northflank overview
- references/guides/_index.md —— 所有指南主题的索引
- references/guides/getting-started.md —— 介绍、首个项目、构建与部署、架构模式
- references/guides/run.md —— 服务、任务、部署源、区域、SSH、容器访问
- references/guides/build.md —— Dockerfile、buildpacks、Git集成、构建参数
- references/guides/scale.md —— 实例数、CPU/内存、存储、自动扩缩容
- references/guides/release.md —— CI/CD、流水线、发布流程、预览环境、环境
- references/guides/databases-and-persistence.md —— 附加组件、存储卷、备份、高可用、迁移
- references/guides/secure.md —— 密钥、RBAC、SSO/MFA、API访问、密钥文件
- references/guides/network.md —— 端口、安全策略、负载均衡器、出口IP、Tailscale
- references/guides/observe.md —— 日志、指标、健康检查、告警、日志接收器、通知
- references/guides/infrastructure-as-code.md —— 模板、GitOps、模板节点、GitHub Actions、OpenTofu
- references/guides/domains.md —— 添加/验证域名、TLS、CDN、路径路由、注册商指南
- references/guides/bring-your-own-cloud.md —— AWS、GCP、Azure、Civo、CoreWeave、OCI的BYOC/BYOK设置
- references/guides/collaborate.md —— 团队、组织、RBAC、多租户模型
- references/guides/gpu-workloads.md —— GPU部署与优化
- references/guides/sandboxes.md —— AI沙箱、微VM、GVisor、预预热池
- references/guides/production-workloads.md —— 生产就绪、操作、发布
- references/guides/billing.md —— 支付、发票、 credits、定价
- references/guides/migrate-from-heroku.md —— Heroku迁移指南
- references/guides/overview.md —— Northflank高级概述