Déploiement production scalable¶
Cette configuration reprend directement le Docker Compose de la configuration simple, puis adapte uniquement les services qui doivent être répliqués en production.
L’image utilisée est :
Différences avec la configuration simple¶
| Service | Configuration simple | Production scalable |
|---|---|---|
stream-fusion |
1 | 4 replicas |
taskiq-worker |
1 | 2 replicas |
taskiq-scheduler |
1 | 1 replica |
| PostgreSQL | 1 | 1 |
| Redis | 1 | 1 |
| Meilisearch | 1 | 1 |
| WARP | 1 | 1 |
Scheduler unique
taskiq-scheduler doit impérativement rester à 1 replica.
Scaling¶
Les adaptations apportées au Compose simple sont :
taskiq-worker:
deploy:
mode: replicated
replicas: 2
taskiq-scheduler:
deploy:
mode: replicated
replicas: 1
stream-fusion:
deploy:
mode: replicated
replicas: 4
container_name est supprimé de stream-fusion et
taskiq-worker, car plusieurs conteneurs doivent pouvoir être créés.
Le scheduler reste explicitement limité à une seule instance.
Architecture¶
| Service | Fonction |
|---|---|
stream-fusion |
Application — 4 replicas |
taskiq-worker |
Traitement asynchrone — 2 replicas |
taskiq-scheduler |
Scheduler — 1 replica |
stremio-postgres |
PostgreSQL 17 |
postgres-security-init |
Sécurisation des rôles PostgreSQL |
pg-restore-secret-init |
Secret de restauration PostgreSQL |
stremio-redis |
Redis 7 |
meilisearch |
Recherche et indexation |
meili-init |
Initialisation/restauration Meilisearch |
warp |
Proxy WARP |
PostgreSQL¶
La configuration sécurisée du Compose simple est intégralement conservée :
streamfusion_owner;streamfusion_runtime;streamfusion_migration;streamfusion_restore.
Le secret de restauration PostgreSQL est généré automatiquement dans
le volume pg-restore-secret.
Aucun PG_RESTORE_PASS n’est nécessaire dans .env.
Réseau et reverse proxy¶
Le réseau Docker externe utilisé est :
Vérification :
Création si nécessaire :
Le reverse proxy doit être connecté à ce réseau afin de distribuer les
requêtes entre les quatre replicas stream-fusion.
Fichier .env¶
La production utilise les mêmes variables que la configuration simple.
# =============================================================================
# Stream Fusion Reborn — Environment Configuration
# =============================================================================
#
# ADMIN_SECRET_KEY = clé choisie par l'utilisateur pour l'interface admin.
# Les autres secrets internes doivent être générés séparément.
#
# Génération d'un secret interne :
# openssl rand -hex 32
#
# IMPORTANT :
# POSTGRES_PASSWORD, PG_PASS et PG_MIGRATION_PASS doivent être des valeurs
# hexadécimales de 64 caractères et toutes différentes.
# =============================================================================
# ── Valeurs utilisateur ────────────────────────────────────────────────────────
ADMIN_SECRET_KEY=replace-with-your-admin-key-at-least-32-characters
TMDB_API_KEY=replace-with-your-tmdb-api-key
# ── Secrets internes ──────────────────────────────────────────────────────────
SECRET_API_KEY=RANDOM_64_HEX
CONFIG_SECRET_KEY=RANDOM_64_HEX
SESSION_KEY=RANDOM_64_HEX
PEER_MASTER_KEY=RANDOM_64_HEX
MEILI_MASTER_KEY=RANDOM_64_HEX
# ── PostgreSQL ────────────────────────────────────────────────────────────────
POSTGRES_PASSWORD=RANDOM_64_HEX
PG_PASS=RANDOM_64_HEX
PG_MIGRATION_PASS=RANDOM_64_HEX
# ── Déploiement ───────────────────────────────────────────────────────────────
TZ=Europe/Paris
USE_HTTPS=true
PROXY_URL=http://warp:1080
Docker Compose scalable¶
Le Compose ci-dessous conserve le Compose actuel de la configuration simple et ajoute uniquement les adaptations nécessaires au scaling.
docker-compose.yml¶
---
networks:
proxy_network:
external: true
name: traefik_proxy
services:
meili-init:
image: laster13/stream-fusion-reborn:latest
user: "0:0"
entrypoint: ["/bin/sh", "-c"]
command:
- |
set -eu
echo "[meili-init] Préparation"
mkdir -p /meili_wrapper
mkdir -p /meili_restore_control
cp \
/opt/streamfusion/meili-auto-restore.sh \
/meili_wrapper/.meili-auto-restore.sh.tmp
chmod 0555 \
/meili_wrapper/.meili-auto-restore.sh.tmp
mv -f \
/meili_wrapper/.meili-auto-restore.sh.tmp \
/meili_wrapper/meili-auto-restore.sh
chown -R 1000:1000 \
/meili_restore_control
chmod 0770 \
/meili_restore_control
find /meili_restore_control \
-type f \
-exec chmod 0660 {} \;
echo "[meili-init] Terminé"
volumes:
- meili-wrapper:/meili_wrapper
- meili-restore-control:/meili_restore_control
network_mode: "none"
restart: "no"
meilisearch:
image: getmeili/meilisearch:v1.41.0
container_name: meilisearch
environment:
MEILI_MASTER_KEY: ${MEILI_MASTER_KEY:?Provide MEILI_MASTER_KEY}
MEILI_ENV: production
MEILI_EXPERIMENTAL_DUMPLESS_UPGRADE: "true"
MEILI_DB_PATH: /meili_data/data.ms
expose:
- 7700
volumes:
- meili-data:/meili_data
- sfr-db-backups:/imports:ro
- meili-wrapper:/meili_wrapper:ro
- meili-restore-control:/meili_restore_control
command: ["/meili_wrapper/meili-auto-restore.sh"]
depends_on:
meili-init:
condition: service_completed_successfully
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:7700/health >/dev/null || exit 1"]
interval: 5s
timeout: 5s
retries: 10
start_period: 5s
restart: unless-stopped
networks:
- proxy_network
pg-restore-secret-init:
image: postgres:17-alpine
command:
- /bin/sh
- -ec
- |
set -eu
umask 077
secret=/run/pg-restore-secret/pg_restore_pass
tmp="$${secret}.tmp.$$$$"
if [ ! -s "$$secret" ]; then
rm -f "$$tmp"
od -An -N32 -tx1 /dev/urandom | tr -d ' \n' > "$$tmp"
test "$$(wc -c < "$$tmp" | tr -d ' ')" -eq 64
chmod 0444 "$$tmp"
mv -f "$$tmp" "$$secret"
fi
test "$$(wc -c < "$$secret" | tr -d ' ')" -eq 64
grep -Eq '^[0-9a-f]{64}$' "$$secret"
chmod 0444 "$$secret"
volumes:
- pg-restore-secret:/run/pg-restore-secret
network_mode: "none"
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
read_only: true
restart: "no"
stremio-postgres:
image: postgres:17-alpine
container_name: stremio-postgres
restart: unless-stopped
environment:
PGDATA: /var/lib/postgresql/data/pgdata
POSTGRES_USER: streamfusion
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
POSTGRES_DB: streamfusion
expose:
- 5432
volumes:
- stremio-postgres:/var/lib/postgresql/data/pgdata
healthcheck:
test:
- CMD-SHELL
- >-
PGPASSWORD="$$POSTGRES_PASSWORD"
psql -h 127.0.0.1
-U "$$POSTGRES_USER"
-d "$$POSTGRES_DB"
-X -qAt -v ON_ERROR_STOP=1
-c "SELECT 1"
| grep -qx 1
interval: 5s
timeout: 5s
retries: 20
start_period: 5s
networks:
- proxy_network
postgres-security-init:
image: postgres:17-alpine
restart: "no"
environment:
POSTGRES_USER: streamfusion
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
POSTGRES_DB: streamfusion
PG_PASS: ${PG_PASS:?PG_PASS is required}
PG_MIGRATION_PASS: ${PG_MIGRATION_PASS:?PG_MIGRATION_PASS is required}
PG_RESTORE_PASS_FILE: /run/pg-restore-secret/pg_restore_pass
volumes:
- pg-restore-secret:/run/pg-restore-secret:ro
depends_on:
pg-restore-secret-init:
condition: service_completed_successfully
stremio-postgres:
condition: service_healthy
command:
- /bin/sh
- -ec
- |
set -eu
echo "[postgres-security] Configuration des rôles Stream Fusion"
: "$${POSTGRES_USER:?POSTGRES_USER manquant}"
: "$${POSTGRES_DB:?POSTGRES_DB manquant}"
: "$${POSTGRES_PASSWORD:?POSTGRES_PASSWORD manquant}"
: "$${PG_PASS:?PG_PASS manquant}"
: "$${PG_MIGRATION_PASS:?PG_MIGRATION_PASS manquant}"
RESTORE_PASS_FILE="$${PG_RESTORE_PASS_FILE:-/run/pg-restore-secret/pg_restore_pass}"
validate_hex64() {
name="$$1"
value="$$2"
if [ "$${#value}" -ne 64 ]; then
echo "[postgres-security] ERREUR : $$name doit contenir exactement 64 caractères hexadécimaux"
exit 1
fi
case "$$value" in
*[!0-9a-f]*)
echo "[postgres-security] ERREUR : $$name doit être hexadécimal en minuscules"
exit 1
;;
esac
}
validate_hex64 "POSTGRES_PASSWORD" "$$POSTGRES_PASSWORD"
validate_hex64 "PG_PASS" "$$PG_PASS"
validate_hex64 "PG_MIGRATION_PASS" "$$PG_MIGRATION_PASS"
if [ ! -s "$$RESTORE_PASS_FILE" ]; then
echo "[postgres-security] ERREUR : secret restore absent : $$RESTORE_PASS_FILE"
exit 1
fi
RESTORE_PASS="$$(cat "$$RESTORE_PASS_FILE")"
validate_hex64 "PG_RESTORE_PASS" "$$RESTORE_PASS"
if [ "$$POSTGRES_PASSWORD" = "$$PG_PASS" ] || \
[ "$$POSTGRES_PASSWORD" = "$$PG_MIGRATION_PASS" ] || \
[ "$$POSTGRES_PASSWORD" = "$$RESTORE_PASS" ] || \
[ "$$PG_PASS" = "$$PG_MIGRATION_PASS" ] || \
[ "$$PG_PASS" = "$$RESTORE_PASS" ] || \
[ "$$PG_MIGRATION_PASS" = "$$RESTORE_PASS" ]; then
echo "[postgres-security] ERREUR : les quatre secrets PostgreSQL doivent être distincts"
exit 1
fi
export PGPASSWORD="$$POSTGRES_PASSWORD"
psql \
--host=stremio-postgres \
--username="$$POSTGRES_USER" \
--dbname="$$POSTGRES_DB" \
--no-psqlrc \
--set=ON_ERROR_STOP=1 \
--set=runtime_password="$$PG_PASS" \
--set=migration_password="$$PG_MIGRATION_PASS" \
--set=restore_password="$$RESTORE_PASS" <<'SQL'
DO $$$$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_roles
WHERE rolname = 'streamfusion_owner'
) THEN
CREATE ROLE streamfusion_owner;
END IF;
IF NOT EXISTS (
SELECT 1 FROM pg_roles
WHERE rolname = 'streamfusion_runtime'
) THEN
CREATE ROLE streamfusion_runtime LOGIN;
END IF;
IF NOT EXISTS (
SELECT 1 FROM pg_roles
WHERE rolname = 'streamfusion_migration'
) THEN
CREATE ROLE streamfusion_migration LOGIN;
END IF;
IF NOT EXISTS (
SELECT 1 FROM pg_roles
WHERE rolname = 'streamfusion_restore'
) THEN
CREATE ROLE streamfusion_restore LOGIN;
END IF;
END
$$$$;
ALTER ROLE streamfusion_owner
WITH NOLOGIN NOSUPERUSER CREATEDB NOCREATEROLE NOINHERIT NOREPLICATION NOBYPASSRLS;
ALTER ROLE streamfusion_runtime
WITH LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOREPLICATION NOBYPASSRLS
PASSWORD :'runtime_password';
ALTER ROLE streamfusion_migration
WITH LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOREPLICATION NOBYPASSRLS
PASSWORD :'migration_password';
ALTER ROLE streamfusion_restore
WITH LOGIN NOSUPERUSER CREATEDB NOCREATEROLE NOINHERIT NOREPLICATION NOBYPASSRLS
PASSWORD :'restore_password';
GRANT streamfusion_owner
TO streamfusion_migration
WITH INHERIT FALSE, SET TRUE;
GRANT streamfusion_owner
TO streamfusion_restore
WITH INHERIT FALSE, SET TRUE;
GRANT pg_signal_backend
TO streamfusion_restore
WITH INHERIT TRUE, SET TRUE;
DO $$$$
BEGIN
IF EXISTS (
SELECT 1
FROM pg_auth_members m
JOIN pg_roles parent ON parent.oid = m.roleid
JOIN pg_roles member ON member.oid = m.member
WHERE parent.rolname = 'streamfusion_owner'
AND member.rolname = 'streamfusion_runtime'
) THEN
EXECUTE 'REVOKE streamfusion_owner FROM streamfusion_runtime';
END IF;
END
$$$$;
ALTER DATABASE streamfusion OWNER TO streamfusion_owner;
ALTER SCHEMA public OWNER TO streamfusion_owner;
DO $$$$
DECLARE
obj record;
ddl text;
BEGIN
FOR obj IN
SELECT
n.nspname,
c.relname,
c.relkind
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'public'
AND pg_get_userbyid(c.relowner) = 'streamfusion'
AND c.relkind IN ('r', 'p', 'S', 'v', 'm', 'f')
AND NOT EXISTS (
SELECT 1
FROM pg_depend d
WHERE d.classid = 'pg_class'::regclass
AND d.objid = c.oid
AND d.deptype = 'e'
)
ORDER BY
CASE c.relkind
WHEN 'S' THEN 2
ELSE 1
END,
c.relname
LOOP
ddl := CASE obj.relkind
WHEN 'S' THEN format(
'ALTER SEQUENCE %I.%I OWNER TO streamfusion_owner',
obj.nspname, obj.relname
)
WHEN 'v' THEN format(
'ALTER VIEW %I.%I OWNER TO streamfusion_owner',
obj.nspname, obj.relname
)
WHEN 'm' THEN format(
'ALTER MATERIALIZED VIEW %I.%I OWNER TO streamfusion_owner',
obj.nspname, obj.relname
)
WHEN 'f' THEN format(
'ALTER FOREIGN TABLE %I.%I OWNER TO streamfusion_owner',
obj.nspname, obj.relname
)
ELSE format(
'ALTER TABLE %I.%I OWNER TO streamfusion_owner',
obj.nspname, obj.relname
)
END;
EXECUTE ddl;
END LOOP;
END
$$$$;
REVOKE ALL ON DATABASE streamfusion FROM PUBLIC;
GRANT CONNECT ON DATABASE streamfusion
TO streamfusion_runtime, streamfusion_migration, streamfusion_restore;
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
REVOKE CREATE ON SCHEMA public FROM streamfusion_runtime;
GRANT USAGE ON SCHEMA public TO streamfusion_runtime;
GRANT SELECT, INSERT, UPDATE, DELETE
ON ALL TABLES IN SCHEMA public
TO streamfusion_runtime;
GRANT USAGE, SELECT, UPDATE
ON ALL SEQUENCES IN SCHEMA public
TO streamfusion_runtime;
ALTER DEFAULT PRIVILEGES FOR ROLE streamfusion_owner IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO streamfusion_runtime;
ALTER DEFAULT PRIVILEGES FOR ROLE streamfusion_owner IN SCHEMA public
GRANT USAGE, SELECT, UPDATE ON SEQUENCES TO streamfusion_runtime;
SQL
result="$$(psql \
--host=stremio-postgres \
--username="$$POSTGRES_USER" \
--dbname="$$POSTGRES_DB" \
--no-psqlrc \
--tuples-only \
--no-align \
--set=ON_ERROR_STOP=1 <<'SQL'
SELECT CASE
WHEN
EXISTS (
SELECT 1
FROM pg_roles
WHERE rolname = 'streamfusion_owner'
AND NOT rolcanlogin
AND NOT rolsuper
AND rolcreatedb
AND NOT rolcreaterole
AND NOT rolinherit
AND NOT rolreplication
AND NOT rolbypassrls
)
AND EXISTS (
SELECT 1
FROM pg_roles
WHERE rolname = 'streamfusion_runtime'
AND rolcanlogin
AND NOT rolsuper
AND NOT rolcreatedb
AND NOT rolcreaterole
AND NOT rolinherit
AND NOT rolreplication
AND NOT rolbypassrls
)
AND EXISTS (
SELECT 1
FROM pg_roles
WHERE rolname = 'streamfusion_migration'
AND rolcanlogin
AND NOT rolsuper
AND NOT rolcreatedb
AND NOT rolcreaterole
AND NOT rolinherit
AND NOT rolreplication
AND NOT rolbypassrls
)
AND EXISTS (
SELECT 1
FROM pg_roles
WHERE rolname = 'streamfusion_restore'
AND rolcanlogin
AND NOT rolsuper
AND rolcreatedb
AND NOT rolcreaterole
AND NOT rolinherit
AND NOT rolreplication
AND NOT rolbypassrls
)
AND EXISTS (
SELECT 1
FROM pg_auth_members m
JOIN pg_roles parent ON parent.oid = m.roleid
JOIN pg_roles member ON member.oid = m.member
WHERE parent.rolname = 'streamfusion_owner'
AND member.rolname = 'streamfusion_migration'
AND NOT m.inherit_option
AND m.set_option
)
AND EXISTS (
SELECT 1
FROM pg_auth_members m
JOIN pg_roles parent ON parent.oid = m.roleid
JOIN pg_roles member ON member.oid = m.member
WHERE parent.rolname = 'streamfusion_owner'
AND member.rolname = 'streamfusion_restore'
AND NOT m.inherit_option
AND m.set_option
)
AND pg_has_role('streamfusion_restore', 'pg_signal_backend', 'MEMBER')
AND pg_has_role('streamfusion_restore', 'pg_signal_backend', 'USAGE')
AND (
SELECT pg_get_userbyid(datdba)
FROM pg_database
WHERE datname = 'streamfusion'
) = 'streamfusion_owner'
AND (
SELECT pg_get_userbyid(nspowner)
FROM pg_namespace
WHERE nspname = 'public'
) = 'streamfusion_owner'
AND NOT EXISTS (
SELECT 1
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'public'
AND pg_get_userbyid(c.relowner) = 'streamfusion'
AND c.relkind IN ('r', 'p', 'S', 'v', 'm', 'f')
AND NOT EXISTS (
SELECT 1
FROM pg_depend d
WHERE d.classid = 'pg_class'::regclass
AND d.objid = c.oid
AND d.deptype = 'e'
)
)
THEN 'OK'
ELSE 'ERROR'
END;
SQL
)"
test "$$result" = "OK"
echo "[postgres-security] Configuration validée"
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp:mode=1777
networks:
- proxy_network
stremio-redis:
image: redis:7-alpine
container_name: stremio-redis
expose:
- 6379
volumes:
- stremio-redis:/data
command: redis-server --appendonly yes
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 5s
retries: 10
restart: unless-stopped
networks:
- proxy_network
warp:
image: caomingjun/warp:latest
container_name: warp
restart: always
expose:
- 1080
environment:
- WARP_SLEEP=2
cap_add:
- NET_ADMIN
sysctls:
- net.ipv6.conf.all.disable_ipv6=0
- net.ipv4.conf.all.src_valid_mark=1
volumes:
- warp-data:/var/lib/cloudflare-warp
networks:
- proxy_network
taskiq-worker:
image: laster13/stream-fusion-reborn:latest
deploy:
mode: replicated
replicas: 2
command: python -m taskiq worker stream_fusion.worker:broker
# env_file: user.env # uncomment to enable unique_account mode (debrid/indexers)
environment:
SECRET_API_KEY: ${SECRET_API_KEY:?Provide SECRET_API_KEY}
CONFIG_SECRET_KEY: ${CONFIG_SECRET_KEY:?Provide CONFIG_SECRET_KEY}
SESSION_KEY: ${SESSION_KEY:?Provide SESSION_KEY}
PEER_MASTER_KEY: ${PEER_MASTER_KEY:?Provide PEER_MASTER_KEY}
TMDB_API_KEY: ${TMDB_API_KEY:?Provide TMDB_API_KEY}
MEILI_MASTER_KEY: ${MEILI_MASTER_KEY:?Provide MEILI_MASTER_KEY}
PG_USER: streamfusion_runtime
PG_PASS: ${PG_PASS:?PG_PASS is required}
PG_BASE: streamfusion
PG_RESTORE_USER: streamfusion_restore
PG_RESTORE_PASS_FILE: /run/pg-restore-secret/pg_restore_pass
PG_OWNER_ROLE: streamfusion_owner
TZ: ${TZ:-Europe/Paris}
PROXY_URL: ${PROXY_URL:-http://warp:1080}
REDIS_HOST: stremio-redis
PG_HOST: stremio-postgres
MEILI_HOST: meilisearch
MEILI_PORT: "7700"
TASKIQ_REDIS_DB: "6"
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp:mode=1777,size=4g
- /home/appuser:uid=1000,gid=1000,mode=0700
volumes:
- dmm-hashlists:/data/dmm_hashlists
- imdb-db:/data/imdb_db
- sfr-db-backups:/data/backups
- pg-restore-secret:/run/pg-restore-secret:ro
- meili-data:/meili_data:ro
- meili-restore-control:/meili_restore_control
- taskiq-logs:/app/config/logs
depends_on:
postgres-security-init:
condition: service_completed_successfully
stremio-redis:
condition: service_healthy
meilisearch:
condition: service_healthy
restart: unless-stopped
networks:
- proxy_network
taskiq-scheduler:
image: laster13/stream-fusion-reborn:latest
deploy:
mode: replicated
replicas: 1
container_name: taskiq-scheduler
command: python -m taskiq scheduler stream_fusion.tkq:scheduler
environment:
SESSION_KEY: ${SESSION_KEY:?Provide SESSION_KEY}
PG_USER: streamfusion_runtime
PG_PASS: ${PG_PASS:?PG_PASS is required}
PG_BASE: streamfusion
TZ: ${TZ:-Europe/Paris}
REDIS_HOST: stremio-redis
PG_HOST: stremio-postgres
TASKIQ_REDIS_DB: "6"
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp:mode=1777
- /home/appuser:uid=1000,gid=1000,mode=0700
volumes:
- taskiq-logs:/app/config/logs
depends_on:
postgres-security-init:
condition: service_completed_successfully
stremio-redis:
condition: service_healthy
restart: unless-stopped
networks:
- proxy_network
# IMPORTANT: replicas must always be 1
stream-fusion:
image: laster13/stream-fusion-reborn:latest
deploy:
mode: replicated
replicas: 4
# env_file: user.env # uncomment to enable unique_account mode (debrid/indexers)
environment:
RUN_MIGRATIONS: "true"
SECRET_API_KEY: ${SECRET_API_KEY:?Provide SECRET_API_KEY}
ADMIN_SECRET_KEY: ${ADMIN_SECRET_KEY:?Provide ADMIN_SECRET_KEY}
CONFIG_SECRET_KEY: ${CONFIG_SECRET_KEY:?Provide CONFIG_SECRET_KEY}
SESSION_KEY: ${SESSION_KEY:?Provide SESSION_KEY}
PEER_MASTER_KEY: ${PEER_MASTER_KEY:?Provide PEER_MASTER_KEY}
TMDB_API_KEY: ${TMDB_API_KEY:?Provide TMDB_API_KEY}
MEILI_MASTER_KEY: ${MEILI_MASTER_KEY:?Provide MEILI_MASTER_KEY}
PG_USER: streamfusion_runtime
PG_PASS: ${PG_PASS:?PG_PASS is required}
PG_BASE: streamfusion
PG_MIGRATION_USER: streamfusion_migration
PG_MIGRATION_PASS: ${PG_MIGRATION_PASS:?PG_MIGRATION_PASS is required}
PG_OWNER_ROLE: streamfusion_owner
TZ: ${TZ:-Europe/Paris}
USE_HTTPS: ${USE_HTTPS:-true}
PROXY_URL: ${PROXY_URL:-http://warp:1080}
REDIS_HOST: stremio-redis
PG_HOST: stremio-postgres
MEILI_HOST: meilisearch
MEILI_PORT: "7700"
TASKIQ_REDIS_DB: "6"
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp:mode=1777
- /home/appuser:uid=1000,gid=1000,mode=0700
expose:
- 8080
volumes:
- stream-fusion:/app/config
- taskiq-logs:/app/config/logs
- torrent-cache:/var/cache/torrents
- imdb-db:/data/imdb_db
- sfr-db-backups:/data/backups
depends_on:
postgres-security-init:
condition: service_completed_successfully
stremio-redis:
condition: service_healthy
meilisearch:
condition: service_healthy
restart: unless-stopped
networks:
- proxy_network
volumes:
stremio-postgres:
stremio-redis:
stream-fusion:
warp-data:
meili-data:
dmm-hashlists:
sfr-db-backups:
meili-restore-control:
meili-wrapper:
imdb-db:
torrent-cache:
taskiq-logs:
pg-restore-secret:
Validation¶
Démarrage¶
Puis :
Configuration attendue :