diff --git a/abra.sh b/abra.sh index 17d3f3e..c1656cb 100644 --- a/abra.sh +++ b/abra.sh @@ -1 +1,3 @@ export CERTDUMPER_POST_VERSION=v1 +export LIVEKIT_CONFIG_VERSION=v1 +export EGRESS_CONFIG_VERSION=v1 diff --git a/compose.livekit.yml b/compose.livekit.yml new file mode 100644 index 0000000..328502c --- /dev/null +++ b/compose.livekit.yml @@ -0,0 +1,150 @@ +services: + livekit: + image: livekit/livekit-server:v1.10.1 + command: --config /etc/livekit/config.yaml + ports: + - target: 7881 + published: 7881 + protocol: udp + mode: host + labels: + # TODO: Make livekit domain configurable + # TODO: Add STACK_NAME + - "traefik.enable=true" + - "traefik.http.routers.livekit.rule=Host(`livekit.${DOMAIN}`)" + - "traefik.http.routers.livekit.entryPoints=web" + - "traefik.http.services.livekit.loadbalancer.server.port=7880" + # TODO: Traefik UDP? + # - "traefik.udp.routers.livekit-udp.entrypoints=udp" + # - "traefik.udp.routers.livekit-udp.service=livekit-udp" + # - "traefik.udp.services.livekit-udp.loadbalancer.server.port=7881" + - "caddy_0=livekit.${DOMAIN}" + - "caddy_0.reverse_proxy={{upstreams 7880}}" + - "caddy_0.tls.on_demand=" + # TODO: Caddy UDP? + configs: + - source: livekit_config + target: /etc/livekit/config.yaml + networks: + - proxy + - internal + + egress: + image: livekit/egress:v1.12.0 + labels: + # TODO: Make egress domain configurable + # TODO: Add STACK_NAME + - "traefik.enable=true" + - "traefik.http.routers.egress.rule=Host(`egress.${DOMAIN}`)" + - "traefik.http.routers.egress.entryPoints=web" + - "traefik.http.services.egress.loadbalancer.server.port=8080" + - "caddy_1=egress.${DOMAIN}" + - "caddy_1.reverse_proxy={{upstreams 8080}}" + - "caddy_1.tls.on_demand=" + environment: + EGRESS_CONFIG_FILE: /etc/egress/config.yaml + DISABLE_CUDA: "true" + DISABLE_NVENC: "true" + EGRESS_OUTPUT_DIR: "/out" + configs: + - source: egress_config + target: /etc/egress/config.yaml + extra_hosts: + - "host.docker.internal:host-gateway" + cap_add: + - SYS_ADMIN + privileged: true + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8081/health"] + interval: 5s + timeout: 3s + retries: 3 + networks: + - proxy + + rustfs: + image: rustfs/rustfs:1.0.0-alpha.83 + command: ["/data"] + labels: + - "traefik.enable=true" + # TODO: Make rustfs domain configurable + # TODO: Add STACK_NAME + - "traefik.http.routers.rustfs-livekit.rule=Host(`rustfs-livekit.${DOMAIN}`)" + - "traefik.http.routers.rustfs-livekit.entryPoints=web" + - "traefik.http.services.rustfs-livekit.loadbalancer.server.port=9001" + - "traefik.http.routers.rustfs-livekit.service=rustfs-livekit" + - "caddy_2=rustfs.${DOMAIN}" + - "caddy_2.reverse_proxy={{upstreams 9001}}" + - "caddy_2.tls.on_demand=" + # TODO: Make rustfs CDN domain configurable + - "traefik.http.routers.cdn-livekit.rule=Host(`cdn-livekit.${DOMAIN}`)" + - "traefik.http.routers.cdn-livekit.entryPoints=web" + - "traefik.http.services.cdn-livekit.loadbalancer.server.port=9000" + - "traefik.http.routers.cdn-livekit.service=cdn-livekit" + - "caddy_3=rustfs-cdn.${DOMAIN}" + - "caddy_3.reverse_proxy={{upstreams 9000}}" + - "caddy_3.tls.on_demand=" + environment: + RUSTFS_ACCESS_KEY: "rustfs-access-key" + RUSTFS_SECRET_KEY: "rustfs-secret-access-key" + RUSTFS_CONSOLE_ENABLE: "true" + networks: + - proxy + - internal + volumes: + - rustfs:/data + + rustfs-init: + image: amazon/aws-cli:2.31.1 + entrypoint: ["/bin/sh", "-ec"] + command: + - | + until aws --endpoint-url http://rustfs:9000 s3api list-buckets >/dev/null 2>&1; do + sleep 1 + done + aws --endpoint-url http://rustfs:9000 s3api head-bucket --bucket livekit-recording >/dev/null 2>&1 \ + || aws --endpoint-url http://rustfs:9000 s3api create-bucket \ + --bucket livekit-recording \ + --create-bucket-configuration LocationConstraint=eu-west-1 + environment: + AWS_ACCESS_KEY_ID: "rustfs-access-key" + AWS_SECRET_ACCESS_KEY: "rustfs-secret-access-key" + AWS_DEFAULT_REGION: "eu-west-1" + networks: + - internal + + back: + environment: + LIVEKIT_HOST: "https://livekit.${DOMAIN}" + LIVEKIT_API_KEY: "devkey" + LIVEKIT_API_SECRET: "12345678901234567890123456789012" + MAX_USERS_FOR_WEBRTC: "2" + LIVEKIT_RECORDING_S3_ENDPOINT: "http://rustfs:9000" + LIVEKIT_RECORDING_S3_ACCESS_KEY: "rustfs-access-key" + LIVEKIT_RECORDING_S3_SECRET_KEY: "rustfs-secret-access-key" + LIVEKIT_RECORDING_S3_REGION: "eu-west-1" + LIVEKIT_RECORDING_S3_BUCKET: "livekit-recording" + LIVEKIT_RECORDING_S3_CDN_ENDPOINT: "https://rustfs-cdn.$DOMAIN" + + app: + environment: + LIVEKIT_RECORDING_S3_ENDPOINT: "http://rustfs:9000" + LIVEKIT_RECORDING_S3_ACCESS_KEY: "rustfs-access-key" + LIVEKIT_RECORDING_S3_SECRET_KEY: "rustfs-secret-access-key" + LIVEKIT_RECORDING_S3_REGION: "eu-west-1" + LIVEKIT_RECORDING_S3_BUCKET: "livekit-recording" + LIVEKIT_RECORDING_S3_CDN_ENDPOINT: "https://rustfs-cdn.$DOMAIN" + LIVEKIT_PIXEL_DENSITY: "${LIVEKIT_PIXEL_DENSITY:-}" + +configs: + livekit_config: + name: ${STACK_NAME}_livekit_config_${LIVEKIT_CONFIG_VERSION} + file: livekit-config.yaml.tmpl + template_driver: golang + egress_config: + name: ${STACK_NAME}_egress_config_${EGRESS_CONFIG_VERSION} + file: egress-config.yaml.tmpl + template_driver: golang + +volumes: + rustfs: diff --git a/compose.yml b/compose.yml index 999ae1a..6048d41 100644 --- a/compose.yml +++ b/compose.yml @@ -1,4 +1,3 @@ -version: "3.6" services: app: image: thecodingmachine/workadventure-play:v1.30.6 @@ -26,16 +25,16 @@ services: - INTERNAL_MAP_STORAGE_URL=http://map-storage:3000 - PUBLIC_MAP_STORAGE_URL=https://${DOMAIN}/map-storage - START_ROOM_URL - - OPID_PROMPT=login - - OPID_WOKA_NAME_POLICY - - OPID_CLIENT_ID - - OPID_CLIENT_SECRET - - OPID_CLIENT_ISSUER - - OPID_PROFILE_SCREEN_PROVIDER - - OPID_SCOPE - - OPID_USERNAME_CLAIM - - OPID_LOCALE_CLAIM - - OPID_LOGOUT_REDIRECT_URL + - OPENID_PROMPT=login + - OPENID_WOKA_NAME_POLICY + - OPENID_CLIENT_ID + - OPENID_CLIENT_SECRET + - OPENID_CLIENT_ISSUER + - OPENID_PROFILE_SCREEN_PROVIDER + - OPENID_SCOPE + - OPENID_USERNAME_CLAIM + - OPENID_LOCALE_CLAIM + - OPENID_LOGOUT_REDIRECT_URL - FALLBACK_LOCALE - ENABLE_CHAT - ENABLE_CHAT_UPLOAD @@ -86,6 +85,7 @@ services: - GOOGLE_DRIVE_PICKER_CLIENT_ID=${GOOGLE_DRIVE_PICKER_CLIENT_ID} - GOOGLE_DRIVE_PICKER_APP_ID=${GOOGLE_DRIVE_PICKER_APP_ID} - MAP_STORAGE_API_TOKEN=${MAP_STORAGE_API_TOKEN:-${SECRET_KEY}} + - MAP_EDITOR_ALLOW_ALL_USERS deploy: labels: traefik.enable: "true" @@ -151,6 +151,7 @@ services: - SENTRY_DSN=${SENTRY_DSN_BACK} - SENTRY_RELEASE=${SENTRY_RELEASE} - SENTRY_TRACES_SAMPLE_RATE=${SENTRY_TRACES_SAMPLE_RATE} + - MAP_EDITOR_ALLOW_ALL_USERS deploy: labels: traefik.enable: "true" diff --git a/egress-config.yaml.tmpl b/egress-config.yaml.tmpl new file mode 100644 index 0000000..d1cf7f0 --- /dev/null +++ b/egress-config.yaml.tmpl @@ -0,0 +1,13 @@ +api_key: "devkey" +api_secret: "12345678901234567890123456789012" +ws_url: "ws://livekit:7880" +log_level: "debug" +insecure: true +template_port: 7980 +health_port: 8081 +prometheus_port: 9000 +redis: + address: "redis:6379" + username: "" + password: "" + db: 2 diff --git a/livekit-config.yaml.tmpl b/livekit-config.yaml.tmpl new file mode 100644 index 0000000..b0961cd --- /dev/null +++ b/livekit-config.yaml.tmpl @@ -0,0 +1,20 @@ +port: 7880 +rtc: + udp_port: 7882 + tcp_port: 7881 + use_external_ip: false +#room: +# enabled_codecs: +# - mime: audio/opus +# - mime: video/h264 +redis: + address: redis:6379 + username: "" + password: "" + db: 2 +keys: + devkey: 12345678901234567890123456789012 +logging: + json: false + #level: debug + level: info