mcpField
A
appliku

appliku

github.com/appliku云与 DevOps249 次安装4 周前更新
代码仓库

关于 appliku

Appliku 提供命令行工具和 Python SDK,用于管理 Appliku PaaS 上的应用与基础设施,涵盖部署相关资源、配置和团队操作。

主要功能

  1. 01管理团队和应用
  2. 02从 GitHub、GitLab 或 Git 创建应用
  3. 03查看部署和日志
  4. 04管理域名、数据存储、卷和定时任务
  5. 05配置环境变量
  6. 06使用命令行工具或 Python SDK

适用场景

  1. 01列出应用并检查最新部署
  2. 02设置应用配置并触发部署或重启
  3. 03创建域名并检查 DNS 记录
  4. 04管理数据存储和定时任务

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/appliku/skill --skill appliku

安装后在 Claude Code 中输入/appliku确认已加载。

附带文件README.mddocs/reference.md

详细介绍

Appliku CLI 和 SDK 参考

Appliku 是一个 PaaS 平台。appliku 软件包同时提供 CLI 和 Python SDK。

安装

1. 检查是否已安装 uv
uv --version

如果找不到该命令,请先安装 uv:

# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows PowerShell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

安装后,重启 shell(或加载配置文件),以便将 uv 加入 $PATH。

2. 检查是否已安装 appliku CLI
appliku --version

如果未找到,请将其安装为 uv 工具:

uv tool install appliku

然后验证:

appliku --help
SDK(在 Python 项目中)
uv add appliku
# or
pip install appliku

需要 Python 3.10+。

身份验证

令牌解析顺序(采用第一个匹配项):

  1. 显式指定:Appliku(token="...")
  2. 环境变量:APPLIKU_TOKEN=...
  3. 配置文件:~/.config/appliku/config.toml → [auth] token = "..."
用于非交互式环境 / CI 环境
export APPLIKU_TOKEN=your_api_token
交互式登录(浏览器设备流程)
appliku login              # opens browser to authorize
appliku login --token TOKEN  # direct token login (non-interactive)
appliku logout
appliku whoami

核心概念

  • team_path:用于标识团队的 slug(例如 my-team)。大多数命令都需要此参数。
  • app id:应用程序的数字 ID。可通过 appliku apps list --team my-team --output json 获取。
  • resource id:域名、数据存储、卷、定时任务等资源的数字 ID。
  • 大多数列表命令都支持 --output json,以生成机器可读的输出。

CLI 命令参考

teams
appliku teams list
appliku teams get <team_path>

无论你的成员身份级别如何,teams get 都会返回相同的字段,但你无权读取的值会显示为 null。管理员的账单字段(paddle_*)、can_invite_members 和 name_picked 会显示为 null;开发者还会看到部署密钥(public_key、public_key_ed25519)和通知 webhook URL 显示为 null。因此,null 表示“未设置”或“你不可见”——对于账单值,请先以所有者身份检查,再判断团队是否没有订阅。需要 CLI 0.5.0 或更高版本;旧版本在非所有者使用时会崩溃。

apps
appliku apps list --team <team_path>
appliku apps list --team <team_path> --output json

# Create from GitHub or GitLab. Use exactly one positive target ID.
appliku apps create github owner/repository -t <team_path> -n myapp -b main --server <id>
appliku apps create gitlab group/repository -t <team_path> -n myapp -b main --cluster <id>

# Create from custom Git. A URL file can contain HTTPS credentials.
appliku apps create custom -t <team_path> -n myapp -b main --server <id> \
  --git-url-file <path-or-> [--private-key-file <path>]

# Trigger a deployment
appliku apps deploy --team <team_path> --app <id>

# Restart WITHOUT a build: same running image, current env vars and process
# settings. No new code, no build, no release command. Build-time variables
# (NEXT_PUBLIC_*, anything the build command reads) keep their old values ->
# use `apps deploy` for those. Needs the backend with the restart endpoint; the
# first restart needs one full deploy made with it. Not for static sites.
appliku apps restart --team <team_path> --app <id>
appliku apps restart --team <team_path> --app <id> --check   # possible? exit 1 + reason if not

# Config vars: see the `config` group below. `apps delete-config-var` is
# DEPRECATED — use `appliku config unset KEY` instead.

# Application logs — one command, any deployment mode, one or more processes.
# With no --process it returns logs for ALL of the app's processes.
appliku apps logs --team <team_path> --app <id>
appliku apps logs --team <team_path> --app <id> --process web
appliku apps logs --team <team_path> --app <id> --process web --process celery --tail 200

# service-logs is DEPRECATED — use `apps logs -p <service>` instead.

# Nginx / load balancer logs
appliku apps nginx-logs         --team <team_path> --app <id> --domain example.com --tail 100
appliku apps load-balancer-logs --team <team_path> --app <id> --domain example.com --tail 100

每个创建命令都接受 --static-site 和 --output table|json。自定义 Git 也接受一个位置参数形式的公开 URL,但必须且只能指定一个位置参数 URL 或 --git-url-file。对于包含凭据的 URL,请使用文件或标准输入(--git-url-file -)。私钥只能通过 --private-key-file 提供。输出仅包含安全的应用程序字段,不包含这些机密信息。

创建操作会启动对初始 appliku.yml 的异步检查,但不会部署应用程序。设置完成后,请单独部署。

目标必须已就绪。 尚未完成设置的服务器或集群会被拒绝,并返回 HTTP 400。两个列表命令都会报告 ready 列,因此请从中选择目标,而不是猜测 ID:

appliku servers list  --team <team_path>                 # Ready column
appliku clusters list --team <team_path>                 # Ready column
appliku servers list  --team <team_path> --output json | jq '[.[] | select(.ready)]'

服务器在处于活动状态且完成设置后即为就绪。集群在其主管理器就绪后即为就绪——没有主管理器的集群永远无法托管应用程序。如果没有任何目标就绪,请等待设置完成;立即重试创建只会返回相同的 400 错误。

config

Heroku 风格的环境变量(heroku config / config:get / config:set / config:unset)。

appliku config list --team <team_path> --app <id>              # table: name, value, source, mode
appliku config list --team <team_path> --app <id> --output json   # {"NAME": "value", ...}
appliku config list --team <team_path> --app <id> --output shell  # NAME='value' (POSIX shell, not dotenv)
appliku config get KEY --team <team_path> --app <id>           # value only; exit 1 if not set
appliku config set A=1 B=2 --team <team_path> --app <id>       # merges; split on first '='
appliku config set A=1 --team <team_path> --app <id> --deploy  # save, then start a full deployment
appliku config set A=1 --team <team_path> --app <id> --restart # save, then restart WITHOUT a build
appliku config unset A B --team <team_path> --app <id>         # missing names: warning, exit 0
  • 更改会在下次部署或重启时生效;保存时不会重启。 --deploy = 完整构建;--restart = 不构建,仅使用运行时值(像 NEXT_PUBLIC_* 这样的构建时变量会保留旧值 → 对这些变量使用 --deploy)。这两个标志不能组合使用;没有写入任何内容时,两者都不会运行。已保存但未启动时,命令以退出码 1 结束,并显示“Config saved, but ...”(请勿重试写入)。
  • set 不接受 KEY=(在 Appliku 中,空值会删除变量——请使用 unset)、重复的名称,以及带有前导或尾随空格的值。
  • 在 appliku.yml 中定义的变量不能在此设置或取消设置。要将数据库或域名关联的变量替换为静态值,需要使用 --replace-links。
  • set/unset 会验证 API 响应,并在有任何键未应用时以退出码 1 结束,同时指出未应用的键。写入前检查仅供参考:如果某个变量在检查与写入之间关联到数据库,该变量会被替换且不会发出警告。
  • set/unset 需要具有 env_vars 读取和更新权限的令牌;--deploy/--restart 还需要 deployments 创建权限。
deployments
appliku deployments list   --team <team_path> --app <id>
appliku deployments latest --team <team_path> --app <id>
appliku deployments logs   --team <team_path> --id <deployment_id>
domains
appliku domains list      --team <team_path> --app <id>
appliku domains create    --team <team_path> --app <id> --domain example.com
appliku domains delete    --team <team_path> --app <id> --id <domain_id>
appliku domains check-dns --team <team_path> --app <id> --domain example.com
datastores
appliku datastores list    --team <team_path> --app <id>
appliku datastores start   --team <team_path> --app <id> --id <datastore_id>
appliku datastores stop    --team <team_path> --app <id> --id <datastore_id>
appliku datastores restart --team <team_path> --app <id> --id <datastore_id>
appliku datastores delete  --team <team_path> --app <id> --id <datastore_id>
volumes
appliku volumes list   --team <team_path> --app <id>
appliku volumes delete --team <team_path> --app <id> --id <volume_id>
crons
appliku crons list   --team <team_path> --app <id>
appliku crons delete --team <team_path> --app <id> --id <cron_id>
clusters
appliku clusters list   --team <team_path>
appliku clusters delete --team <team_path> --id <cluster_id>
servers
appliku servers list --team <team_path>
appliku servers get  --team <team_path> --id <server_id>

# Hetzner Cloud server provisioning (requires the team to have a stored
# Hetzner Cloud token, configured in the dashboard under Team Settings ->
# Cloud Providers).
appliku servers hetzner-info   --team <team_path> --show locations
appliku servers hetzner-info   --team <team_path> --show server-types \
  --category "ARM" --location nbg1
appliku servers create-hetzner --team <team_path> \
  --location nbg1 --server-type cax11 \
  [--enable-backups] [--cluster <cluster_id>]
invites
appliku invites list   --team <team_path>
appliku invites delete --team <team_path> --id <invite_id>
migrations
appliku migrations list --team <team_path>
appliku migrations logs --team <team_path> --id <migration_id>
ssh-keys
appliku ssh-keys list
appliku ssh-keys add    --key "ssh-rsa AAAA... user@host"
appliku ssh-keys add    --key "$(cat ~/.ssh/id_ed25519.pub)"
appliku ssh-keys delete --id <key_id>

只接受 OpenSSH 公钥。 值必须是单行,以密钥类型(ssh-ed25519、ssh-rsa、ecdsa-sha2-nistp256 等)开头,后跟 base64 密钥数据;末尾的注释会保留。其他任何内容都会被拒绝,并返回 HTTP 400。

请发送 .pub 文件,切勿发送私钥。以下内容常被误贴到此处,且都会被拒绝:

  • 私钥(-----BEGIN ... PRIVATE KEY-----,或以 b3BlbnNzaC1rZXktdjEA 开头的 base64)
  • PuTTY/RFC4716 导出格式(---- BEGIN SSH2 PUBLIC KEY ----)——请先使用 ssh-keygen -i -f key.pub 转换
  • 指纹(SHA256:...)、Git 远程 URL 或访问令牌

在仪表板中保存 Git 凭据时,密钥也会自动导入。提供商提供的密钥如果不是有效的 OpenSSH 公钥,将会被跳过,记录为 skipped_public_keys,并汇总在一封电子邮件中。

Python SDK 参考

from appliku import Appliku

client = Appliku()                     # uses APPLIKU_TOKEN or config file
client = Appliku(token="YOUR_TOKEN")   # explicit token
apps
client.apps.list("my-team")
client.apps.get("my-team", app_id=42)
client.apps.create_from_github(
    "my-team", "owner/repository", name="myapp", branch="main", server=12
)
client.apps.create_from_gitlab(
    "my-team", "group/repository", name="myapp", branch="main", cluster=7
)
client.apps.create_from_custom_git(
    "my-team",
    "[email protected]:team/repository.git",
    name="myapp",
    branch="main",
    server=12,
    private_key=private_key_contents,
)
client.apps.update("my-team", app_id=42, branch="develop")
client.apps.delete("my-team", app_id=42)
client.apps.deploy("my-team", app_id=42)
client.apps.restart("my-team", app_id=42)               # no build; {success, deployment_id}
client.apps.restart_availability("my-team", app_id=42)  # {available, reason, source_number_id}

# Config vars. get returns {"env_vars": [...]}; set takes a flat mapping.
vars = client.apps.get_config_vars("my-team", app_id=42)

# set MERGES: variables not named in the call are left untouched.
client.apps.set_config_vars("my-team", app_id=42, vars={"DEBUG": "false"})

# An empty ("" or None) value DELETES the variable rather than blanking it.
client.apps.set_config_vars("my-team", app_id=42, vars={"DEBUG": ""})  # deletes DEBUG
client.apps.delete_config_var("my-team", app_id=42, key="OLD_VAR")  # returns remaining vars

# Logs — get_logs takes a list of processes (None = all), works on any mode.
logs = client.apps.get_logs("my-team", app_id=42)  # all processes
logs = client.apps.get_logs("my-team", app_id=42, processes=["web", "celery"], tail=100)
# get_service_logs is a deprecated shim that delegates to get_logs.
logs = client.apps.get_nginx_logs("my-team", app_id=42, domain="example.com", tail=100)
logs = client.apps.get_load_balancer_logs("my-team", app_id=42, domain="example.com", tail=100)
deployments
client.deployments.list("my-team", app_id=42)
client.deployments.get("my-team", app_id=42, deployment_id=1234)
client.deployments.latest("my-team", app_id=42)
client.deployments.logs("my-team", deployment_id=1234)
domains
client.domains.list("my-team", app_id=42)
client.domains.get("my-team", app_id=42, domain_id=7)
client.domains.create("my-team", app_id=42, domain="example.com")
client.domains.delete("my-team", app_id=42, domain_id=7)
result = client.domains.check_dns("my-team", app_id=42, domain="example.com")
datastores
client.datastores.list("my-team", app_id=42)
client.datastores.get("my-team", app_id=42, datastore_id=5)
client.datastores.create("my-team", app_id=42, name="mydb", kind="postgresql")
client.datastores.start("my-team", app_id=42, datastore_id=5)
client.datastores.stop("my-team", app_id=42, datastore_id=5)
client.datastores.restart("my-team", app_id=42, datastore_id=5)
client.datastores.delete("my-team", app_id=42, datastore_id=5)
volumes
client.volumes.list("my-team", app_id=42)
client.volumes.create("my-team", app_id=42, name="uploads", mount_path="/app/uploads")
client.volumes.update("my-team", app_id=42, volume_id=3, mount_path="/app/media")
client.volumes.delete("my-team", app_id=42, volume_id=3)
cron_jobs
client.cron_jobs.list("my-team", app_id=42)
client.cron_jobs.create("my-team", app_id=42, schedule="0 * * * *", command="python manage.py clearsessions")
client.cron_jobs.update("my-team", app_id=42, cron_id=8, schedule="30 2 * * *")
client.cron_jobs.delete("my-team", app_id=42, cron_id=8)
clusters
client.clusters.list("my-team")
client.clusters.get("my-team", cluster_id=2)
client.clusters.create("my-team", name="prod-cluster")
client.clusters.delete("my-team", cluster_id=2)
servers
client.servers.list("my-team")
client.servers.get("my-team", server_id=10)

# Hetzner Cloud provisioning. Requires the team to have a stored Hetzner Cloud
# token. Server types and locations are pulled live from Hetzner.
info = client.servers.get_hetzner_cloud_info("my-team")
client.servers.create_hetzner_cloud(
    "my-team",
    location="nbg1",
    server_type="cax11",
    hetzner_backups_enabled=False,
    cluster=None,
)
invites
client.invites.list("my-team")
client.invites.create("my-team", email="[email protected]")
client.invites.delete("my-team", invite_id=4)
migrations
client.migrations.list("my-team")
client.migrations.run("my-team", app_id=42, command="python manage.py migrate")
client.migrations.logs("my-team", migration_id=99)
public_keys
client.public_keys.list()
client.public_keys.create("ssh-rsa AAAA... user@host")
client.public_keys.delete(key_id=12)

错误处理(SDK)

from appliku import (
    Appliku,
    AuthenticationError,
    AuthorizationError,
    NotFoundError,
    ValidationError,
    RateLimitError,
    ServerError,
)

client = Appliku()
try:
    client.teams.get("missing-team")
except AuthenticationError:
    print("Invalid or missing token")
except NotFoundError as exc:
    print(exc)
异常HTTP 状态
AuthenticationError401
AuthorizationError403
NotFoundError404
ValidationError400
RateLimitError429
ServerError5xx

常见工作流

查找应用并检查其最新部署
appliku teams list
appliku apps list --team my-team --output json   # grab the numeric app id
appliku deployments latest --team my-team --app 42
appliku deployments logs --team my-team --id <deployment_id>
跟踪应用日志
# All processes (default when no --process is given)
appliku apps logs --team my-team --app 42 --tail 200

# Specific processes
appliku apps logs --team my-team --app 42 --process web --process celery --tail 200
添加自定义域名并验证 DNS
appliku domains create    --team my-team --app 42 --domain example.com
appliku domains check-dns --team my-team --app 42 --domain example.com
重启数据存储
appliku datastores list    --team my-team --app 42   # get the datastore id
appliku datastores restart --team my-team --app 42 --id 5

注意事项

  • 创建不会触发部署:创建应用只会启动初始配置检查。完成设置后,请单独运行部署命令。
  • apps logs 是唯一的日志命令:它适用于服务器模式和集群模式的应用,并返回一个或多个进程的日志。它会 POST 一个请求,然后轮询直到日志就绪。(apps service-logs 仍作为 apps logs -p <service> 的弃用别名保留。)
  • --process 可重复使用且为可选参数:多次传入即可指定多个进程(--process web --process celery);完全省略该参数,则获取应用所有进程的日志。
  • 机器可读输出:需要以编程方式解析 ID 时,可在任何列表命令中添加 --output json。
  • 在 CI 中使用 APPLIKU_TOKEN:设置此环境变量,以避免在自动化环境中进行交互式登录。

评论

支持 Markdown