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 等故障排障。
Azimutt 2.0 常用 CLI 命令与运维实操
目标:以服务器视角给出 Azimutt 2.0 的全部命令行运维面——Erlang release 命令族(
bin/azimutt)、npmazimuttCLI(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,gatewayhttp://192.168.1.200:8137(@azimutt/gateway0.1.26) - 元数据库:PostgreSQL 16(
192.168.1.200:5432,库azimutt;另有演示业务库demo:6 表 31 列 7 外键) - npm CLI:
azimutt0.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 CLI | schema 导出(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 实操
4.3.1 登录并拿到会话 cookie
会话 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 → 起应用。
五、注意事项
- eval 与 rpc 别混用:eval 系统未启动应用(Repo 不可用),一切查库/改库用 rpc;
- 密码 12~72 位是组件强制策略,rpc 重置同样受
password_changeset校验; - http 下 curl 会话 cookie 不落盘(
Secure; SameSite=None),API 实操一律手动拼Cookie:头; storage_kind=local的项目 schema 存在浏览器端,应用目录bin/uploads为空属正常,备份以元数据库为准;- npm CLI 输出自带 ASCII 横幅,管道解析先跳横幅;
main滚动发布,任何升级后用bin/azimutt version核对构建号(见部署篇 9 节 digest 回滚法)。
六、常见问题
| 症状 | 原因与解法 |
|---|---|
ERROR: Unknown command ping | release 命令族只有 usage 列出的 11 个(4.1.1),拼写/大小写核对 |
eval 里 Azimutt.Repo 报 Repo not started | eval 不启动应用,改用 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 found | 0.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 介绍与选型指南》:定位与版本生态
- 《Azimutt Docker Compose 部署指南》:部署、登录验证与 digest 回滚
- 《Azimutt 2.0 配置参数详解》:环境变量族与生效机制
- 官方 CLI 文档:https://docs.azimutt.app/cli (WIP)与 npm 包页 https://www.npmjs.com/package/azimutt
- Erlang release 概念:https://www.erlang.org/doc/system/releases.html
- pg_dump / pg_restore 手册:https://www.postgresql.org/docs/current/app-pgdump.html