SVSANNVIT
Primeros pasos

Alojamiento con Docker

Ejecute la pila completa de Sannvit Ledger — Postgres, Keycloak, la API del ledger, almacenamiento de blobs y el dashboard — con Docker Compose.

Docker Compose es la forma más rápida de ejecutar una instancia de Sannvit Ledger, ya sea un entorno de desarrollo local o un despliegue de producción en un único host. Todo lo que sigue asume que ya ha clonado el repositorio.

Requisitos previos

  • Docker + Docker Compose
  • Node.js — para aplicar las migraciones de la base de datos y (opcionalmente) desarrollo nativo fuera de contenedores

Qué contienen los ficheros de compose

La pila se divide en un fichero base más overrides que se van añadiendo según se necesiten:

ServicioFichero de composeQué es
dbdocker-compose.ymlUn postgres:17 sin más — la única base de datos de la pila
keycloakdocker-compose.keycloak.ymlAutenticación — Direct Access Grant, sin UI de login alojada
api / alertingdocker-compose.api.ymlEl servicio de ingesta, más su ejecutor independiente de integridad/alertas como un segundo contenedor
dashboarddocker-compose.dashboard.ymlLa interfaz de navegador
rustfsdocker-compose.rustfs.ymlAlmacén de blobs compatible con S3 incluido — opcional, vea Aporte su propio almacenamiento compatible con S3
maildocker-compose.mail.ymlCapturador SMTP solo para desarrollo (Mailpit) para que los correos de invitación/restablecimiento/alerta lleguen a algún sitio visible
nginx / caddydocker-compose.nginx.yml / docker-compose.caddy.ymlProxy inverso opcional con terminación TLS delante de los subdominios app. / api. / auth.

La aplicación habla directamente con Postgres sin más, y Keycloak gestiona la autenticación — sin servicios adicionales en medio — lo que mantiene la huella lo bastante pequeña como para instalarla en la propia infraestructura de un cliente.

1. Configure su entorno

.env vive en la raíz del repositorio y lo lee cada fichero de compose.

cp .env.example .env

Como mínimo, rellene estos secretos antes de arrancar nada — openssl rand -hex 24 para cada uno:

  • POSTGRES_PASSWORD
  • JWT_SECRET
  • KEYCLOAK_ADMIN_PASSWORD
  • KEYCLOAK_SERVICE_CLIENT_SECRET
  • S3_ROOT_PASSWORD (solo necesario si usa el almacén de blobs incluido)
  • EXPORT_SECRET_KEY (solo necesario antes de usar la función de exportación de paquetes de evidencia por SFTP)

Para trabajo local, unos valores solo de desarrollo son suficientes — simplemente no los reutilice en ningún entorno real.

2. Levante la pila

Desarrollo

docker/run.sh gestiona qué ficheros de override de compose están activos y siempre lee .env desde la raíz del repositorio, sin importar el directorio de trabajo de su shell:

cd docker
./run.sh config add keycloak rustfs mail api api.dev dashboard dashboard.dev
./run.sh start

api.dev / dashboard.dev añaden recarga en caliente (código montado por bind mount, tsx watch / HMR de Nuxt) sobre sus servicios base.

Producción (un único host)

npm run prod

que equivale a:

cd docker
COMPOSE_FILE=docker-compose.yml:docker-compose.keycloak.yml:docker-compose.rustfs.yml:docker-compose.api.yml:docker-compose.dashboard.yml \
COMPOSE_ENV_FILES=../.env COMPOSE_IGNORE_ORPHANS=true \
docker compose up -d --wait --build

!WARNING Antes de hacer esto en un entorno real:

  • Los valores de .env.example son marcadores de posición, no secretos — establezca valores reales y únicos para cada entrada listada arriba.
  • Ponga delante un proxy inverso real con terminación TLS (docker-compose.nginx.yml o .caddy.yml) en lugar de exponer los puertos de servicio en crudo, y establezca PROXY_DOMAIN en .env.
  • Cambie el secreto del cliente ledger-service de Keycloak respecto al valor de desarrollo por defecto de la exportación del realm (docker/volumes/keycloak/ledger-realm.json) desde la consola de administración de Keycloak, y actualice KEYCLOAK_SERVICE_CLIENT_SECRET en .env para que coincida.
  • Apunte SMTP_* a un relay real en lugar de Mailpit, y establezca DASHBOARD_URL al dominio público real del dashboard — vea Correo electrónico (SMTP) más abajo.
  • Configure procedimientos de copia de seguridad adecuados para el volumen de db.

3. Aplique el esquema de la base de datos

Este es un paso único por cada base de datos nueva — no forma parte de run.sh start. Espere a que db y keycloak reporten estar saludables (./run.sh status), y luego, desde la raíz del repositorio:

for f in api/drizzle/0*.sql; do
  psql -h localhost -U postgres -d postgres -v ON_ERROR_STOP=1 -f "$f"
done

cd api
npm install
npm run db:functions   # aplica src/db/functions/*.sql — no son objetos de drizzle-kit
npm run seed:demo      # org de demo + equipo + clave de ingesta (la clave se imprime una vez, guárdela)

No hay un usuario de dashboard sembrado — seed:demo solo crea una org/equipo/clave de ingesta de demo para el lado del SDK. Para obtener un login humano, en su lugar arranque el primer administrador (desde api/, una vez que db y keycloak estén activos y las migraciones aplicadas):

npm run seed:admin -- you@example.com --org-name="Your Org Name"

Esto imprime una contraseña generada una sola vez. Cada usuario posterior se invita a través del dashboard (Organization → Users → Invite) por un compliance_admin ya existente, no mediante este script.

4. Ya está en marcha

  • Dashboard — http://localhost:3000
  • Ledger API — http://localhost:4010 (GET /healthz)
  • Admin de Keycloak — http://localhost:8180
  • Mailpit (capturador de correo de desarrollo) — http://localhost:8025
  • Consola del almacén de blobs — http://localhost:9001 (RustFS incluido, si lo mantuvo)

Comandos útiles de run.sh

./run.sh logs [service]     # seguir logs
./run.sh status             # docker compose ps
./run.sh recreate [service] # forzar recreación de un servicio
./run.sh stop                # detener todo

Invocar docker compose directamente en lugar de run.sh requiere especificar el fichero de entorno de forma explícita, por ejemplo desde la raíz del repositorio:

docker compose --env-file .env -f docker/docker-compose.yml -f docker/docker-compose.keycloak.yml up -d

Aporte su propio almacenamiento compatible con S3

Por defecto la pila incluye un contenedor RustFS como almacén de blobs para el contenido de los payloads — el propio ledger solo guarda un puntero + hash. Si prefiere apuntar a un bucket ya existente (AWS S3, Cloudflare R2, Backblaze B2, su propio MinIO/RustFS, etc.):

  1. No añada el override rustfs — omita ./run.sh config add rustfs, o ejecute ./run.sh config remove rustfs si ya estaba añadido.
  2. En .env, establezca S3_ENDPOINT, S3_PORT, S3_USE_SSL, y opcionalmente S3_REGION con los del proveedor externo, y S3_ACCESS_KEY / S3_SECRET_KEY con credenciales acotadas a ese bucket. Establezca LEDGER_BUCKET con el nombre del bucket.
  3. El bucket se crea de forma perezosa en la primera subida si aún no existe, así que puede pre-crearlo o conceder a las credenciales dadas el permiso CreateBucket.

El segundo plano de integridad append-only es un segundo bucket (LEDGER_INTEGRITY_BUCKET, por defecto ledger-integrity) en el mismo endpoint, creado con S3 Object Lock activado — imborrable durante su ventana de retención, incluso para administradores.

!CAUTION El contenedor RustFS incluido tiene errores abiertos en su implementación de Object Lock. Eso está bien para desarrollo, pero los despliegues de producción deberían apuntar LEDGER_INTEGRITY_BUCKET a una implementación madura de Object Lock mediante la vía de traer su propio S3 — AWS S3 real, Backblaze B2, o GCS vía interoperabilidad con S3.

Correo electrónico (SMTP)

La API del ledger envía correos de invitación, restablecimiento de contraseña y resumen de alertas vía SMTP.

Desarrollo local — capture los correos en lugar de enviarlos:

./run.sh config add mail
./run.sh start

Cada correo llega a http://localhost:8025 (Mailpit) en lugar de a una bandeja de entrada real.

Producción — entregue correo real:

  1. Obtenga credenciales SMTP de un proveedor de correo (SendGrid, Postmark, AWS SES, Resend, Mailgun, o un relay corporativo ya existente).
  2. Establezca SMTP_ADMIN_EMAIL, SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, y SMTP_SENDER_NAME en el .env de ese entorno. Deje SMTP_ALLOW_INSECURE_AUTH sin definir — existe solo para Mailpit.
  3. Establezca DASHBOARD_URL con el dominio público real del dashboard — se incrusta en los enlaces de los correos de invitación/restablecimiento.
  4. No añada el override mail en producción, o interceptará el correo real.
  5. Aplique el cambio: ./run.sh recreate api alerting.

Si su proveedor requiere verificación de dominio (SPF/DKIM, identidad del remitente — habitual con SES y Postmark), eso debe completarse en el lado del proveedor antes de que el correo llegue de verdad.

Actualización

  1. Revise el changelog en busca de cambios incompatibles en las imágenes que esta pila sigue usando (Postgres, Keycloak, RustFS, Mailpit).
  2. Actualice las etiquetas de imagen en el docker-compose.*.yml correspondiente si es necesario.
  3. Descargue las últimas imágenes: docker compose pull.
  4. Reconstruya api / dashboard si su código fuente cambió: docker compose -f docker-compose.api.yml -f docker-compose.dashboard.yml up -d --build.

Haga siempre una copia de seguridad de su base de datos antes de actualizar.

¿Necesita escalado horizontal en su lugar?

Para un despliegue en clúster más allá de un único host de Compose, existe una vía basada en Helm para Kubernetes — construcción/publicación de imágenes, secretos, DNS y helm install — cubierta por separado de Docker Compose.