mirror of
https://github.com/suitenumerique/meet.git
synced 2026-10-11 23:52:00 +00:00
🔧(compose) replace MinIO by Garage for local development
The development stacks now run Garage instead of MinIO which is deprecated. Garage is a bit stricter than MinIO: - key IDs and secrets must be at least 8 and 16 characters long - requests must be signed for its region, so every development env now sets AWS_S3_REGION_NAME=local; - cross-origin requests are denied unless the bucket CORS rules allow them, so a one-shot aws-cli container allows the frontend origin to upload files straight to the bucket.
This commit is contained in:
@@ -117,14 +117,14 @@ def test_api_files_create_file_authenticated_success():
|
||||
policy_parsed = urlparse(policy)
|
||||
|
||||
assert policy_parsed.scheme == "http"
|
||||
assert policy_parsed.netloc in ["minio:9000", "localhost:9000"]
|
||||
assert policy_parsed.netloc in ["garage:9000", "localhost:9000"]
|
||||
assert policy_parsed.path == f"/meet-media-storage/tmp/files/{file.id!s}.png"
|
||||
|
||||
query_params = parse_qs(policy_parsed.query)
|
||||
|
||||
assert query_params.pop("X-Amz-Algorithm") == ["AWS4-HMAC-SHA256"]
|
||||
assert query_params.pop("X-Amz-Credential") == [
|
||||
f"meet/{now.strftime('%Y%m%d')}/us-east-1/s3/aws4_request"
|
||||
f"meet-access-key/{now.strftime('%Y%m%d')}/local/s3/aws4_request"
|
||||
]
|
||||
assert query_params.pop("X-Amz-Date") == [now.strftime("%Y%m%dT%H%M%SZ")]
|
||||
assert query_params.pop("X-Amz-Expires") == ["60"]
|
||||
|
||||
@@ -24,10 +24,11 @@ _summaryEnvVars: &summaryEnvVars
|
||||
APP_NAME: summary-microservice
|
||||
APP_API_TOKEN: password
|
||||
AWS_STORAGE_BUCKET_NAME: meet-media-storage
|
||||
AWS_S3_ENDPOINT_URL: http://minio.meet.svc.cluster.local:9000/
|
||||
AWS_S3_ACCESS_KEY_ID: meet
|
||||
AWS_S3_SECRET_ACCESS_KEY: password
|
||||
AWS_S3_ENDPOINT_URL: http://garage.meet.svc.cluster.local:9000/
|
||||
AWS_S3_ACCESS_KEY_ID: meet-access-key
|
||||
AWS_S3_SECRET_ACCESS_KEY: meet-secret-access-key
|
||||
AWS_S3_SECURE_ACCESS: False
|
||||
AWS_S3_REGION_NAME: local
|
||||
AUTHORIZED_TENANTS: >
|
||||
[
|
||||
{
|
||||
@@ -161,9 +162,9 @@ backend:
|
||||
FRONTEND_TRANSCRIPTION_DESTINATION: "https://docs.numerique.gouv.fr"
|
||||
FRONTEND_IS_SILENT_LOGIN_ENABLED: False
|
||||
# S3 Storage
|
||||
AWS_S3_ENDPOINT_URL: http://minio.meet.svc.cluster.local:9000
|
||||
AWS_S3_ACCESS_KEY_ID: meet
|
||||
AWS_S3_SECRET_ACCESS_KEY: password
|
||||
AWS_S3_ENDPOINT_URL: http://garage.meet.svc.cluster.local:9000
|
||||
AWS_S3_ACCESS_KEY_ID: meet-access-key
|
||||
AWS_S3_SECRET_ACCESS_KEY: meet-secret-access-key
|
||||
AWS_STORAGE_BUCKET_NAME: meet-media-storage
|
||||
# Telephony
|
||||
ROOM_TELEPHONY_ENABLED: True
|
||||
@@ -180,7 +181,7 @@ backend:
|
||||
# Custom Background
|
||||
AWS_S3_REGION_NAME: local
|
||||
AWS_S3_SIGNATURE_VERSION: s3v4
|
||||
AWS_S3_DOMAIN_REPLACE: https://minio.127.0.0.1.nip.io
|
||||
AWS_S3_DOMAIN_REPLACE: https://garage.127.0.0.1.nip.io
|
||||
MEDIA_BASE_URL: https://meet.127.0.0.1.nip.io
|
||||
FILE_UPLOAD_ENABLED: True
|
||||
CELERY_ENABLED: True
|
||||
@@ -264,11 +265,11 @@ ingressMedia:
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/auth-url: https://meet.127.0.0.1.nip.io/api/v1.0/recordings/media-auth/
|
||||
nginx.ingress.kubernetes.io/auth-response-headers: "Authorization, X-Amz-Date, X-Amz-Content-SHA256"
|
||||
nginx.ingress.kubernetes.io/upstream-vhost: minio.meet.svc.cluster.local:9000
|
||||
nginx.ingress.kubernetes.io/upstream-vhost: garage.meet.svc.cluster.local:9000
|
||||
nginx.ingress.kubernetes.io/rewrite-target: /meet-media-storage/$1
|
||||
|
||||
serviceMedia:
|
||||
host: minio.meet.svc.cluster.local
|
||||
host: garage.meet.svc.cluster.local
|
||||
port: 9000
|
||||
|
||||
# ---- Extra ingress/service for background file uploads ------------
|
||||
@@ -280,11 +281,11 @@ ingressMediaFiles:
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/auth-url: https://meet.127.0.0.1.nip.io/api/v1.0/files/media-auth/
|
||||
nginx.ingress.kubernetes.io/auth-response-headers: "Authorization, X-Amz-Date, X-Amz-Content-SHA256"
|
||||
nginx.ingress.kubernetes.io/upstream-vhost: minio.meet.svc.cluster.local:9000
|
||||
nginx.ingress.kubernetes.io/upstream-vhost: garage.meet.svc.cluster.local:9000
|
||||
nginx.ingress.kubernetes.io/rewrite-target: /meet-media-storage/files/$1
|
||||
|
||||
serviceMediaFiles:
|
||||
host: minio.meet.svc.cluster.local
|
||||
host: garage.meet.svc.cluster.local
|
||||
port: 9000
|
||||
|
||||
# ---- STT Orchestration Microservice Components --------------------
|
||||
@@ -362,10 +363,11 @@ agentMetadata:
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
ENABLE_SILERO_VAD: "false"
|
||||
AWS_S3_ENDPOINT_URL: minio.meet.svc.cluster.local:9000
|
||||
AWS_S3_ACCESS_KEY_ID: meet
|
||||
AWS_S3_SECRET_ACCESS_KEY: password
|
||||
AWS_S3_ENDPOINT_URL: garage.meet.svc.cluster.local:9000
|
||||
AWS_S3_ACCESS_KEY_ID: meet-access-key
|
||||
AWS_S3_SECRET_ACCESS_KEY: meet-secret-access-key
|
||||
AWS_S3_SECURE_ACCESS: False
|
||||
AWS_S3_REGION_NAME: local
|
||||
AWS_STORAGE_BUCKET_NAME: meet-media-storage
|
||||
AWS_S3_OUTPUT_FOLDER: metadata
|
||||
|
||||
|
||||
@@ -16,11 +16,11 @@ egress:
|
||||
address: redis-master:6379
|
||||
password: pass
|
||||
s3:
|
||||
access_key: meet
|
||||
secret: password
|
||||
access_key: meet-access-key
|
||||
secret: meet-secret-access-key
|
||||
region: local
|
||||
bucket: meet-media-storage
|
||||
endpoint: http://minio:9000
|
||||
endpoint: http://garage:9000
|
||||
force_path_style: true
|
||||
|
||||
loadBalancer:
|
||||
|
||||
@@ -19,11 +19,11 @@ egress:
|
||||
address: redis-master:6379
|
||||
password: pass
|
||||
s3:
|
||||
access_key: meet
|
||||
secret: password
|
||||
access_key: meet-access-key
|
||||
secret: meet-secret-access-key
|
||||
region: local
|
||||
bucket: meet-media-storage
|
||||
endpoint: http://minio:9000
|
||||
endpoint: http://garage:9000
|
||||
force_path_style: true
|
||||
|
||||
loadBalancer:
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: garage
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: 10m
|
||||
spec:
|
||||
rules:
|
||||
- host: "garage.127.0.0.1.nip.io"
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: garage
|
||||
port:
|
||||
number: 9000
|
||||
tls:
|
||||
- hosts:
|
||||
- garage.127.0.0.1.nip.io
|
||||
secretName: meet-tls
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: garage
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
spec:
|
||||
ports:
|
||||
- name: client
|
||||
port: 9000
|
||||
protocol: TCP
|
||||
targetPort: 9000
|
||||
selector:
|
||||
app.kubernetes.io/instance: extra
|
||||
app.kubernetes.io/name: garage
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: garage-config
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
data:
|
||||
garage.toml: |
|
||||
metadata_dir = "/var/lib/garage/meta"
|
||||
data_dir = "/var/lib/garage/data"
|
||||
db_engine = "lmdb"
|
||||
|
||||
replication_factor = 1
|
||||
|
||||
rpc_bind_addr = "127.0.0.1:3901"
|
||||
rpc_public_addr = "127.0.0.1:3901"
|
||||
|
||||
[s3_api]
|
||||
api_bind_addr = "[::]:9000"
|
||||
# Clients must sign their requests for this region (AWS_S3_REGION_NAME)
|
||||
s3_region = "local"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: garage-dev
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
type: Opaque
|
||||
data:
|
||||
GARAGE_RPC_SECRET: {{ printf "%s/garage-rpc-secret" .Release.Namespace | sha256sum | b64enc }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: garage
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
app.kubernetes.io/instance: extra
|
||||
app.kubernetes.io/name: garage
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: extra
|
||||
app.kubernetes.io/name: garage
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: extra
|
||||
app.kubernetes.io/name: garage
|
||||
spec:
|
||||
containers:
|
||||
- name: garage
|
||||
command:
|
||||
- /garage
|
||||
- server
|
||||
- --single-node
|
||||
- --default-bucket
|
||||
env:
|
||||
- name: GARAGE_RPC_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: garage-dev
|
||||
key: GARAGE_RPC_SECRET
|
||||
- name: GARAGE_DEFAULT_ACCESS_KEY
|
||||
value: meet-access-key
|
||||
- name: GARAGE_DEFAULT_SECRET_KEY
|
||||
value: meet-secret-access-key
|
||||
- name: GARAGE_DEFAULT_BUCKET
|
||||
value: meet-media-storage
|
||||
image: "dxflrs/garage:v2.4.1"
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 9000
|
||||
name: client
|
||||
readinessProbe:
|
||||
exec:
|
||||
command:
|
||||
- /garage
|
||||
- health
|
||||
volumeMounts:
|
||||
- mountPath: /etc/garage.toml
|
||||
name: config
|
||||
subPath: garage.toml
|
||||
- mountPath: /var/lib/garage
|
||||
name: data
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: garage-config
|
||||
- name: data
|
||||
emptyDir:
|
||||
---
|
||||
# Garage denies cross-origin requests by default: allow the frontend to upload
|
||||
# files straight to the bucket
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: garage-cors
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: aws-cli
|
||||
image: amazon/aws-cli:2.37.1
|
||||
env:
|
||||
- name: AWS_ACCESS_KEY_ID
|
||||
value: meet-access-key
|
||||
- name: AWS_SECRET_ACCESS_KEY
|
||||
value: meet-secret-access-key
|
||||
- name: AWS_DEFAULT_REGION
|
||||
value: local
|
||||
- name: AWS_ENDPOINT_URL
|
||||
value: http://garage:9000
|
||||
- name: BUCKET
|
||||
value: meet-media-storage
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
deadline=$(($(date +%s) + 300))
|
||||
until aws s3api head-bucket --bucket="$BUCKET" --cli-connect-timeout=5; do
|
||||
if [ "$(date +%s)" -ge "$deadline" ]; then
|
||||
echo "Bucket $BUCKET still unavailable on $AWS_ENDPOINT_URL" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Waiting for bucket $BUCKET on $AWS_ENDPOINT_URL"
|
||||
sleep 5
|
||||
done
|
||||
exec aws s3api put-bucket-cors --bucket="$BUCKET" \
|
||||
--cors-configuration='{"CORSRules": [{"AllowedOrigins": ["https://meet.127.0.0.1.nip.io"], "AllowedMethods": ["GET", "HEAD", "PUT"], "AllowedHeaders": ["*"], "ExposeHeaders": ["ETag"]}]}'
|
||||
restartPolicy: Never
|
||||
backoffLimit: 3
|
||||
@@ -1,115 +0,0 @@
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: minio
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: 10m
|
||||
spec:
|
||||
rules:
|
||||
- host: "minio.127.0.0.1.nip.io"
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: minio
|
||||
port:
|
||||
number: 9000
|
||||
tls:
|
||||
- hosts:
|
||||
- minio.127.0.0.1.nip.io
|
||||
secretName: meet-tls
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: minio
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
spec:
|
||||
ports:
|
||||
- name: client
|
||||
port: 9000
|
||||
protocol: TCP
|
||||
targetPort: 9000
|
||||
- name: console
|
||||
port: 9001
|
||||
protocol: TCP
|
||||
targetPort: 9001
|
||||
selector:
|
||||
app.kubernetes.io/instance: extra
|
||||
app.kubernetes.io/name: minio
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: minio
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
app.kubernetes.io/instance: extra
|
||||
app.kubernetes.io/name: minio
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: extra
|
||||
app.kubernetes.io/name: minio
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: extra
|
||||
app.kubernetes.io/name: minio
|
||||
spec:
|
||||
containers:
|
||||
- name: minio
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
minio server --console-address :9001 /data
|
||||
env:
|
||||
- name: MINIO_ROOT_USER
|
||||
value: meet
|
||||
- name: MINIO_ROOT_PASSWORD
|
||||
value: password
|
||||
image: "quay.io/minio/minio"
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 9000
|
||||
name: client
|
||||
- containerPort: 9001
|
||||
name: console
|
||||
volumeMounts:
|
||||
- mountPath: /data
|
||||
name: data
|
||||
- mountPath: /etc/ssl/certs/mkcert-ca.pem
|
||||
name: mkcert
|
||||
subPath: rootCA.pem
|
||||
volumes:
|
||||
- name: data
|
||||
emptyDir:
|
||||
- name: mkcert
|
||||
secret:
|
||||
secretName: mkcert
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: minio-bucket
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: mc
|
||||
image: quay.io/minio/mc
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
/usr/bin/mc alias set meet http://minio:9000 meet password && \
|
||||
/usr/bin/mc mb meet/meet-media-storage && \
|
||||
exit 0
|
||||
restartPolicy: Never
|
||||
backoffLimit: 3
|
||||
Reference in New Issue
Block a user