跳到主要内容

运维 stack

使用 almirant install 安装后,pslogsupgradedown 命令涵盖实例维护所需的全部操作。它们默认假设 stack 位于 ~/.almirant/stack/;若使用其他 --dir 安装,后续命令也应传入相同的 --dir

查看状态

almirant ps

该命令显示所有容器的状态(相当于针对 docker-compose.prod.ymldocker compose ps)。postgresredisbackendfrontendrunner 应处于 Up (healthy)。若任一显示为 ExitedRestarting,请检查其日志。

读取日志

实时跟随所有日志:

almirant logs -f

限制为某个服务(查找特定问题时更快):

almirant logs -f backend frontend

仅显示最后 N 行:

almirant logs --tail 200 backend
服务用途
backendAPI、身份验证和业务错误
frontendSSR 渲染错误、不完整构建、意外的 404
db-initschema bootstrap 和 seeds,仅在启动时运行
postgres连接错误、崩溃
runnerAI 智能体 jobs
web-bridge与前端的实时通信

升级到最新版本

almirant upgrade

升级会依次执行三步:

  1. 在 stack 目录执行 git pull
  2. 依据 .env.production.example 协调 .env.production。如果升级引入新的必需变量(例如生成的密钥或派生路径),会自动添加,且不修改原有变量。任何变更前,都会在文件旁创建 .env.production.bak.<unix-timestamp> 备份。
  3. 执行 docker compose up -d --build --force-recreate:重建镜像并重启容器,保留数据卷。

应用前检查

查看将发生的变更而不修改任何内容:

almirant upgrade --check-env

它会列出将添加到 .env.production 的变量及每个值的来源(generatedderiveddefaultempty)。不会运行 docker,也不会写入文件。

跳过 env 协调

若你使用自己的工具管理 .env.production(Ansible、sealed secrets 等),且不希望 CLI 修改文件:

almirant upgrade --no-env-sync

此时你负责让 .env.production 与 schema 保持一致。若缺少必需变量,docker compose up 会因 required variable X is missing a value 失败。

从异常同步中恢复

每次修改 .env.productionalmirant upgrade 都会留下带时间戳的备份:

ls -la ~/.almirant/stack/.env.production.bak.*
cp ~/.almirant/stack/.env.production.bak.<ts> ~/.almirant/stack/.env.production

备份不会自动轮换:它们占用空间很小,并保留每次变更的可追溯性。

仅升级特定部分

若只修改了前端,可限制范围以提升速度:

almirant upgrade frontend

可传入多个服务:almirant upgrade frontend backend

升级到特定版本

almirant upgrade --branch v1.3.0

通过 SSH 升级远程机器

如果 stack 位于其他服务器,并且希望从笔记本电脑升级它:

almirant upgrade --host [email protected]

CLI 会通过 SSH 连接并在目标机器执行 scripts/update-remote.sh。该机器必须已将仓库克隆到 ~/.almirant/stack/.env.production 协调也会在远程主机运行,因此 stack 新增必需变量后的首次升级,远程主机会像本地一样自动同步。

从仪表板一键升级

当 stack 版本包含 updater sidecar 时,如果 main 领先于正在运行的 build,管理员会在仪表板看到 "Update now" 横幅。这是供无法访问 stack 机器 shell 的管理员使用的 CLI 替代方案。

工作方式

后端通过比较自身 build SHA 与 main 来检测新版本,并向管理员显示按钮。单击后:

  1. 后端向 updater sidecar 发起 POST 请求(它位于 compose 内部网络,未暴露)。
  2. sidecar 对除 updater 自身以外的所有服务运行 git pull --ff-only origin maindocker compose buildup -d --force-recreate
  3. UI 显示进度,并在新后端响应 healthcheck 前保持在 "Restarting…"。

sidecar 被排除在 recreate 之外,因此能在自己触发的重建中存活。

按钮何时出现

  • 用户拥有 admin 角色。
  • updater sidecar 存活且可从后端访问(已配置变量 UPDATER_INTERNAL_URLUPDATER_INTERNAL_TOKEN;缺失时 almirant upgrade 会自动生成它们)。
  • main 中有领先当前 build SHA 的 commits。

若 sidecar 不可访问,管理员会看到 "Copy command" 按钮,提供可直接粘贴到 shell 的 almirant upgrade

禁用一键升级

有两种仅保留 CLI 的方式:

# A) Quitar el sidecar del compose
cd ~/.almirant/stack
# editar docker-compose.prod.yml y comentar el bloque `updater:`
docker compose -f docker-compose.prod.yml --env-file .env.production up -d
# El backend cae al fallback "Copy command" automaticamente.

# B) Mantener el sidecar pero invalidar el token
sed -i '' 's|^UPDATER_INTERNAL_TOKEN=.*|UPDATER_INTERNAL_TOKEN=|' ~/.almirant/stack/.env.production
docker compose -f docker-compose.prod.yml --env-file .env.production up -d --force-recreate backend

限制

  • 不支持选择服务:始终重建不在排除列表中的全部服务。
  • 如果重建让 stack 变为 unhealthy,不会回滚。需要更多控制时,请从 shell 使用 almirant upgrade <servicio>
  • 如果新 build 的迁移失败,db-init 非零退出会导致 backend 无法启动;你需要通过 almirant logs db-init 诊断。

对于此类情况,回退到 CLI:

almirant upgrade --host [email protected]

停止 stack

不丢失数据(常见做法;可通过 almirant upgrade 或再次 install 启动):

almirant down

删除本地镜像(以在下次安装时强制干净重建):

almirant down --rmi local

删除包括数据卷在内的所有内容(破坏性操作):

almirant down --volumes
注意

--volumes 会不可逆地删除 Postgres 和 Redis 数据。若有不希望丢失的工作,请先备份。备份策略参见源仓库中的 docs/self-hosting/backups.md

更改公开 URL

这是最敏感的变更,因为 NEXT_PUBLIC_SITE_URL 会被编译进前端 bundle。只修改 .env.production 不够。

选项 A:重新干净安装(较简单,破坏性)

如果是测试 stack 且不介意丢失数据:

almirant down --volumes
almirant install --public-url https://nueva-url.example.com

选项 B:编辑 env 并重建(保留数据)

cd ~/.almirant/stack

# 1. Edita las 4 variables relevantes en .env.production
sed -i '' \
-e 's|^NEXT_PUBLIC_SITE_URL=.*|NEXT_PUBLIC_SITE_URL=https://nueva-url.example.com|' \
-e 's|^BETTER_AUTH_URL=.*|BETTER_AUTH_URL=https://nueva-url.example.com|' \
-e 's|^BETTER_AUTH_TRUSTED_ORIGINS=.*|BETTER_AUTH_TRUSTED_ORIGINS=https://nueva-url.example.com|' \
-e 's|^CORS_ORIGIN=.*|CORS_ORIGIN=https://nueva-url.example.com|' \
.env.production

# 2. Rebuild obligatorio de frontend + backend
docker compose -f docker-compose.prod.yml --env-file .env.production \
up -d --build --force-recreate frontend backend
无需重建即可添加 origin

如果只需让 Better-Auth 接受额外 origin(例如同时允许 http://localhost:8080 和 Tailscale URL),可在 BETTER_AUTH_TRUSTED_ORIGINSCORS_ORIGIN 中使用逗号分隔多个值,并只重启 backend,无需重建:

# .env.production
BETTER_AUTH_TRUSTED_ORIGINS=http://localhost:8080,https://mimac.tailnet.ts.net
CORS_ORIGIN=http://localhost:8080,https://mimac.tailnet.ts.net
cd ~/.almirant/stack
docker compose -f docker-compose.prod.yml --env-file .env.production \
up -d --force-recreate backend

注意:前端仍会调用 bundle 中 baked 的 NEXT_PUBLIC_SITE_URL 值。若该值与访问 URL 不一致,即使 CORS 和 origin 接受请求,某些调用也会失败。若要永久修改,请完成整个选项 B

备份与恢复

实例数据位于 almirant-prod_postgres_prod_data 卷中。要在实例运行时进行备份:

docker compose -f ~/.almirant/stack/docker-compose.prod.yml --env-file ~/.almirant/stack/.env.production \
exec postgres pg_dump -U almirant -d almirant > backup-$(date +%Y%m%d).sql

请参阅源仓库文档(docs/self-hosting/backups.md)以了解更稳健的备份策略,包括轮换和发送到 S3。

更改密钥

若某个密钥泄露(例如 BETTER_AUTH_SECRETENCRYPTION_KEY):

  1. 编辑 ~/.almirant/stack/.env.production 中的值。
  2. 重启受影响服务:
cd ~/.almirant/stack
docker compose -f docker-compose.prod.yml --env-file .env.production \
up -d --force-recreate backend
注意

轮换 ENCRYPTION_KEY 会使先前加密的所有值失效(已保存的 OAuth tokens、外部集成等)。必须重新生成这些 tokens。

stack 无法启动时的处理方式

诊断顺序:

# 1. Ver que servicio esta caido
almirant ps

# 2. Logs del servicio problema
almirant logs --tail 200 <servicio>

# 3. Si es db-init (bootstrap de base de datos), es casi siempre:
# - password authentication failed → reinstalar limpio
# - Ver guia self-hosted → "Errores comunes"

# 4. Si es frontend, a menudo es build corrupto — fuerza rebuild sin cache:
cd ~/.almirant/stack
docker compose -f docker-compose.prod.yml --env-file .env.production \
build --no-cache frontend
docker compose -f docker-compose.prod.yml --env-file .env.production \
up -d --force-recreate frontend