Ir al contenido

Primeros pasos con Docker Compose

El repositorio incluye un stack Compose bajo deploy/compose/: un despliegue endurecido de nodo único (SQLite embebido, cero dependencias externas) más dos overlays — un override multi-tenant con Postgres y un perfil de copia de seguridad para recuperación ante desastres. Este tutorial te lleva desde up -d hasta un control plane configurado con copias de seguridad.

El contenedor envuelve el mismo binario único que cualquier otra instalación; solo difiere el empaquetado. Los comandos de abajo son los propios puntos de entrada documentados del stack (deploy/compose/*.yml), y el flujo de primer arranque que conducen es el mismo que se verifica de extremo a extremo contra el binario en el tutorial de nodo único.

  1. Arráncalo:

    Ventana de terminal
    docker compose -f deploy/compose/docker-compose.yml up -d

    Lo que obtienes, por diseño:

    | Propiedad | Valor | |---|---| | Puertos | 127.0.0.1:8443 (HTTPS: REST + UI web), 127.0.0.1:8444 (gRPC) — vinculados a localhost en el host; expón deliberadamente | | Datos | volumen nombrado olivares-data/var/lib/olivares (almacén SQLite, clave de firma de auditoría, material TLS) | | Endurecimiento | corre como 65532:65532, root de solo lectura, todas las capabilities descartadas, no-new-privileges, tmpfs /tmp | | Healthcheck | ninguno dentro del contenedor (la imagen es distroless — sin shell). Sondea /livez y /readyz desde el host |

  2. Lee el token de configuración de un solo uso de los logs:

    Ventana de terminal
    docker compose -f deploy/compose/docker-compose.yml logs olivares \
    | sed -n '/FIRST-BOOT SETUP/,/========================/p'
  3. Crea el primer administrador, inicia sesión, y crea tu organización — exactamente como en el tutorial de nodo único (la API es la misma; el certificado TLS es autofirmado en el primer arranque, así que curl -k para el bootstrap):

    Ventana de terminal
    curl -ksf -X POST https://localhost:8443/v1/setup \
    -H 'Content-Type: application/json' \
    -d '{"token":"<olst_ token>","email":"you@example.com","password":"<strong-password>"}'

Las fuentes se declaran en un único fichero de operador nombrado por OLIVARES_SOURCES_CONFIG (conectar una fuente). Para el contenedor, monta el fichero y establece la variable con un pequeño override:

# deploy/compose/docker-compose.sources.yml (yours — not shipped)
services:
olivares:
environment:
OLIVARES_SOURCES_CONFIG: /etc/olivares/sources.json
volumes:
- ./sources.json:/etc/olivares/sources.json:ro
Ventana de terminal
docker compose -f deploy/compose/docker-compose.yml \
-f deploy/compose/docker-compose.sources.yml up -d
docker compose -f deploy/compose/docker-compose.yml logs olivares | grep "ingest: wired source"

Recuerda que las rutas dentro de sources.json son rutas de contenedor — un tail de log pgAudit, por ejemplo, necesita que el directorio de logs de Postgres también esté montado de solo lectura dentro del contenedor.

3. Copias de seguridad DR cifradas (el perfil backup)

Sección titulada «3. Copias de seguridad DR cifradas (el perfil backup)»

El stack incluye un servicio de copia de seguridad de un solo disparo que produce un bundle cifrado y con continuidad de ledger segura (olivares dr backup) y poda los bundles con más de 14 días de antigüedad:

Ventana de terminal
# Write your KEK passphrase once (keep it OUT of the repo / image):
printf 'a strong DR passphrase' > deploy/compose/dr-pass
docker compose -f deploy/compose/docker-compose.yml \
-f deploy/compose/docker-compose.backup.yml \
--profile backup run --rm backup

Envuelve ese comando en el cron del host para un RPO programado, y espeja el volumen olivares-backups offsite — una copia de seguridad en el mismo host no es recuperación ante desastres, y la passphrase debe viajar por separado de los bundles (3-2-1). El procedimiento completo, incluyendo el simulacro de restauración (olivares dr verify), está en copia de seguridad y restauración.

4. Opcional: el override multi-tenant con Postgres

Sección titulada «4. Opcional: el override multi-tenant con Postgres»

Para la topología multi-tenant, superpón el override de Postgres. Levanta un Postgres 16, aprovisiona el rol de mínimo privilegio olivares_app (sin superuser, sin BYPASSRLS — el motor se niega a arrancar contra un rol privilegiado, porque la seguridad a nivel de fila es el backstop del tenant), y apunta el motor a él:

Ventana de terminal
cp deploy/compose/.env.example deploy/compose/.env
# set POSTGRES_SUPERUSER_PASSWORD and OLIVARES_DB_PASSWORD in .env
docker compose -f deploy/compose/docker-compose.yml \
-f deploy/compose/docker-compose.postgres.yml up -d
Ventana de terminal
curl -ks https://localhost:8443/readyz
# {"leader":true,"setup_required":false,"status":"ok","store":"up"}
curl -ks https://localhost:8443/metrics | grep olivares_store_up