Desplegar en Kubernetes con Helm
El chart de Helm de BostonIvy ejecuta el servidor (API, MCP, CalDAV y trabajos en segundo plano), BostonIvy Web delante de él en la misma dirección y, para empezar rápido, un PostgreSQL incluido. Con cada versión del servidor se publica un chart nuevo en oci://ghcr.io/ivylabsapp/charts/bostonivy.
Antes de empezar
- Un clúster de Kubernetes,
kubectly Helm 3.8 o posterior, que puede instalar charts desde un registro OCI. - Un controlador de Ingress (ingress-nginx en los ejemplos) y un nombre de dominio que apunte a él. Para probar BostonIvy sin ellos, consulta Probar sin Ingress.
- Un token de GitHub con el permiso
read:packages. Las imágenes y el chart son paquetes privados en GitHub Container Registry.
Instalar
Crea un espacio de nombres y un secreto para descargar las imágenes privadas:
kubectl create namespace bostonivy kubectl -n bostonivy create secret docker-registry ghcr \ --docker-server=ghcr.io --docker-username=<tu usuario de GitHub> --docker-password=<token con read:packages>Inicia sesión en el registro con Helm para que pueda descargar el chart:
echo "$GITHUB_TOKEN" | helm registry login ghcr.io -u <tu usuario de GitHub> --password-stdinEscribe tu configuración en un archivo, por ejemplo
values.yaml.urles obligatoria: la usan los enlaces de los correos, los enlaces compartidos y las devoluciones de llamada de OAuth y OIDC.url: https://tasks.example.com imagePullSecrets: - name: ghcr ingress: enabled: true className: nginx annotations: # las actualizaciones en tiempo real son WebSockets de larga duración en /api/v1/realtime; las subidas llegan a 64 MiB nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" nginx.ingress.kubernetes.io/proxy-body-size: 64m tls: - secretName: bostonivy-tls hosts: [tasks.example.com]bostonivy-tlses el certificado de tu dominio: un Secret TLS que creas tú o uno que genera cert-manager.Instala:
helm install ivy oci://ghcr.io/ivylabsapp/charts/bostonivy --version 0.7.0 -n bostonivy -f values.yamlLos ejemplos de esta página llaman
ivya la release, así que sus recursos se llamanivy-bostonivy-…. Con una copia de bostonivy-os también puedes instalar desdedeploy/helm/bostonivy.
Crear el primer administrador
Helm también muestra estos pasos al terminar la instalación. La contraseña se lee sin mostrarla:
printf 'Password: '; read -rs PW; echo
printf '%s\n' "$PW" | kubectl -n bostonivy exec -i deploy/ivy-bostonivy-server -- bostonivy admin create-user <usuario> <correo> --admin
unset PW
Copia de seguridad del secreto del servidor
El secreto del servidor y la contraseña de la base de datos incluida se generan al instalar, se conservan en cada actualización y se guardan en el Secret ivy-bostonivy-secrets, que Helm no borra ni siquiera al desinstalar. Todas las claves de firma y cifrado se derivan del secreto del servidor: si lo pierdes, todo el mundo tendrá que volver a iniciar sesión y los secretos TOTP y de webhooks guardados ya no se podrán leer. Cópialo ahora a un lugar seguro:
kubectl -n bostonivy get secret ivy-bostonivy-secrets -o jsonpath='{.data.auth-secret}' | base64 -d
Para usar uno propio, define auth.secret, o guárdalo en la clave auth-secret de un Secret que administres tú y define auth.existingSecret.
Probar sin Ingress
Deja ingress.enabled desactivado, define auth.cookieSecure=false y reenvía el servicio web a tu máquina:
kubectl -n bostonivy port-forward svc/ivy-bostonivy-web 8080:80
y abre http://localhost:8080. En cuanto BostonIvy se sirva por HTTPS, vuelve a poner auth.cookieSecure en true.
Valores
| Valor | Por defecto | Qué hace |
|---|---|---|
url |
obligatorio | La dirección en la que se accede a BostonIvy; la usan los enlaces y las devoluciones de llamada de OAuth y OIDC |
imagePullSecrets |
[] |
Secretos para descargar las imágenes privadas |
auth.secret, auth.existingSecret |
generado | El secreto del servidor, indicado directamente o tomado de tu propio Secret (clave auth-secret) |
auth.cookieSecure |
true |
Déjalo activado detrás de HTTPS; desactívalo solo para probar BostonIvy con http sin cifrar |
database.url, database.existingSecret |
incluida | Un PostgreSQL externo, versión 16 o posterior; vacío usa la base de datos incluida |
postgresql.enabled |
true |
Un PostgreSQL en el clúster, para probar BostonIvy o instalaciones pequeñas |
mail.smtpUrl, mail.from |
vacío | Por ejemplo smtp://user:password@host:587, o log; vacío no envía correo |
config |
vacío | Ajustes adicionales del servidor en TOML, como los proveedores de inicio de sesión [[auth.oidc]] |
server.env, server.envFrom |
[] |
Cualquier otro ajuste BOSTONIVY_<SECCIÓN>__<CLAVE> |
server.replicas |
1 |
Más de una requiere almacenamiento S3 y worker.separate |
worker.separate, worker.replicas |
false, 1 |
Ejecuta los trabajos en segundo plano (correo, webhooks, recordatorios, mantenimiento) en sus propios pods |
persistence.* |
10Gi, ReadWriteOnce | Adjuntos y avatares mientras el almacenamiento sea local |
web.image.tag |
0.2.0 |
La versión de BostonIvy Web que se sirve |
ingress.* |
desactivado | El host por defecto es el de url; permite lecturas largas de WebSocket para las actualizaciones en tiempo real |
Base de datos
El PostgreSQL incluido es un solo pod, bueno para probar BostonIvy y para instalaciones pequeñas. En producción, usa una base de datos gestionada o un operador, y apunta BostonIvy hacia ella:
postgresql:
enabled: false
database:
url: postgres://bostonivy:<contraseña>@db.example.com:5432/bostonivy
o guarda la dirección en un Secret propio y define database.existingSecret. BostonIvy necesita PostgreSQL 16 o posterior.
Correo, inicio de sesión y otros ajustes
Correo:
mail.smtpUrlymail.from.logescribe los correos en el registro del servidor, útil para una prueba.Ajustes del servidor en TOML:
configadmite un archivo TOML, por ejemplo con proveedores de inicio de sesión:config: | [[auth.oidc]] id = "google" # el resto de campos están en bostonivy.example.tomlTodo lo demás:
server.envadmite variablesBOSTONIVY_<SECCIÓN>__<CLAVE>;bostonivy.example.tomlen bostonivy-os enumera todos los ajustes.
Escalar
El servidor no guarda estado propio, salvo los archivos almacenados localmente. Para más de una réplica:
server:
replicas: 3
env:
- name: BOSTONIVY_STORAGE__KIND
value: s3
# más los ajustes del bucket de [storage] en bostonivy.example.toml
worker:
separate: true
persistence:
enabled: false
- Los archivos van a un almacenamiento compatible con S3 en lugar del volumen, que solo puede montar un pod.
worker.separatelleva los trabajos en segundo plano a sus propios pods, para que se ejecuten una sola vez y no en cada réplica del servidor.- Define
BOSTONIVY_REDIS__URLenserver.envsi las réplicas deben compartir los contadores de límite de peticiones. - Las actualizaciones en tiempo real, la revocación de sesiones y los plugins se sincronizan entre réplicas a través de PostgreSQL; no hace falta nada más.
Actualizar y hacer copias de seguridad
Actualiza con el chart de la nueva versión:
helm upgrade ivy oci://ghcr.io/ivylabsapp/charts/bostonivy --version <nueva versión> -n bostonivy -f values.yaml
Los pods del servidor se renuevan uno a uno y la nueva versión migra la base de datos al arrancar. Las migraciones solo añaden y nunca eliminan, así que con una copia de seguridad puedes volver atrás.
Haz copia de tres cosas:
La base de datos. Con el PostgreSQL incluido:
kubectl -n bostonivy exec ivy-bostonivy-postgresql-0 -- pg_dump -U bostonivy bostonivy > backup.sqlAdjuntos y avatares: el volumen de archivos o tu bucket.
El secreto del servidor:
auth-secret(ver Copia de seguridad del secreto del servidor).