chore(infra): point cloud relay at shared cluster MinIO
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m11s

Drop the standalone MinIO StatefulSet — the cluster already runs one
in the `minio` namespace, exposed at minio.arthurbarre.fr. Use that
with a scoped anydrop user + bucket instead of spinning up a second
instance.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
ordinarthur 2026-04-20 11:25:19 +02:00
parent 0b639dfc3c
commit 6ba5401c4d
3 changed files with 17 additions and 148 deletions

View File

@ -1,138 +0,0 @@
# MinIO — S3-compatible object storage for the encrypted relay.
#
# Phase 2 context: the server never sees plaintext. Clients upload an
# XChaCha20-Poly1305 ciphertext directly to MinIO via a presigned PUT URL,
# and recipients download via a presigned GET URL. The symmetric key stays
# in the browser URL fragment (#k=...); the server only knows the storage
# key and blob size.
#
# Single-node deployment in-cluster. Bucket "transfers" is created on boot
# via a one-shot initContainer (mc mb --ignore-existing).
#
# DEPLOY-TIME REQUIREMENT: the API port (9000) must be publicly reachable at
# the host declared by S3_ENDPOINT in server.yml (s3.anydrop.arthurbarre.fr).
# Presigned URLs are signed against that host, and the browser must be able
# to resolve it. Configure an external route (traefik ingress, nginx, etc.)
# from that hostname to this Service on port 9000.
apiVersion: v1
kind: Service
metadata:
name: minio
namespace: anydrop
labels:
app: minio
spec:
clusterIP: None
selector:
app: minio
ports:
- name: api
port: 9000
targetPort: 9000
- name: console
port: 9001
targetPort: 9001
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: minio
namespace: anydrop
spec:
serviceName: minio
replicas: 1
selector:
matchLabels:
app: minio
template:
metadata:
labels:
app: minio
spec:
initContainers:
- name: ensure-bucket
image: minio/mc:latest
command:
- /bin/sh
- -c
- |
set -e
until mc alias set local http://minio:9000 "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD" 2>/dev/null; do
echo "waiting for minio..."
sleep 2
done
mc mb --ignore-existing local/transfers
# Keep the bucket private — every object is served via presigned URL.
mc anonymous set none local/transfers
echo "bucket ready"
env:
- name: MINIO_ROOT_USER
valueFrom:
secretKeyRef:
name: minio-credentials
key: access_key
- name: MINIO_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: minio-credentials
key: secret_key
containers:
- name: minio
image: minio/minio:latest
args:
- server
- /data
- --console-address
- ":9001"
ports:
- containerPort: 9000
name: api
- containerPort: 9001
name: console
env:
- name: MINIO_ROOT_USER
valueFrom:
secretKeyRef:
name: minio-credentials
key: access_key
- name: MINIO_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: minio-credentials
key: secret_key
- name: MINIO_BROWSER_REDIRECT_URL
value: "https://anydrop.arthurbarre.fr/minio-console"
volumeMounts:
- name: data
mountPath: /data
livenessProbe:
httpGet:
path: /minio/health/live
port: 9000
initialDelaySeconds: 30
periodSeconds: 20
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /minio/health/ready
port: 9000
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 3
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "1Gi"
cpu: "1000m"
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 20Gi

View File

@ -16,12 +16,19 @@
# --from-literal=SESSION_SECRET="$SESSION_SECRET" \
# --from-literal=DATABASE_URL="$DATABASE_URL"
#
# # MinIO (object storage for the encrypted relay)
# MINIO_ACCESS_KEY=$(openssl rand -hex 16)
# MINIO_SECRET_KEY=$(openssl rand -base64 40 | tr -d '=+/')
# # MinIO — reuses the shared cluster MinIO in the `minio` namespace.
# # Create a scoped user + policy on MinIO (one-shot), then store its
# # credentials here. Don't use the MinIO root account.
# # kubectl -n minio exec deploy/minio -- sh -c '
# # mc alias set local http://localhost:9000 "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD"
# # mc mb --ignore-existing local/transfers
# # mc anonymous set none local/transfers
# # mc admin user add local anydrop <STRONG_SECRET>
# # # Attach a policy scoped to the transfers bucket only.
# # '
# kubectl -n anydrop create secret generic minio-credentials \
# --from-literal=access_key="$MINIO_ACCESS_KEY" \
# --from-literal=secret_key="$MINIO_SECRET_KEY"
# --from-literal=access_key="anydrop" \
# --from-literal=secret_key="<STRONG_SECRET>"
#
# Rotate by replacing the secret and restarting the pods:
# kubectl -n anydrop rollout restart deployment/anydrop-server

View File

@ -15,11 +15,11 @@ data:
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"
# Phase 2 — encrypted cloud relay (shared MinIO in the `minio` namespace,
# exposed publicly via Traefik as minio.arthurbarre.fr). The browser uses
# presigned URLs signed against this host, so server and client must see
# the same hostname.
S3_ENDPOINT: "https://minio.arthurbarre.fr"
S3_REGION: "us-east-1"
S3_BUCKET: "transfers"
S3_FORCE_PATH_STYLE: "true"