Operar el stack
Una vez instalado con almirant install, los comandos ps, logs, upgrade y down cubren todo lo que necesitas para mantener la instancia.
Todos asumen que el stack vive en ~/.almirant/stack/. Si lo instalaste con --dir distinto, pasa el mismo --dir a los comandos siguientes.
Ver el estado
almirant ps
Muestra el estado de todos los contenedores (equivalente a docker compose ps contra docker-compose.prod.yml). Te interesa que postgres, redis, backend, frontend y runner esten en Up (healthy). Si alguno aparece como Exited o Restarting, revisa sus logs.
Leer logs
Seguir todos los logs en tiempo real:
almirant logs -f
Limitar a un servicio (mas rapido cuando buscas algo especifico):
almirant logs -f backend frontend
Solo las ultimas N lineas:
almirant logs --tail 200 backend
Servicios utiles:
| Servicio | Para que |
|---|---|
backend | Errores de API, autenticacion, negocio |
frontend | Errores de render SSR, build incompleto, 404 inesperados |
db-init | Bootstrap de esquema y seeds — solo vive al arranque |
postgres | Errores de conexion, crashes |
runner | Jobs de agentes IA |
web-bridge | Comunicacion en tiempo real con el frontend |
Actualizar a la ultima version
almirant upgrade
El upgrade hace tres pasos en orden:
git pullen el directorio del stack.- Reconciliacion de
.env.productioncontra.env.production.example. Si el upgrade introdujo variables nuevas obligatorias (ej. un secreto generado, una ruta derivada), se anaden automaticamente sin tocar las que ya tenias. Antes de cualquier cambio se escribe un backup.env.production.bak.<unix-timestamp>al lado del archivo. docker compose up -d --build --force-recreate: rebuild de imagenes y restart de contenedores. Los volumenes de datos se conservan.
Inspeccionar antes de aplicar
Para ver que cambiaria sin tocar nada:
almirant upgrade --check-env
Lista las variables que se anadirian a .env.production y de donde vendria cada valor (generated, derived, default, empty). No corre docker, no escribe el archivo.
Saltarse la reconciliacion de env
Si gestionas .env.production con tu propio tooling (Ansible, sealed secrets, etc.) y queres que el CLI no toque el archivo:
almirant upgrade --no-env-sync
En ese caso quedas responsable de mantener .env.production coherente con el schema. Si te falta una variable obligatoria, docker compose up fallara con required variable X is missing a value.
Recuperar de un sync que metio algo raro
Cada almirant upgrade que modifica .env.production deja un backup con timestamp:
ls -la ~/.almirant/stack/.env.production.bak.*
cp ~/.almirant/stack/.env.production.bak.<ts> ~/.almirant/stack/.env.production
Los backups no se rotan automaticamente — ocupan poco y dejan trazabilidad de cada cambio.
Actualizar solo partes concretas
Si sabes que solo cambio el frontend, limitalo para ir mas rapido:
almirant upgrade frontend
Puedes pasar varios servicios: almirant upgrade frontend backend.
Actualizar a una version concreta
almirant upgrade --branch v1.3.0
Actualizar una maquina remota via SSH
Si el stack vive en otro servidor y quieres actualizarlo desde tu portatil:
almirant upgrade --host [email protected]
El CLI se conecta por SSH y ejecuta scripts/update-remote.sh en la maquina destino. Requiere que esa maquina tenga el repo ya clonado en ~/.almirant/stack/. La reconciliacion de .env.production tambien corre en el host remoto, asi que la primera vez que actualices despues de que el stack haya anadido nuevas variables obligatorias, el remoto se autosincroniza igual que el local.
Click-to-update desde el dashboard
A partir de la version del stack que incluye el sidecar updater, los administradores ven un banner "Update now" en el dashboard cuando main esta por delante del build corriendo. Es una alternativa al CLI para administradores que no tienen acceso shell a la maquina del stack.
Como funciona
El backend detecta una nueva version comparando su SHA de build contra main. Cuando lo hace, expone un boton al admin. Al pulsarlo:
- El backend hace POST al sidecar
updater(vive en la red interna del compose, no expuesto). - El sidecar corre
git pull --ff-only origin main+docker compose build+up -d --force-recreatepara todos los servicios excepto el propio updater. - La UI muestra progreso y queda en "Restarting…" hasta que el backend nuevo responde a healthchecks.
El sidecar se excluye del recreate para sobrevivir al rebuild que el mismo dispara.
Cuando se ve el boton
- El usuario tiene rol admin.
- El sidecar
updateresta vivo y accesible desde el backend (variablesUPDATER_INTERNAL_URLyUPDATER_INTERNAL_TOKENconfiguradas — elalmirant upgradelas genera automaticamente cuando faltan). - Hay commits en
mainpor delante del SHA de build actual.
Si el sidecar no esta accesible, los admins ven en su lugar un boton "Copy command" que te da el almirant upgrade listo para pegar en una shell.
Desactivar el click-to-update
Dos formas de quedarte solo con el 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
Limitaciones
- No selecciona servicios — siempre rebuildea todo lo que no este en la lista de exclusion.
- No hace rollback si el rebuild deja al stack unhealthy. Para mas control usa
almirant upgrade <servicio>desde shell. - Si una migracion del nuevo build falla, el
db-initexit no-cero deja al backend sin arrancar y tienes que diagnosticar viaalmirant logs db-init.
Para esos casos, fallback al CLI:
almirant upgrade --host [email protected]
Parar el stack
Sin perder datos (lo habitual — puedes volver a arrancar con almirant upgrade o un nuevo install):
almirant down
Borrando imagenes locales (para forzar rebuild limpio en el siguiente install):
almirant down --rmi local
Borrando todo incluyendo volumenes de datos (destructivo):
almirant down --volumes
--volumes elimina los datos de Postgres y Redis de forma irreversible. Si tienes trabajo que no quieres perder, haz backup antes. Ver docs/self-hosting/backups.md en el repo fuente para la estrategia de backup.
Cambiar la URL publica
Este es el cambio mas delicado porque NEXT_PUBLIC_SITE_URL se compila dentro del bundle del frontend. Cambiar solo .env.production no basta.
Opcion A — reinstalar limpio (mas simple, destructivo)
Si el stack es de test y no te importa perder datos:
almirant down --volumes
almirant install --public-url https://nueva-url.example.com
Opcion B — editar env y rebuildear (conserva datos)
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
Si solo necesitas que Better-Auth acepte un origin adicional (p. ej. permitir a la vez http://localhost:8080 y tu URL de Tailscale), puedes listar varios separados por coma en BETTER_AUTH_TRUSTED_ORIGINS y CORS_ORIGIN, y reiniciar solo el backend sin rebuild:
# .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
Ojo: el frontend seguira haciendo llamadas al valor de NEXT_PUBLIC_SITE_URL baqueado en el bundle. Si ese valor no coincide con la URL desde la que accedes, algunas llamadas fallaran aunque CORS y origin acepten la peticion. Para un cambio definitivo, sigue la Opcion B completa.
Backup y restauracion
Los datos de la instancia viven en el volumen almirant-prod_postgres_prod_data. Para hacer un backup con la instancia corriendo:
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
Consulta la doc del repo fuente (docs/self-hosting/backups.md) para estrategias de backup mas robustas, incluyendo rotacion y envio a S3.
Cambiar secretos
Si un secreto se compromete (por ejemplo BETTER_AUTH_SECRET o ENCRYPTION_KEY):
- Edita el valor en
~/.almirant/stack/.env.production. - Reinicia los servicios afectados:
cd ~/.almirant/stack
docker compose -f docker-compose.prod.yml --env-file .env.production \
up -d --force-recreate backend
Rotar ENCRYPTION_KEY invalida cualquier valor cifrado previamente (tokens OAuth guardados, integraciones externas, etc.). Esos tokens hay que volver a generarlos.
Que hacer si el stack no arranca
Secuencia de diagnostico:
# 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