anydrop/k8s/server.yml
ordinarthur 0b639dfc3c feat: encrypted cloud relay (Phase 2)
Adds a "Via AnyDrop" flow for senders who need to reach someone not
present on the mesh. The file is sealed client-side (XChaCha20-Poly1305),
uploaded directly to an in-cluster MinIO bucket via a presigned PUT, and
handed off to the recipient as a URL whose fragment carries the key.
The server only ever sees ciphertext, opaque metadata blobs, and sizes.

- server: transfers table (drizzle migration), /api/transfers CRUD +
  consume endpoint, presigned PUT/GET via @aws-sdk/client-s3, cleanup
  loop that purges expired + exhausted blobs.
- web: @noble/ciphers sealFile/openFile, high-level sendCloud/receive
  helpers, CloudSharePanel on Home, /r/:id receive page, /inbox page
  for signed-in users (sent + received tabs).
- k8s: MinIO StatefulSet with bucket-init initContainer, S3 env vars
  on the server Deployment (credentials pulled from minio-credentials
  Secret).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 11:09:58 +02:00

108 lines
3.0 KiB
YAML

apiVersion: v1
kind: ConfigMap
metadata:
name: anydrop-server-config
namespace: anydrop
data:
PORT: "3001"
BASE_URL: "https://anydrop.arthurbarre.fr"
APP_URL: "https://anydrop.arthurbarre.fr"
VAPID_PUBLIC_KEY: "BCta0SNLmjBFfizMInnBhEQvVZlMbbaM-qw1a-p3JeQykCyy00GRGkDAKMDA5nv5UfokwJ30HRGoA6buJjWwKcE"
VAPID_PRIVATE_KEY: "gbmrcm9Tuz4JgoHophO-jUbam8rV9YgjImYcWvoE0w0"
VAPID_SUBJECT: "mailto:arthurbarre.js@gmail.com"
SMTP_HOST: "maddy.anydrop.svc.cluster.local"
SMTP_PORT: "587"
SMTP_SECURE: "false"
SMTP_TLS_REJECT_UNAUTHORIZED: "false"
SMTP_FROM: "AnyDrop <noreply@anydrop.arthurbarre.fr>"
# Phase 2 — encrypted cloud relay (MinIO in-cluster)
# Endpoint must be publicly reachable: the browser uses presigned URLs
# signed against this host, so the hostname seen by the server and the
# client must match. Ingress routes s3.anydrop.arthurbarre.fr → minio:9000.
S3_ENDPOINT: "https://s3.anydrop.arthurbarre.fr"
S3_REGION: "us-east-1"
S3_BUCKET: "transfers"
S3_FORCE_PATH_STYLE: "true"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: anydrop-server
namespace: anydrop
spec:
replicas: 1
selector:
matchLabels:
app: anydrop-server
template:
metadata:
labels:
app: anydrop-server
spec:
initContainers:
- name: db-migrate
image: git.arthurbarre.fr/ordinarthur/anydrop-server:latest
command: ["node", "server/dist/db/migrate.js"]
envFrom:
- configMapRef:
name: anydrop-server-config
- secretRef:
name: anydrop-app-secrets
containers:
- name: anydrop-server
image: git.arthurbarre.fr/ordinarthur/anydrop-server:latest
ports:
- containerPort: 3001
envFrom:
- configMapRef:
name: anydrop-server-config
- secretRef:
name: anydrop-app-secrets
env:
- name: S3_ACCESS_KEY
valueFrom:
secretKeyRef:
name: minio-credentials
key: access_key
- name: S3_SECRET_KEY
valueFrom:
secretKeyRef:
name: minio-credentials
key: secret_key
livenessProbe:
httpGet:
path: /health
port: 3001
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 3001
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
memory: "96Mi"
cpu: "50m"
limits:
memory: "192Mi"
cpu: "300m"
imagePullSecrets:
- name: gitea-registry
---
apiVersion: v1
kind: Service
metadata:
name: anydrop-server
namespace: anydrop
spec:
type: ClusterIP
selector:
app: anydrop-server
ports:
- port: 3001
targetPort: 3001