Azimutt 2.0 常用 CLI 命令与运维实操

Azimutt 2.0 命令行运维全解(2026-11-03 实测):Erlang release 命令族 bin/azimutt(version/pid/eval/rpc/stop 与密码重置)、npm azimutt CLI 0.1.39(export 实测回显与参数表)、项目 REST API 登录建项目 201、gateway schema/query、元数据库 pg_dump/pg_restore 备份恢复与 eval-rpc/CSRF/400 等故障排障。

AzimuttAzimuttCLI命令运维运维CLIPostgreSQL2026/11/03

Azimutt 2.0 常用 CLI 命令与运维实操

目标:以服务器视角给出 Azimutt 2.0 的全部命令行运维面——Erlang release 命令族(bin/azimutt)、npm azimutt CLI(export 实测)、项目 REST API 实操(登录→建项目→gateway schema/query)、元数据库备份恢复与真实故障排障,命令与回显均逐行实测(2026-11-03)。

一、环境信息

  • 应用:Azimutt 2.0(release 构建号 2.0.1787693602,OTP 25 / Elixir 1.14.3 / ERTS 13.1.4),安装目录 /opt/azimutt/app
  • 入口:应用 http://192.168.1.200:8136,gateway http://192.168.1.200:8137(@azimutt/gateway 0.1.26)
  • 元数据库:PostgreSQL 16(192.168.1.200:5432,库 azimutt;另有演示业务库 demo:6 表 31 列 7 外键)
  • npm CLI:azimutt 0.1.39(Node.js 20 下经 npx 调用)
  • 示例账号:admin@azimutt.local / q1w2e3r4q1w2(Azimutt 强制密码 12~72 位,故演示口令为 12 位)

二、工具总览

工具形态用途
/opt/azimutt/app/bin/azimutt应用自带 release 命令行启停、版本核对、运行时求值(eval/rpc/remote)、密码重置
npx azimutt(npm 包 0.1.39)Node.js CLIschema 导出(export)、本地起 gateway、库分析(analyze/explore/diff)
REST API(curl)应用 HTTP 接口组织/项目查询与创建(会话 cookie 鉴权)
psql / pg_dump / pg_restore数据库自带工具元数据库整库备份与恢复

三、前置准备

  • 应用安装目录可写、进程在跑(pid 有输出即活);
  • REST API 实操需先登录拿会话 cookie(见 4.3.1,http 场景要手动拼 Cookie 头);
  • npm CLI 需要 Node.js 20+;
  • 备份恢复在数据库服务器上执行,需 postgres 角色口令。

四、各工具详解

4.1 release 命令族 /opt/azimutt/app/bin/azimutt

4.1.1 usage 全量(实测)

$ /opt/azimutt/app/bin/azimutt
Usage: azimutt COMMAND [ARGS]

The known commands are:

    start          Starts the system
    start_iex      Starts the system with IEx attached
    daemon         Starts the system as a daemon
    daemon_iex     Starts the system as a daemon with IEx attached
    eval "EXPR"    Executes the given expression on a new, non-booted system
    rpc "EXPR"     Executes the given expression remotely on the running system
    remote         Connects to the running system via a remote shell
    restart        Restarts the running system via a remote command
    stop           Stops the running system via a remote command
    pid            Prints the operating system PID of the running system via a remote command
    version        Prints the release name and version to be booted

Azimutt 是标准 Erlang release:start/daemon 系启动命令(前台/后台,可附 IEx),eval/rpc/remote 系求值命令,restart/stop/pid 系进程控制命令。

4.1.2 version 与 pid

$ /opt/azimutt/app/bin/azimutt version
azimutt 2.0.1787693602
$ /opt/azimutt/app/bin/azimutt pid
65

version 打印「将被启动的 release 名与版本」——官方发布无版本化 tag,这个 2.0.<Unix 秒> 构建号就是唯一的版本凭证,升级前后各打一次即可确认是否真的换版。

4.1.3 eval:新起未启动系统求值

$ /opt/azimutt/app/bin/azimutt eval 'IO.puts(inspect(:erlang.system_info(:otp_release)) <> " / " <> inspect(System.version))'
Setup Local file storage
Setup Local email provider
Setup Password auth
'25' / "1.14.3"

注意两点:输出前的三行 Setup 是 runtime.exs 装配痕迹(eval 也会完整走配置装配);eval 的系统未启动应用,Azimutt.Repo 等进程不在,访问数据库会报 Repo not started——查库必须用 rpc。

4.1.4 rpc:对运行中系统求值

$ /opt/azimutt/app/bin/azimutt rpc 'IO.puts("rpc-ok")'
rpc-ok
$ /opt/azimutt/app/bin/azimutt rpc 'IO.puts(Azimutt.Repo.aggregate(Azimutt.Accounts.User, :count, :id) |> inspect())'
1

rpc 直接挂上在跑的节点,无 Setup 输出、可用全部进程。忘记密码重置实操:

$ /opt/azimutt/app/bin/azimutt rpc 'u=Azimutt.Repo.get_by!(Azimutt.Accounts.User,[email:"admin@azimutt.local"]); cs=Azimutt.Accounts.User.password_changeset(u,%{password:"q1w2e3r4q1w2",password_confirmation:"q1w2e3r4q1w2"}); {:ok,r}=Azimutt.Repo.update(cs); IO.puts("OK "<>r.email)'
OK admin@azimutt.local

口令仍受 12~72 位校验约束;改完即可登录。

4.1.5 remote / restart / stop / start

  • remote:进入运行系统的远程 shell(IEx),交互式排障用;
  • restart / stop:经远程命令重启/停止运行系统。实测 stop 成功时无任何输出,随后端口即失联(curl 返回 000),再 start 或进程管理器拉起即恢复;
  • daemon:以守护方式启动,配合 pid 轮询存活。

4.1.6 未知命令

$ /opt/azimutt/app/bin/azimutt ping
Usage: azimutt COMMAND [ARGS]

The known commands are:

    start          Starts the system
    start_iex      Starts the system with IEx attached
    daemon         Starts the system as a daemon
    daemon_iex     Starts the system as a daemon with IEx attached
    eval "EXPR"    Executes the given expression on a new, non-booted system
    rpc "EXPR"     Executes the given expression remotely on the running system
    remote         Connects to the running system via a remote shell
    restart        Restarts the running system via a remote command
    stop           Stops the running system via a remote command
    pid            Prints the operating system PID of the running system via a remote command
    version        Prints the release name and version to be booted

ERROR: Unknown command ping

4.2 npm azimutt CLI(0.1.39)

4.2.1 版本与横幅

$ npx azimutt --version
     _            _                       _     _                               
    / \     ____ (_)  _ __ ___    _   _  | |_  | |_        __ _   _ __    _ __  
   / _ \   |_  / | | | '_ ` _ \  | | | | | __| | __|      / _` | | '_ \  | '_ \ 
  / ___ \   / /  | | | | | | | | | |_| | | |_  | |_   _  | (_| | | |_) | | |_) |
 /_/   \_\ /___| |_| |_| |_| |_|  \__,_|  \__|  \__| (_)  \__,_| | .__/  | .__/ 
                                                                 |_|     |_|    
Version 0.1.39

0.1.39

每次调用都会先打印 ASCII 横幅与 Version 0.1.39,脚本解析输出时要跳过横幅段。

4.2.2 命令总表(--help 实测全文)

Usage: azimutt [options] [command]

Export database schema from relational or document databases. Import it to
https://azimutt.app.
- export database schemas from PostgreSQL, MongoDB and Couchbase

Options:
  -V, --version                        output the version number
  -h, --help                           display help for command

Commands:
  gateway [options] [datasource_urls]  Launch the gateway server to allow
                                       Azimutt to access your local databases.
  explore [options] <url>              Open Azimutt with your database url to
                                       see it immediately.
  analyze [options] <url>              Analyze your database and give
                                       improvement suggestions.
  export [options] <url>               Export a database schema in a file to
                                       easily import it in Azimutt.
                                       Works with BigQuery, Couchbase, MariaDB,
                                       MongoDB, MySQL, PostgreSQL,
                                       Snowflake..., issues and PR are welcome
                                       in https://github.com/azimuttapp/azimutt
                                       ;)
  convert [options] <path>             A dialect to an other
  diff [options] <url_old> <url_new>   Compare the schema of two databases
  clustering [options] <url>           WIP
  help [command]                       display help for command

Snowflake...、clustering ... WIP 均为产品原文。日常运维主力是 export(离线导 schema)与 gateway(本地一键起数据面)。

4.2.3 export 选项(export --help 实测全文)

Usage: azimutt export [options] <url>

Export a database schema in a file to easily import it in Azimutt.
Works with BigQuery, Couchbase, MariaDB, MongoDB, MySQL, PostgreSQL,
Snowflake..., issues and PR are welcome in
https://github.com/azimuttapp/azimutt ;)

Arguments:
  url                            the url to connect to the source, including
                                 credentials

Options:
  -d, --database <database>      Limit to a specific database (ex for MongoDB),
                                 works with LIKE syntax
  -c, --catalog <catalog>        Limit to a specific catalog (ex for
                                 Snowflake), works with LIKE syntax
  -s, --schema <schema>          Limit to a specific schema (ex for
                                 PostgreSQL), works with LIKE syntax
  -e, --entity <entity>          Limit to a specific entity (ex for
                                 PostgreSQL), works with LIKE syntax
  -b, --bucket <bucket>          Limit to a specific bucket (ex for Couchbase),
                                 works with LIKE syntax
  --sample-size <number>         Number of items used to infer a schema
                                 (default: 10)
  -m, --mixed-json <field>       When collection have mixed documents typed by
                                 a field
  --infer-json-attributes        Infer schema on json attributes
  --infer-polymorphic-relations  Infer polymorphic relations
  --infer-relations              Infer relations using column names
  --ignore-errors                Do not stop export on errors, just log them
  --log-queries                  Log queries when executing them
  -f, --format <format>          Output format (default: "json")
  -o, --output <output>          Path to write the schema, ex: ~/azimutt.json
  --debug                        Add debug logs and show the full stacktrace
                                 instead of a shorter error
  -h, --help                     display help for command

PostgreSQL 场景常用组合:-s public 限定 schema、--infer-relations 按列名补外键缺失的关系、-o 指定输出文件。

4.2.4 export 实测(对演示库 demo)

$ npx azimutt export "postgresql://postgres:q1w2e3r4@192.168.1.200:5432/demo" -o demo2.azimutt.json
     _            _                       _     _                               
    / \     ____ (_)  _ __ ___    _   _  | |_  | |_        __ _   _ __    _ __  
   / _ \   |_  / | | | '_ ` _ \  | | | | | __| | __|      / _` | | '_ \  | '_ \ 
  / ___ \   / /  | | | | | | | | | |_| | | |_  | |_   _  | (_| | | |_) | | |_) |
 /_/   \_\ /___| |_| |_| |_| |_|  \__,_|  \__|  \__| (_)  \__,_| | .__/  | .__/ 
                                                                 |_|     |_|    
Version 0.1.39

Exporting database schema from postgresql://postgres:q1w2e3r4@192.168.1.200:5432/demo ...
Connected to the database ...
Found 6 tables ...
Found 31 columns ...
Found 9 constraints ...
Found 4 indexes ...
Found 7 relations ...
Found 0 types ...
✔︎ Exported 6 tables, 7 relations and 0 types from the database!
Export done in 73 ms.
Writing schema to demo2.azimutt.json file ...

PostgreSQL schema written in 'demo2.azimutt.json'.
Found 6 tables in 1 schema.
You can now import this file in ▶︎ https://azimutt.app/new?json ◀︎︎

导出的 JSON 可在 Azimutt 新建项目页 ?json 入口导入,全程业务库不出内网。

4.3 项目 REST API 实操

会话 cookie _azimutt_key 带 Secure; SameSite=None,curl 走 http 时 cookie jar 不落盘,需从响应头手动提取(详见部署篇 《Azimutt Docker Compose 部署指南》 10.1):

$ curl -s -D get.hdr -o login.html http://192.168.1.200:8136/login
$ TOK=$(grep -oE 'name="_csrf_token"[^>]*value="[^"]+"' login.html | sed -E 's/.*value="([^"]+)".*/\1/' | head -1)
$ CK=$(grep -i 'set-cookie: _azimutt_key' get.hdr | sed -E 's/.*_azimutt_key=([^;]+).*/_azimutt_key=\1/')
$ curl -s -H "Cookie: $CK" -D login2.hdr -o /dev/null -X POST http://192.168.1.200:8136/login \
  --data-urlencode _utf8=✓ --data-urlencode "_csrf_token=$TOK" \
  --data-urlencode 'user[email]=admin@azimutt.local' \
  --data-urlencode 'user[password]=q1w2e3r4q1w2'
$ grep -iE '^(HTTP|location)' login2.hdr
HTTP/1.1 302 Found
location: /home
$ SCK=$(grep -i 'set-cookie: _azimutt_key' login2.hdr | tail -1 | sed -E 's/.*_azimutt_key=([^;]+).*/_azimutt_key=\1/')

4.3.2 查组织与项目

$ curl -s -H "Cookie: $SCK" http://192.168.1.200:8136/api/v1/organizations
[{"description":null,"id":"32170407-49ef-4e66-ab0f-44214d50eaf3","name":"admin","slug":"admin"}]
$ curl -s -H "Cookie: $SCK" http://192.168.1.200:8136/api/v1/organizations/32170407-49ef-4e66-ab0f-44214d50eaf3/projects
[{"name":"demo-shop","id":"4d40deb4-3df6-48d9-be54-76636daf6c65","slug":"demo-shop","organization_id":"32170407-49ef-4e66-ab0f-44214d50eaf3","storage_kind":"local","nb_sources":1,"nb_tables":6,"nb_columns":31,"nb_relations":7,"nb_types":0,"nb_comments":0,"nb_layouts":0,"nb_notes":0,"nb_memos":0,"created_at":"2026-11-03T01:55:54Z","updated_at":"2026-11-03T01:55:54Z","imported_at":"2026-11-03T01:55:54Z","visibility":"private","default_source":null,"archived":false}]

4.3.3 创建项目(实测 201)

计数类字段(nb_tables 等)必须齐给,body 口径:

$ curl -s -w 'code=%{http_code}\n' -X POST -H "Cookie: $SCK" -H "Content-Type: application/json" \
  -d '{"name":"demo-shop","description":"演示电商库 demo","storage_kind":"local","encoding_version":2,"nb_sources":1,"nb_tables":6,"nb_columns":31,"nb_relations":7,"nb_types":0,"nb_comments":0,"nb_layouts":0,"nb_notes":0,"nb_memos":0}' \
  http://192.168.1.200:8136/api/v1/organizations/32170407-49ef-4e66-ab0f-44214d50eaf3/projects
code=201

响应体(即 4.3.2 看到的 demo-shop 记录):

{"archived_at":null,"created_at":"2026-11-02T23:22:29.751455Z","description":"演示电商库 demo","encoding_version":2,"id":"4d40deb4-3df6-48d9-be54-76636daf6c65","name":"demo-shop","nb_columns":31,"nb_comments":0,"nb_layouts":0,"nb_memos":0,"nb_notes":0,"nb_relations":7,"nb_sources":1,"nb_tables":6,"nb_types":0,"slug":"demo-shop","storage_kind":"local","updated_at":"2026-11-02T23:22:29.751455Z","visibility":"none"}

反例:body 只给 name/description(漏全部计数)实测直接 500:

$ curl -s -o /dev/null -w "code=%{http_code}\n" -X POST -H "Cookie: $SCK" -H "Content-Type: application/json" \
  -d '{"name":"bad-proj","description":"缺计数"}' \
  http://192.168.1.200:8136/api/v1/organizations/32170407-49ef-4e66-ab0f-44214d50eaf3/projects
code=500
$ curl -s -X POST -H "Cookie: $SCK" -H "Content-Type: application/json" \
  -d '{"name":"bad-proj","description":"缺计数"}' \
  http://192.168.1.200:8136/api/v1/organizations/32170407-49ef-4e66-ab0f-44214d50eaf3/projects
{"error":"Internal Server Error","message":"can't insert project","statusCode":500}

4.3.4 gateway schema / query(数据面验证)

参数名是 url(完整 URL 含凭据),不是 connection:

$ curl -s http://192.168.1.200:8137/health
{"status":200,"version":"x.y.z"}
$ curl -s -X POST http://192.168.1.200:8137/gateway/schema -H "Content-Type: application/json" \
  -d '{"url":"postgresql://postgres:q1w2e3r4@192.168.1.200:5432/demo"}' | head -c 200
{"tables":[{"schema":"public","table":"categories","columns":[{"name":"id","type":"bigint","default":"nextval('categories_id_seq'::regclass)"},{"name":"name","type":"character varying(100)"},{"name":"
$ curl -s -X POST http://192.168.1.200:8137/gateway/schema -H "Content-Type: application/json" \
  -d '{"url":"postgresql://postgres:q1w2e3r4@192.168.1.200:5432/demo"}' | python3 -c 'import json,sys; d=json.load(sys.stdin); print("tables:",len(d["tables"]),"relations:",len(d["relations"]),"types:",len(d["types"]))'
tables: 6 relations: 7 types: 0
$ curl -s -X POST http://192.168.1.200:8137/gateway/query -H "Content-Type: application/json" \
  -d '{"url":"postgresql://postgres:q1w2e3r4@192.168.1.200:5432/demo","query":"select id, sku, title, price from products order by id limit 5"}'
{"query":"select id, sku, title, price from products order by id limit 5","columns":[{"name":"id","ref":{"table":"public.products","column":"id"}},{"name":"sku","ref":{"table":"public.products","column":"sku"}},{"name":"title","ref":{"table":"public.products","column":"title"}},{"name":"price","ref":{"table":"public.products","column":"price"}}],"rows":[{"id":1,"sku":"B-001","title":"The Elixir Book","price":"39.90"},{"id":2,"sku":"E-001","title":"USB-C Hub","price":"25.00"}]}

4.4 元数据库备份与恢复

以下在数据库服务器上执行。整库自定义格式备份:

$ pg_dump -U postgres -Fc azimutt -f /tmp/azimutt_backup.dump
$ ls -l /tmp/azimutt_backup.dump
-rw-r--r-- 1 root root 52323 Nov  3 02:41 /tmp/azimutt_backup.dump

恢复到新库验证完整性:

$ psql -U postgres -c "CREATE DATABASE azimutt_restore;"
CREATE DATABASE
$ pg_restore -U postgres -d azimutt_restore /tmp/azimutt_backup.dump
$ psql -U postgres -d azimutt_restore -t -c "select count(*) from users"
     1

$ psql -U postgres -d azimutt_restore -t -c "select count(*) from projects"
     1

$ psql -U postgres -c "DROP DATABASE azimutt_restore;"
DROP DATABASE

要点:pg_restore 必须带 -U postgres(缺省按当前系统用户名找角色,实测报 FATAL: role "root" does not exist);DROP DATABASE 不能与别的语句同一条 -c(实测 ERROR: DROP DATABASE cannot run inside a transaction block),须单独执行。生产恢复覆盖原库时:先停应用 → pg_restore -U postgres --clean --if-exists -d azimutt /tmp/azimutt_backup.dump → 起应用。

五、注意事项

  1. eval 与 rpc 别混用:eval 系统未启动应用(Repo 不可用),一切查库/改库用 rpc;
  2. 密码 12~72 位是组件强制策略,rpc 重置同样受 password_changeset 校验;
  3. http 下 curl 会话 cookie 不落盘(Secure; SameSite=None),API 实操一律手动拼 Cookie: 头;
  4. storage_kind=local 的项目 schema 存在浏览器端,应用目录 bin/uploads 为空属正常,备份以元数据库为准;
  5. npm CLI 输出自带 ASCII 横幅,管道解析先跳横幅;
  6. main 滚动发布,任何升级后用 bin/azimutt version 核对构建号(见部署篇 9 节 digest 回滚法)。

六、常见问题

症状原因与解法
ERROR: Unknown command pingrelease 命令族只有 usage 列出的 11 个(4.1.1),拼写/大小写核对
eval 里 Azimutt.Repo 报 Repo not startedeval 不启动应用,改用 rpc(4.1.3/4.1.4)
登录 POST 返回 403未带会话 cookie 或 CSRF token 失效:手动拼 Cookie: $CK 且 token 取自同一次 GET(4.3.1)
gateway 返回 {"error":"Bad Request"}(400)参数名写成 connection,正确是 url(实测 400)
gateway 返回 404 Route GET:/net/inspect not found0.1.26 路由为 /gateway/schema、/gateway/query、/gateway/column-stats、/gateway/table-stats、/gateway/parse-url、/health、/ping、/status,旧 /net/inspect 已移除
建项目 500 can't insert project计数 body 字段不齐(4.3.3 反例),按 201 口径补全
pg_restore 报 role "root" does not exist缺 -U postgres(4.4)

七、参考链接

Azimutt 2.0 常用 CLI 命令与运维实操 - Quzuo