mirror of
https://github.com/suitenumerique/meet.git
synced 2026-09-30 06:28:59 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4759fd97ff | |||
| 1aeb5141b4 |
@@ -12,6 +12,7 @@ and this project adheres to
|
||||
|
||||
- ✨(backend) make the LiveKit default video codec configurable
|
||||
- 🔧(dev) add support for Bureautix workstations
|
||||
- ✨(frontend) switch frontend images to Caddy and proxy recording/file downloads through it, removing the NGINX Ingress auth annotations dependency
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# Shared Caddy snippet: proxies recording/file downloads to object storage after
|
||||
# checking authorization with the backend
|
||||
#
|
||||
# Env vars (all optional, fall back to local dev defaults): BACKEND_INTERNAL_HOST,
|
||||
# BACKEND_INTERNAL_PORT, MEDIA_STORAGE_HOST, MEDIA_STORAGE_PROTOCOL, MEDIA_STORAGE_PORT, AWS_STORAGE_BUCKET_NAME.
|
||||
|
||||
handle /media/files/* {
|
||||
route {
|
||||
forward_auth http://{$BACKEND_INTERNAL_HOST:localhost}:{$BACKEND_INTERNAL_PORT:8000} {
|
||||
uri /api/v1.0/files/media-auth/
|
||||
copy_headers Authorization X-Amz-Date X-Amz-Content-Sha256
|
||||
header_up X-Original-URL {http.request.uri}
|
||||
# Backend has SECURE_SSL_REDIRECT: without this the auth subrequest is
|
||||
# 301'd to https, the browser follows it to media-auth (no X-Original-URL) and 403s.
|
||||
header_up X-Forwarded-Proto https
|
||||
}
|
||||
uri replace /media/ /{$AWS_STORAGE_BUCKET_NAME:meet-media-storage}/ 1
|
||||
reverse_proxy {$MEDIA_STORAGE_PROTOCOL:http}://{$MEDIA_STORAGE_HOST:localhost}:{$MEDIA_STORAGE_PORT:9000} {
|
||||
header_up Host {$MEDIA_STORAGE_HOST:localhost}:{$MEDIA_STORAGE_PORT:9000}
|
||||
header_down -Content-Disposition
|
||||
header_down Content-Disposition attachment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Recordings media - kept generic (/media/*) to match the existing ingress path.
|
||||
handle /media/* {
|
||||
route {
|
||||
forward_auth http://{$BACKEND_INTERNAL_HOST:localhost}:{$BACKEND_INTERNAL_PORT:8000} {
|
||||
uri /api/v1.0/recordings/media-auth/
|
||||
copy_headers Authorization X-Amz-Date X-Amz-Content-Sha256
|
||||
header_up X-Original-URL {http.request.uri}
|
||||
header_up X-Forwarded-Proto https
|
||||
}
|
||||
uri replace /media/ /{$AWS_STORAGE_BUCKET_NAME:meet-media-storage}/ 1
|
||||
reverse_proxy {$MEDIA_STORAGE_PROTOCOL:http}://{$MEDIA_STORAGE_HOST:localhost}:{$MEDIA_STORAGE_PORT:9000} {
|
||||
header_up Host {$MEDIA_STORAGE_HOST:localhost}:{$MEDIA_STORAGE_PORT:9000}
|
||||
header_down -Content-Disposition
|
||||
header_down Content-Disposition attachment
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
# Global options
|
||||
{
|
||||
auto_https off
|
||||
admin off
|
||||
# replace_response can't process compressed bodies, so it must run before encode.
|
||||
order replace before encode
|
||||
}
|
||||
|
||||
:{$PORT} {
|
||||
root * /usr/share/nginx/html
|
||||
encode gzip
|
||||
|
||||
route {
|
||||
import /etc/caddy/media-proxy.caddy
|
||||
|
||||
handle /.well-known/windows-app-web-link {
|
||||
header Content-Type "application/json"
|
||||
header Content-Disposition "attachment; filename=windows-app-web-link"
|
||||
file_server
|
||||
}
|
||||
|
||||
# Manifest — fetched, never iframed
|
||||
handle /addons/outlook/manifest.xml {
|
||||
header Access-Control-Allow-Origin "*"
|
||||
header Cache-Control "no-cache, no-store, must-revalidate"
|
||||
header X-Frame-Options "DENY"
|
||||
header Content-Security-Policy "frame-ancestors 'none'"
|
||||
file_server
|
||||
}
|
||||
|
||||
handle /addons/outlook/assets/* {
|
||||
header Cache-Control "public, max-age=2592000, immutable"
|
||||
header Access-Control-Allow-Origin "*"
|
||||
header Vary "Origin"
|
||||
file_server
|
||||
}
|
||||
|
||||
# Outlook add-on pages: per-request CSP nonce, mirrors the Office.js/config.js
|
||||
# script tags baked into the build with a literal NONCE_PLACEHOLDER string.
|
||||
handle /addons/outlook/* {
|
||||
header Cache-Control "no-cache, no-store, must-revalidate"
|
||||
header Pragma "no-cache"
|
||||
header Expires 0
|
||||
header Content-Security-Policy "default-src 'self'; upgrade-insecure-requests; frame-ancestors https://*.live.com https://*.office.com https://*.microsoft.com https://*.office365.com https://*.sharepoint.com; script-src 'nonce-{http.request.uuid}' 'strict-dynamic'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self' https://*.live.com https://*.office.com https://*.microsoft.com https://*.office365.com https://*.sharepoint.com; frame-src 'none'; object-src 'none'; base-uri 'none'"
|
||||
replace NONCE_PLACEHOLDER {http.request.uuid}
|
||||
try_files {path} /index.html
|
||||
file_server
|
||||
}
|
||||
|
||||
# Vite fingerprints everything under /assets, so a given URL's bytes never
|
||||
# change: cache it forever. A new build emits new hashed URLs.
|
||||
@immutable path /assets/*
|
||||
header @immutable Cache-Control "public, max-age=2592000, immutable"
|
||||
|
||||
# The SPA shell and other non-fingerprinted files must revalidate every
|
||||
# load, or a deploy's new asset hashes only show up after a hard refresh.
|
||||
@revalidate not path /assets/*
|
||||
header @revalidate {
|
||||
Cache-Control "no-cache, no-store, must-revalidate"
|
||||
Pragma "no-cache"
|
||||
Expires 0
|
||||
}
|
||||
|
||||
try_files {path} /index.html
|
||||
file_server
|
||||
}
|
||||
|
||||
handle_errors {
|
||||
@spa_404 expression `{err.status_code} == 404`
|
||||
handle @spa_404 {
|
||||
rewrite * /index.html
|
||||
file_server
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,19 +52,17 @@ COPY ./src/addons/outlook/ .
|
||||
|
||||
RUN npx webpack --mode production
|
||||
|
||||
# ---- Caddy builder image ----
|
||||
FROM caddy:2.11.4-builder AS caddy-builder
|
||||
|
||||
RUN xcaddy build --with github.com/caddyserver/replace-response
|
||||
RUN apk add --no-cache libcap && \
|
||||
setcap -r /usr/bin/caddy
|
||||
|
||||
# ---- Front-end image ----
|
||||
FROM nginxinc/nginx-unprivileged:1.30.4-alpine3.24 AS frontend-production
|
||||
FROM gcr.io/distroless/static-debian12:nonroot AS frontend-production
|
||||
|
||||
USER root
|
||||
RUN apk del curl
|
||||
USER nginx
|
||||
|
||||
USER nginx
|
||||
|
||||
# Un-privileged user running the application
|
||||
ARG DOCKER_USER
|
||||
USER ${DOCKER_USER}
|
||||
COPY --from=caddy-builder /usr/bin/caddy /usr/bin/caddy
|
||||
|
||||
COPY --from=meet-builder \
|
||||
/home/frontend/dist \
|
||||
@@ -74,9 +72,9 @@ COPY --from=addons-builder \
|
||||
/home/addons/outlook/dist \
|
||||
/usr/share/nginx/html/addons/outlook
|
||||
|
||||
COPY ./docker/dinum-frontend/nginx/default.conf /etc/nginx/conf.d
|
||||
COPY ./docker/files/usr/local/bin/entrypoint /usr/local/bin/entrypoint
|
||||
COPY ./docker/dinum-frontend/Caddyfile /etc/caddy/Caddyfile
|
||||
COPY ./docker/caddy/media-proxy.caddy /etc/caddy/media-proxy.caddy
|
||||
|
||||
ENTRYPOINT [ "/usr/local/bin/entrypoint" ]
|
||||
ENV PORT=8080
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
ENTRYPOINT ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"]
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
server {
|
||||
listen 8080;
|
||||
server_name localhost;
|
||||
server_tokens off;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
location = /.well-known/windows-app-web-link {
|
||||
default_type application/json;
|
||||
alias /usr/share/nginx/html/.well-known/windows-app-web-link;
|
||||
add_header Content-Disposition "attachment; filename=windows-app-web-link";
|
||||
}
|
||||
|
||||
# Manifest — fetched, never iframed
|
||||
location = /addons/outlook/manifest.xml {
|
||||
alias /usr/share/nginx/html/addons/outlook/manifest.xml;
|
||||
|
||||
add_header Access-Control-Allow-Origin "*";
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header X-Frame-Options "DENY";
|
||||
add_header Content-Security-Policy "frame-ancestors 'none'";
|
||||
}
|
||||
|
||||
location = /addons/outlook/assets/ {
|
||||
return 404;
|
||||
}
|
||||
|
||||
location ~* ^/addons/outlook/assets/(.+\.(?:css|js|json|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot))/?$ {
|
||||
root /usr/share/nginx/html;
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, max-age=2592000, immutable" always;
|
||||
add_header Access-Control-Allow-Origin "*";
|
||||
add_header Vary "Origin" always;
|
||||
}
|
||||
|
||||
location = /addons/outlook/ {
|
||||
return 404;
|
||||
}
|
||||
|
||||
location ~ ^/addons/outlook(/.*)?$ {
|
||||
alias /usr/share/nginx/html/addons/outlook$1;
|
||||
error_page 404 =200 /index.html;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache" always;
|
||||
add_header Expires 0 always;
|
||||
|
||||
set $ms_domains "https://*.live.com https://*.office.com https://*.microsoft.com https://*.office365.com https://*.sharepoint.com";
|
||||
|
||||
set $nonce $request_id;
|
||||
|
||||
set $csp "default-src 'self'; upgrade-insecure-requests; ";
|
||||
set $csp "${csp}frame-ancestors ${ms_domains}; ";
|
||||
set $csp "${csp}script-src 'nonce-${nonce}' 'strict-dynamic'; ";
|
||||
set $csp "${csp}style-src 'self' 'unsafe-inline'; ";
|
||||
set $csp "${csp}img-src 'self' data:; ";
|
||||
set $csp "${csp}font-src 'self' data:; ";
|
||||
set $csp "${csp}connect-src 'self' ${ms_domains}; ";
|
||||
set $csp "${csp}frame-src 'none'; ";
|
||||
set $csp "${csp}object-src 'none'; ";
|
||||
set $csp "${csp}base-uri 'none'; ";
|
||||
|
||||
add_header Content-Security-Policy $csp;
|
||||
|
||||
sub_filter 'NONCE_PLACEHOLDER' $nonce;
|
||||
sub_filter_once off;
|
||||
}
|
||||
|
||||
location ^~ /assets/mediapipe/wasm/ {
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, max-age=2592000";
|
||||
}
|
||||
|
||||
# Serve static files with caching
|
||||
location ~* ^/assets/.*\.(css|js|json|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, max-age=2592000";
|
||||
}
|
||||
|
||||
# Serve static files
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
# Add no-cache headers
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache"; # HTTP 1.0 header for backward compatibility
|
||||
add_header Expires 0;
|
||||
}
|
||||
|
||||
# Optionally, handle 404 errors by redirecting to index.html
|
||||
error_page 404 =200 /index.html;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
# Global options
|
||||
{
|
||||
auto_https off
|
||||
admin off
|
||||
}
|
||||
|
||||
:{$PORT} {
|
||||
root * /usr/share/nginx/html
|
||||
encode gzip
|
||||
|
||||
# Vite fingerprints everything under /assets, so a given URL's bytes never
|
||||
# change: cache it forever. A new build emits new hashed URLs.
|
||||
@immutable path /assets/*
|
||||
header @immutable Cache-Control "public, max-age=2592000, immutable"
|
||||
|
||||
# The SPA shell and other non-fingerprinted files must revalidate every
|
||||
# load, or a deploy's new asset hashes only show up after a hard refresh.
|
||||
@revalidate not path /assets/*
|
||||
header @revalidate {
|
||||
Cache-Control "no-cache, no-store, must-revalidate"
|
||||
Pragma "no-cache"
|
||||
Expires 0
|
||||
}
|
||||
|
||||
route {
|
||||
import /etc/caddy/media-proxy.caddy
|
||||
try_files {path} /index.html
|
||||
file_server
|
||||
}
|
||||
|
||||
handle_errors {
|
||||
@spa_404 expression `{err.status_code} == 404`
|
||||
handle @spa_404 {
|
||||
rewrite * /index.html
|
||||
file_server
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
-13
@@ -41,24 +41,24 @@ ENV VITE_APP_TITLE=${VITE_APP_TITLE}
|
||||
|
||||
RUN npm run build
|
||||
|
||||
# ---- Caddy builder image ----
|
||||
FROM caddy:2.11.4-builder AS caddy-builder
|
||||
|
||||
RUN xcaddy build --with github.com/caddyserver/replace-response
|
||||
RUN apk add --no-cache libcap && \
|
||||
setcap -r /usr/bin/caddy
|
||||
|
||||
# ---- Front-end image ----
|
||||
FROM nginxinc/nginx-unprivileged:1.30.4-alpine3.24 AS frontend-production
|
||||
|
||||
USER root
|
||||
RUN apk del curl
|
||||
USER nginx
|
||||
|
||||
# Un-privileged user running the application
|
||||
ARG DOCKER_USER
|
||||
USER ${DOCKER_USER}
|
||||
FROM gcr.io/distroless/static-debian12:nonroot AS frontend-production
|
||||
|
||||
COPY --from=caddy-builder /usr/bin/caddy /usr/bin/caddy
|
||||
COPY --from=meet-builder \
|
||||
/home/frontend/dist \
|
||||
/usr/share/nginx/html
|
||||
|
||||
COPY ./src/frontend/default.conf /etc/nginx/conf.d
|
||||
COPY ./docker/files/usr/local/bin/entrypoint /usr/local/bin/entrypoint
|
||||
COPY ./src/frontend/Caddyfile /etc/caddy/Caddyfile
|
||||
COPY ./docker/caddy/media-proxy.caddy /etc/caddy/media-proxy.caddy
|
||||
|
||||
ENTRYPOINT [ "/usr/local/bin/entrypoint" ]
|
||||
ENV PORT=8080
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
ENTRYPOINT ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"]
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
server {
|
||||
listen 8080;
|
||||
server_name localhost;
|
||||
server_tokens off;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
location ^~ /assets/mediapipe/wasm/ {
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, max-age=2592000";
|
||||
}
|
||||
|
||||
# Serve static files with caching
|
||||
location ~* ^/assets/.*\.(css|js|json|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, max-age=2592000";
|
||||
}
|
||||
|
||||
# Serve static files
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
# Add no-cache headers
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache"; # HTTP 1.0 header for backward compatibility
|
||||
add_header Expires 0;
|
||||
}
|
||||
|
||||
# Optionally, handle 404 errors by redirecting to index.html
|
||||
error_page 404 =200 /index.html;
|
||||
}
|
||||
@@ -256,37 +256,6 @@ posthog:
|
||||
ingressAssets:
|
||||
enabled: false
|
||||
|
||||
# ---- Extra ingress/service for recording file downloads -----------
|
||||
|
||||
ingressMedia:
|
||||
enabled: true
|
||||
host: meet.127.0.0.1.nip.io
|
||||
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/rewrite-target: /meet-media-storage/$1
|
||||
|
||||
serviceMedia:
|
||||
host: minio.meet.svc.cluster.local
|
||||
port: 9000
|
||||
|
||||
# ---- Extra ingress/service for background file uploads ------------
|
||||
|
||||
ingressMediaFiles:
|
||||
enabled: true
|
||||
host: meet.127.0.0.1.nip.io
|
||||
|
||||
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/rewrite-target: /meet-media-storage/files/$1
|
||||
|
||||
serviceMediaFiles:
|
||||
host: minio.meet.svc.cluster.local
|
||||
port: 9000
|
||||
|
||||
# ---- STT Orchestration Microservice Components --------------------
|
||||
|
||||
summary:
|
||||
|
||||
@@ -23,9 +23,6 @@ frontend:
|
||||
- name: outlook-addon-manifest
|
||||
configMap:
|
||||
name: outlook-addon-manifest
|
||||
- name: frontend-nginx-config
|
||||
configMap:
|
||||
name: frontend-nginx-config
|
||||
|
||||
extraVolumeMounts:
|
||||
- name: outlook-addon-config
|
||||
@@ -36,10 +33,6 @@ frontend:
|
||||
mountPath: /usr/share/nginx/html/addons/outlook/manifest.xml
|
||||
subPath: manifest.xml
|
||||
readOnly: true
|
||||
- name: frontend-nginx-config
|
||||
mountPath: /etc/nginx/conf.d/default.conf
|
||||
subPath: default.conf
|
||||
readOnly: true
|
||||
|
||||
outlookAddon:
|
||||
enabled: true
|
||||
@@ -49,5 +42,3 @@ frontend:
|
||||
appName: "Visio"
|
||||
id: "a025f0f6-757a-4790-97f3-99c66c4a5795"
|
||||
|
||||
frontendNginxConfig:
|
||||
enabled: true
|
||||
|
||||
@@ -55,5 +55,3 @@ agentSubtitles:
|
||||
- key: cacert.pem
|
||||
path: cert.pem
|
||||
|
||||
frontendNginxConfig:
|
||||
enabled: false
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
{{- if .Values.frontendNginxConfig.enabled }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: frontend-nginx-config
|
||||
namespace: {{ .Release.Namespace }}
|
||||
data:
|
||||
default.conf: |
|
||||
server {
|
||||
listen 8080;
|
||||
server_name localhost;
|
||||
server_tokens off;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
location = /.well-known/windows-app-web-link {
|
||||
default_type application/json;
|
||||
alias /usr/share/nginx/html/.well-known/windows-app-web-link;
|
||||
add_header Content-Disposition "attachment; filename=windows-app-web-link";
|
||||
}
|
||||
|
||||
# Manifest — fetched, never iframed
|
||||
location = /addons/outlook/manifest.xml {
|
||||
alias /usr/share/nginx/html/addons/outlook/manifest.xml;
|
||||
|
||||
add_header Access-Control-Allow-Origin "*";
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header X-Frame-Options "DENY";
|
||||
add_header Content-Security-Policy "frame-ancestors 'none'";
|
||||
}
|
||||
|
||||
location = /addons/outlook/assets/ {
|
||||
return 404;
|
||||
}
|
||||
|
||||
location ~* ^/addons/outlook/assets/(.+\.(?:css|js|json|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot))/?$ {
|
||||
root /usr/share/nginx/html;
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, max-age=2592000, immutable" always;
|
||||
add_header Access-Control-Allow-Origin "*";
|
||||
add_header Vary "Origin" always;
|
||||
}
|
||||
|
||||
location = /addons/outlook/ {
|
||||
return 404;
|
||||
}
|
||||
|
||||
location ~ ^/addons/outlook(/.*)?$ {
|
||||
alias /usr/share/nginx/html/addons/outlook$1;
|
||||
error_page 404 =200 /index.html;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache" always;
|
||||
add_header Expires 0 always;
|
||||
|
||||
set $ms_domains "https://*.live.com https://*.office.com https://*.microsoft.com https://*.office365.com https://*.sharepoint.com";
|
||||
|
||||
set $nonce $request_id;
|
||||
|
||||
set $csp "default-src 'self'; upgrade-insecure-requests; ";
|
||||
set $csp "${csp}frame-ancestors ${ms_domains}; ";
|
||||
set $csp "${csp}script-src 'nonce-${nonce}' 'strict-dynamic'; ";
|
||||
set $csp "${csp}style-src 'self' 'unsafe-inline'; ";
|
||||
set $csp "${csp}img-src 'self' data:; ";
|
||||
set $csp "${csp}font-src 'self' data:; ";
|
||||
set $csp "${csp}connect-src 'self' ${ms_domains}; ";
|
||||
set $csp "${csp}frame-src 'none'; ";
|
||||
set $csp "${csp}object-src 'none'; ";
|
||||
set $csp "${csp}base-uri 'none'; ";
|
||||
|
||||
add_header Content-Security-Policy $csp;
|
||||
|
||||
sub_filter 'NONCE_PLACEHOLDER' $nonce;
|
||||
sub_filter_once off;
|
||||
}
|
||||
|
||||
location ^~ /assets/mediapipe/wasm/ {
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, max-age=2592000";
|
||||
}
|
||||
|
||||
# Serve static files with caching
|
||||
location ~* ^/assets/.*\.(css|js|json|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, max-age=2592000";
|
||||
}
|
||||
|
||||
# Serve static files
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
# Add no-cache headers
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache"; # HTTP 1.0 header for backward compatibility
|
||||
add_header Expires 0;
|
||||
}
|
||||
|
||||
# Optionally, handle 404 errors by redirecting to index.html
|
||||
error_page 404 =200 /index.html;
|
||||
}
|
||||
{{- end }}
|
||||
+5
-19
@@ -34,24 +34,6 @@
|
||||
| `ingressAdmin.tls.secretName` | Secret name for TLS config | `nil` |
|
||||
| `ingressAdmin.tls.additional[].secretName` | Secret name for additional TLS config | |
|
||||
| `ingressAdmin.tls.additional[].hosts[]` | Hosts for additional TLS config | |
|
||||
| `ingressMedia.enabled` | whether to enable the Ingress or not | `false` |
|
||||
| `ingressMedia.className` | IngressClass to use for the Ingress | `nil` |
|
||||
| `ingressMedia.host` | Host for the Ingress | `meet.example.com` |
|
||||
| `ingressMedia.path` | Path to use for the Ingress | `/media/(.*)` |
|
||||
| `ingressMedia.hosts` | Additional host to configure for the Ingress | `[]` |
|
||||
| `ingressMedia.tls.enabled` | Weather to enable TLS for the Ingress | `true` |
|
||||
| `ingressMedia.tls.secretName` | Secret name for TLS config | `nil` |
|
||||
| `ingressMedia.tls.additional[].secretName` | Secret name for additional TLS config | |
|
||||
| `ingressMedia.tls.additional[].hosts[]` | Hosts for additional TLS config | |
|
||||
| `ingressMedia.annotations.nginx.ingress.kubernetes.io/auth-url` | | `https://meet.example.com/api/v1.0/recordings/media-auth/` |
|
||||
| `ingressMedia.annotations.nginx.ingress.kubernetes.io/auth-response-headers` | | `Authorization, X-Amz-Date, X-Amz-Content-SHA256` |
|
||||
| `ingressMedia.annotations.nginx.ingress.kubernetes.io/upstream-vhost` | | `minio.meet.svc.cluster.local:9000` |
|
||||
| `ingressMedia.annotations.nginx.ingress.kubernetes.io/configuration-snippet` | | `add_header Content-Security-Policy "default-src 'none'" always;
|
||||
` |
|
||||
| `serviceMedia.host` | | `minio.meet.svc.cluster.local` |
|
||||
| `serviceMedia.port` | | `9000` |
|
||||
| `serviceMedia.annotations` | | `{}` |
|
||||
|
||||
### backend
|
||||
|
||||
| Name | Description | Value |
|
||||
@@ -125,7 +107,11 @@
|
||||
| `frontend.envVars.FROM_CONFIGMAP.configMapKeyRef.key` | Key within a ConfigMap when configuring env vars from a ConfigMap | |
|
||||
| `frontend.envVars.FROM_SECRET.secretKeyRef.name` | Name of a Secret when configuring env vars from a Secret | |
|
||||
| `frontend.envVars.FROM_SECRET.secretKeyRef.key` | Key within a Secret when configuring env vars from a Secret | |
|
||||
| `frontend.podAnnotations` | Annotations to add to the frontend Pod | `{}` |
|
||||
| `frontend.podAnnotations` | Annotations to add to the frontend Pod | `{}` | |
|
||||
| `frontend.mediaProxy.storageHost` | Hostname of the S3/MinIO endpoint serving recordings and files | `minio.meet.svc.cluster.local` |
|
||||
| `frontend.mediaProxy.storageProtocol` | The protocol of the S3/MinIO endpoint serving recordings and files | http |
|
||||
| `frontend.mediaProxy.storagePort` | Port of the S3/MinIO endpoint serving recordings and files | `9000` |
|
||||
| `frontend.mediaProxy.bucketName` | Name of the S3/MinIO bucket storing recordings and files | `meet-media-storage` |
|
||||
| `frontend.service.type` | frontend Service type | `ClusterIP` |
|
||||
| `frontend.service.port` | frontend Service listening port | `80` |
|
||||
| `frontend.service.targetPort` | frontend container listening port | `8080` |
|
||||
|
||||
@@ -54,6 +54,18 @@ spec:
|
||||
{{- if $envVars }}
|
||||
{{- $envVars | indent 12 }}
|
||||
{{- end }}
|
||||
- name: BACKEND_INTERNAL_HOST
|
||||
value: {{ include "meet.backend.fullname" . | quote }}
|
||||
- name: BACKEND_INTERNAL_PORT
|
||||
value: {{ .Values.backend.service.port | quote }}
|
||||
- name: MEDIA_STORAGE_HOST
|
||||
value: {{ .Values.frontend.mediaProxy.storageHost | quote }}
|
||||
- name: MEDIA_STORAGE_PROTOCOL
|
||||
value: {{ .Values.frontend.mediaProxy.storageProtocol | quote }}
|
||||
- name: MEDIA_STORAGE_PORT
|
||||
value: {{ .Values.frontend.mediaProxy.storagePort | quote }}
|
||||
- name: AWS_STORAGE_BUCKET_NAME
|
||||
value: {{ .Values.frontend.mediaProxy.bucketName | quote }}
|
||||
{{- with .Values.frontend.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
{{- if .Values.ingressMedia.enabled -}}
|
||||
{{- $fullName := include "meet.fullname" . -}}
|
||||
{{- if and .Values.ingressMedia.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingressMedia.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingressMedia.annotations "kubernetes.io/ingress.class" .Values.ingressMedia.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}-media
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "meet.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingressMedia.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if and .Values.ingressMedia.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||
ingressClassName: {{ .Values.ingressMedia.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingressMedia.tls.enabled }}
|
||||
tls:
|
||||
{{- if .Values.ingressMedia.host }}
|
||||
- secretName: {{ .Values.ingressMedia.tls.secretName | default (printf "%s-tls" $fullName) | quote }}
|
||||
hosts:
|
||||
- {{ .Values.ingressMedia.host | quote }}
|
||||
{{- end }}
|
||||
{{- range .Values.ingressMedia.tls.additional }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- if .Values.ingressMedia.host }}
|
||||
- host: {{ .Values.ingressMedia.host | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: {{ .Values.ingressMedia.path | quote }}
|
||||
{{- if semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
pathType: ImplementationSpecific
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
name: {{ $fullName }}-media
|
||||
port:
|
||||
number: {{ .Values.serviceMedia.port }}
|
||||
{{- else }}
|
||||
serviceName: {{ $fullName }}-media
|
||||
servicePort: {{ .Values.serviceMedia.port }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- range .Values.ingressMedia.hosts }}
|
||||
- host: {{ . | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: {{ $.Values.ingressMedia.path | quote }}
|
||||
{{- if semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
pathType: ImplementationSpecific
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
name: {{ $fullName }}-media
|
||||
port:
|
||||
number: {{ .Values.serviceMedia.port }}
|
||||
{{- else }}
|
||||
serviceName: {{ $fullName }}-media
|
||||
servicePort: {{ .Values.serviceMedia.port }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,83 +0,0 @@
|
||||
{{- if .Values.ingressMediaFiles.enabled -}}
|
||||
{{- $fullName := include "meet.fullname" . -}}
|
||||
{{- if and .Values.ingressMediaFiles.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingressMediaFiles.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingressMediaFiles.annotations "kubernetes.io/ingress.class" .Values.ingressMediaFiles.className }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}-media-files
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "meet.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingressMediaFiles.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if and .Values.ingressMediaFiles.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||
ingressClassName: {{ .Values.ingressMediaFiles.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingressMediaFiles.tls.enabled }}
|
||||
tls:
|
||||
{{- if .Values.ingressMediaFiles.host }}
|
||||
- secretName: {{ .Values.ingressMediaFiles.tls.secretName | default (printf "%s-tls" $fullName) | quote }}
|
||||
hosts:
|
||||
- {{ .Values.ingressMediaFiles.host | quote }}
|
||||
{{- end }}
|
||||
{{- range .Values.ingressMediaFiles.tls.additional }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- if .Values.ingressMediaFiles.host }}
|
||||
- host: {{ .Values.ingressMediaFiles.host | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: {{ .Values.ingressMediaFiles.path | quote }}
|
||||
{{- if semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
pathType: ImplementationSpecific
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
name: {{ $fullName }}-media-files
|
||||
port:
|
||||
number: {{ .Values.serviceMediaFiles.port }}
|
||||
{{- else }}
|
||||
serviceName: {{ $fullName }}-media-files
|
||||
servicePort: {{ .Values.serviceMediaFiles.port }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- range .Values.ingressMediaFiles.hosts }}
|
||||
- host: {{ . | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: {{ $.Values.ingressMediaFiles.path | quote }}
|
||||
{{- if semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
pathType: ImplementationSpecific
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
name: {{ $fullName }}-media-files
|
||||
port:
|
||||
number: {{ .Values.serviceMediaFiles.port }}
|
||||
{{- else }}
|
||||
serviceName: {{ $fullName }}-media-files
|
||||
servicePort: {{ .Values.serviceMediaFiles.port }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,14 +0,0 @@
|
||||
{{- $fullName := include "meet.fullname" . -}}
|
||||
{{- $component := "media-files" -}}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ $fullName }}-media-files
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "meet.common.labels" (list . $component) | nindent 4 }}
|
||||
annotations:
|
||||
{{- toYaml $.Values.serviceMediaFiles.annotations | nindent 4 }}
|
||||
spec:
|
||||
type: ExternalName
|
||||
externalName: {{ $.Values.serviceMediaFiles.host }}
|
||||
@@ -1,14 +0,0 @@
|
||||
{{- $fullName := include "meet.fullname" . -}}
|
||||
{{- $component := "media" -}}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ $fullName }}-media
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "meet.common.labels" (list . $component) | nindent 4 }}
|
||||
annotations:
|
||||
{{- toYaml $.Values.serviceMedia.annotations | nindent 4 }}
|
||||
spec:
|
||||
type: ExternalName
|
||||
externalName: {{ $.Values.serviceMedia.host }}
|
||||
+10
-88
@@ -98,94 +98,6 @@ ingressAdmin:
|
||||
enabled: true
|
||||
additional: []
|
||||
|
||||
## @param ingressMedia.enabled whether to enable the Ingress or not
|
||||
## @param ingressMedia.className IngressClass to use for the Ingress
|
||||
## @param ingressMedia.host Host for the Ingress
|
||||
## @param ingressMedia.path Path to use for the Ingress
|
||||
ingressMedia:
|
||||
enabled: false
|
||||
className: null
|
||||
host: meet.example.com
|
||||
path: /media/(.*)
|
||||
## @param ingressMedia.hosts Additional host to configure for the Ingress
|
||||
hosts: [ ]
|
||||
# - chart-example.local
|
||||
## @param ingressMedia.tls.enabled Whether to enable TLS for the Ingress
|
||||
## @param ingressMedia.tls.secretName Secret name for TLS config
|
||||
## @skip ingressMedia.tls.additional
|
||||
## @extra ingressMedia.tls.additional[].secretName Secret name for additional TLS config
|
||||
## @extra ingressMedia.tls.additional[].hosts[] Hosts for additional TLS config
|
||||
tls:
|
||||
secretName: null
|
||||
enabled: true
|
||||
additional: []
|
||||
|
||||
## @param ingressMedia.annotations.nginx.ingress.kubernetes.io/auth-url
|
||||
## @param ingressMedia.annotations.nginx.ingress.kubernetes.io/auth-response-headers
|
||||
## @param ingressMedia.annotations.nginx.ingress.kubernetes.io/upstream-vhost
|
||||
## @param ingressMedia.annotations.nginx.ingress.kubernetes.io/configuration-snippet
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/use-regex: "true"
|
||||
nginx.ingress.kubernetes.io/auth-url: https://meet.example.com/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/configuration-snippet: |
|
||||
add_header Content-Security-Policy "default-src 'none'" always;
|
||||
|
||||
## @param serviceMedia.host
|
||||
## @param serviceMedia.port
|
||||
## @param serviceMedia.annotations
|
||||
serviceMedia:
|
||||
host: minio.meet.svc.cluster.local
|
||||
port: 9000
|
||||
annotations: {}
|
||||
|
||||
|
||||
## @param ingressMediaFiles.enabled whether to enable the Ingress or not
|
||||
## @param ingressMediaFiles.className IngressClass to use for the Ingress
|
||||
## @param ingressMediaFiles.host Host for the Ingress
|
||||
## @param ingressMediaFiles.path Path to use for the Ingress
|
||||
ingressMediaFiles:
|
||||
enabled: false
|
||||
className: null
|
||||
host: meet.example.com
|
||||
path: /media/files/(.*)
|
||||
## @param ingressMediaFiles.hosts Additional host to configure for the Ingress
|
||||
hosts: [ ]
|
||||
# - chart-example.local
|
||||
## @param ingressMediaFiles.tls.enabled Weather to enable TLS for the Ingress
|
||||
## @param ingressMediaFiles.tls.secretName Secret name for TLS config
|
||||
## @skip ingressMediaFiles.tls.additional
|
||||
## @extra ingressMediaFiles.tls.additional[].secretName Secret name for additional TLS config
|
||||
## @extra ingressMediaFiles.tls.additional[].hosts[] Hosts for additional TLS config
|
||||
tls:
|
||||
secretName: null
|
||||
enabled: true
|
||||
additional: []
|
||||
|
||||
## @param ingressMediaFiles.annotations.nginx.ingress.kubernetes.io/auth-url
|
||||
## @param ingressMediaFiles.annotations.nginx.ingress.kubernetes.io/auth-response-headers
|
||||
## @param ingressMediaFiles.annotations.nginx.ingress.kubernetes.io/upstream-vhost
|
||||
## @param ingressMediaFiles.annotations.nginx.ingress.kubernetes.io/configuration-snippet
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/use-regex: "true"
|
||||
nginx.ingress.kubernetes.io/auth-url: https://meet.example.com/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/configuration-snippet: |
|
||||
add_header Content-Security-Policy "default-src 'none'" always;
|
||||
add_header Content-Disposition "attachment";
|
||||
|
||||
## @param serviceMediaFiles.host
|
||||
## @param serviceMediaFiles.port
|
||||
## @param serviceMediaFiles.annotations
|
||||
serviceMediaFiles:
|
||||
host: minio.meet.svc.cluster.local
|
||||
port: 9000
|
||||
annotations: {}
|
||||
|
||||
|
||||
|
||||
## @section backend
|
||||
|
||||
backend:
|
||||
@@ -417,6 +329,16 @@ frontend:
|
||||
## @param frontend.podAnnotations Annotations to add to the frontend Pod
|
||||
podAnnotations: {}
|
||||
|
||||
## @param frontend.mediaProxy.storageHost Hostname of the S3/MinIO endpoint serving recordings and files
|
||||
## @param frontend.mediaProxy.storageProtocol Protocol of the S3/MinIO endpoint serving recordings and files
|
||||
## @param frontend.mediaProxy.storagePort Port of the S3/MinIO endpoint serving recordings and files
|
||||
## @param frontend.mediaProxy.bucketName Name of the S3/MinIO bucket storing recordings and files
|
||||
mediaProxy:
|
||||
storageHost: minio.meet.svc.cluster.local
|
||||
storageProtocol: http
|
||||
storagePort: 9000
|
||||
bucketName: meet-media-storage
|
||||
|
||||
## @param frontend.service.type frontend Service type
|
||||
## @param frontend.service.port frontend Service listening port
|
||||
## @param frontend.service.targetPort frontend container listening port
|
||||
|
||||
Reference in New Issue
Block a user