chore(search): wire Meilisearch — local compose + prod k8s manifests
Add a meilisearch service to the dev docker-compose (port 7700, persistent volume) and MEILI_URL/MEILI_KEY (+ IIOS_CRED_KEY, IIOS_MEDIA_GC_INTERVAL_MS) to .env.example. Add deploy/meilisearch.yaml — a ready-to-apply k8s Deployment/Service/PVC/Secret for the ArgoCD prod stack (copy into k8s-pods/services/iios/), with wiring notes for the iios-service env (MEILI_URL=http://meilisearch:7700, MEILI_KEY from the secret). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -6,3 +6,18 @@ DATABASE_URL="postgresql://iios:iios@localhost:5434/iios?schema=public"
|
|||||||
JWT_SECRET="dev-only-change-me"
|
JWT_SECRET="dev-only-change-me"
|
||||||
# Per-app HS256 secrets, JSON map keyed by appId (the `session` platform port)
|
# Per-app HS256 secrets, JSON map keyed by appId (the `session` platform port)
|
||||||
APP_SECRETS={"portal-demo":"dev-secret"}
|
APP_SECRETS={"portal-demo":"dev-secret"}
|
||||||
|
|
||||||
|
# Full-text message search (Meilisearch). Unset MEILI_URL → search is disabled (no-op).
|
||||||
|
# MEILI_KEY must equal the meilisearch server's MEILI_MASTER_KEY (docker-compose default below).
|
||||||
|
MEILI_URL="http://localhost:7700"
|
||||||
|
MEILI_KEY="dev-meili-master-key"
|
||||||
|
# Consumed by docker-compose's meilisearch service; keep in sync with MEILI_KEY.
|
||||||
|
MEILI_MASTER_KEY="dev-meili-master-key"
|
||||||
|
|
||||||
|
# BYO integration credentials at rest (Twilio SMS, SMTP): 32-byte base64 AES-256-GCM key.
|
||||||
|
# Generate with: openssl rand -base64 32
|
||||||
|
IIOS_CRED_KEY=""
|
||||||
|
|
||||||
|
# Orphaned-media garbage collection (uploaded-but-never-sent attachments).
|
||||||
|
# Interval 0 = off; set e.g. 3600000 (hourly) in prod. Grace defaults to 24h.
|
||||||
|
IIOS_MEDIA_GC_INTERVAL_MS=0
|
||||||
|
|||||||
@@ -29,5 +29,24 @@ services:
|
|||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 10
|
retries: 10
|
||||||
|
|
||||||
|
# Full-text message search. The service uses it when MEILI_URL is set (else search no-ops).
|
||||||
|
# Point the service at it with MEILI_URL=http://localhost:7700 + MEILI_KEY=<master key>.
|
||||||
|
meilisearch:
|
||||||
|
image: getmeili/meilisearch:v1.11
|
||||||
|
container_name: iios-meili
|
||||||
|
ports:
|
||||||
|
- "7700:7700"
|
||||||
|
environment:
|
||||||
|
MEILI_NO_ANALYTICS: "true"
|
||||||
|
MEILI_MASTER_KEY: ${MEILI_MASTER_KEY:-dev-meili-master-key}
|
||||||
|
volumes:
|
||||||
|
- iios_meili_data:/meili_data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "curl -sf http://localhost:7700/health || exit 1"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
iios_postgres_data:
|
iios_postgres_data:
|
||||||
|
iios_meili_data:
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
# Meilisearch for IIOS message search (prod).
|
||||||
|
#
|
||||||
|
# IIOS deploys to Kubernetes via ArgoCD from the platform-engineering/k8s-pods repo
|
||||||
|
# (services/iios/). This file is the template for the prod Meilisearch instance — copy it into
|
||||||
|
# k8s-pods/services/iios/meilisearch.yaml and let ArgoCD sync it. Then wire the service:
|
||||||
|
#
|
||||||
|
# 1. Create the master key once (32+ random chars) and set it in the Secret below (or via a
|
||||||
|
# sealed-secret / your secret manager — do NOT commit a real key in plaintext):
|
||||||
|
# kubectl -n <iios-namespace> create secret generic iios-meili \
|
||||||
|
# --from-literal=MEILI_MASTER_KEY="$(openssl rand -base64 32)"
|
||||||
|
# 2. Add these env vars to the iios-service Deployment (services/iios/deployment.yaml):
|
||||||
|
# - name: MEILI_URL
|
||||||
|
# value: http://meilisearch:7700
|
||||||
|
# - name: MEILI_KEY
|
||||||
|
# valueFrom: { secretKeyRef: { name: iios-meili, key: MEILI_MASTER_KEY } }
|
||||||
|
# 3. After the first deploy, backfill existing messages once: POST /v1/search/reindex per tenant
|
||||||
|
# (authenticated as a scope member) — new messages index automatically on message.sent.
|
||||||
|
#
|
||||||
|
# Set the namespace on each object (or via kustomize) to match the iios-service namespace so the
|
||||||
|
# `meilisearch` Service DNS resolves as http://meilisearch:7700 from the pod.
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: iios-meili
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
# Replace with a real key (or manage out-of-band per note #1 and delete this stringData block).
|
||||||
|
MEILI_MASTER_KEY: "CHANGE_ME_meili_master_key"
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: iios-meili-data
|
||||||
|
spec:
|
||||||
|
accessModes: ["ReadWriteOnce"]
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: meilisearch
|
||||||
|
labels: { app: meilisearch }
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy: { type: Recreate } # single RWO volume — never run two writers
|
||||||
|
selector:
|
||||||
|
matchLabels: { app: meilisearch }
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels: { app: meilisearch }
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: meilisearch
|
||||||
|
image: getmeili/meilisearch:v1.11
|
||||||
|
ports:
|
||||||
|
- containerPort: 7700
|
||||||
|
env:
|
||||||
|
- name: MEILI_ENV
|
||||||
|
value: "production"
|
||||||
|
- name: MEILI_NO_ANALYTICS
|
||||||
|
value: "true"
|
||||||
|
- name: MEILI_MASTER_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef: { name: iios-meili, key: MEILI_MASTER_KEY }
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /meili_data
|
||||||
|
resources:
|
||||||
|
requests: { cpu: "100m", memory: "256Mi" }
|
||||||
|
limits: { cpu: "1", memory: "1Gi" }
|
||||||
|
readinessProbe:
|
||||||
|
httpGet: { path: /health, port: 7700 }
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
livenessProbe:
|
||||||
|
httpGet: { path: /health, port: 7700 }
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 20
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: iios-meili-data
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: meilisearch
|
||||||
|
labels: { app: meilisearch }
|
||||||
|
spec:
|
||||||
|
selector: { app: meilisearch }
|
||||||
|
ports:
|
||||||
|
- port: 7700
|
||||||
|
targetPort: 7700
|
||||||
|
# ClusterIP (internal only) — reached by iios-service as http://meilisearch:7700.
|
||||||
|
type: ClusterIP
|
||||||
Reference in New Issue
Block a user