mirror of https://github.com/synctv-org/synctv
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
501 lines
16 KiB
YAML
501 lines
16 KiB
YAML
services:
|
|
postgres:
|
|
image: postgres:18
|
|
container_name: synctv-postgres-dev
|
|
environment:
|
|
POSTGRES_USER: synctv
|
|
POSTGRES_PASSWORD: synctv
|
|
POSTGRES_DB: synctv
|
|
volumes:
|
|
- postgres_dev_data:/var/lib/postgresql
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U synctv"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 10
|
|
start_period: 20s
|
|
networks:
|
|
- synctv-dev
|
|
restart: unless-stopped
|
|
|
|
redis:
|
|
image: redis:8
|
|
container_name: synctv-redis-dev
|
|
volumes:
|
|
- redis_dev_data:/data
|
|
command: redis-server --appendonly yes
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 5s
|
|
timeout: 3s
|
|
retries: 10
|
|
networks:
|
|
- synctv-dev
|
|
restart: unless-stopped
|
|
|
|
rustfs:
|
|
image: rustfs/rustfs:latest-glibc
|
|
container_name: synctv-rustfs-dev
|
|
profiles: ["storage"]
|
|
environment:
|
|
RUSTFS_ACCESS_KEY: rustfsadmin
|
|
RUSTFS_SECRET_KEY: rustfsadmin
|
|
RUSTFS_CONSOLE_ENABLE: "true"
|
|
ports:
|
|
- "127.0.0.1:9000:9000"
|
|
- "127.0.0.1:9001:9001"
|
|
volumes:
|
|
- rustfs_dev_data:/data
|
|
command: rustfs /data --address 0.0.0.0:9000 --console-address 0.0.0.0:9001
|
|
networks:
|
|
- synctv-dev
|
|
restart: unless-stopped
|
|
|
|
rustfs-init:
|
|
image: minio/mc:latest
|
|
container_name: synctv-rustfs-init-dev
|
|
profiles: ["storage"]
|
|
depends_on:
|
|
rustfs:
|
|
condition: service_started
|
|
entrypoint:
|
|
- /bin/sh
|
|
- -ec
|
|
- |
|
|
until mc alias set rustfs http://rustfs:9000 rustfsadmin rustfsadmin; do
|
|
sleep 2
|
|
done
|
|
mc mb --ignore-existing rustfs/synctv-dev
|
|
mc anonymous set download rustfs/synctv-dev
|
|
networks:
|
|
- synctv-dev
|
|
restart: "no"
|
|
|
|
openlist:
|
|
image: openlistteam/openlist:latest
|
|
container_name: synctv-openlist-dev
|
|
profiles: ["media"]
|
|
user: "0:0"
|
|
environment:
|
|
UMASK: "022"
|
|
OPENLIST_ADMIN_PASSWORD: synctv-openlist
|
|
ports:
|
|
- "127.0.0.1:5244:5244"
|
|
volumes:
|
|
- openlist_dev_data:/opt/openlist/data
|
|
- openlist_dev_media:/opt/openlist/dev-media
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1:5244/ || exit 1"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 20
|
|
start_period: 20s
|
|
networks:
|
|
- synctv-dev
|
|
restart: unless-stopped
|
|
|
|
openlist-init:
|
|
image: curlimages/curl:latest
|
|
container_name: synctv-openlist-init-dev
|
|
profiles: ["media"]
|
|
user: "0:0"
|
|
depends_on:
|
|
openlist:
|
|
condition: service_healthy
|
|
volumes:
|
|
- openlist_dev_media:/opt/openlist/dev-media
|
|
entrypoint:
|
|
- /bin/sh
|
|
- -ec
|
|
- |
|
|
mkdir -p /opt/openlist/dev-media
|
|
if [ ! -f /opt/openlist/dev-media/hello.txt ]; then
|
|
printf "hello from openlist dev media\n" > /opt/openlist/dev-media/hello.txt
|
|
fi
|
|
|
|
token="$$(curl -fsS -X POST http://openlist:5244/api/auth/login \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"username":"admin","password":"synctv-openlist"}' \
|
|
| sed -n 's/.*"token":"\([^"]*\)".*/\1/p')"
|
|
if [ -z "$$token" ]; then
|
|
printf "OpenList admin login did not return a token.\n" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if curl -fsS -H "Authorization: $$token" http://openlist:5244/api/admin/storage/list \
|
|
| grep -q '"mount_path":"/"'; then
|
|
curl -fsS -X POST -H "Authorization: $$token" http://openlist:5244/api/admin/storage/load_all
|
|
else
|
|
curl -fsS -X POST http://openlist:5244/api/admin/storage/create \
|
|
-H "Authorization: $$token" \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"driver":"Local","mount_path":"/","order":0,"remark":"SyncTV dev media","addition":"{\"root_folder_path\":\"/opt/openlist/dev-media\",\"thumbnail\":false,\"show_hidden\":true,\"mkdir_perm\":\"777\"}"}'
|
|
curl -fsS -X POST -H "Authorization: $$token" http://openlist:5244/api/admin/storage/load_all
|
|
fi
|
|
networks:
|
|
- synctv-dev
|
|
restart: "no"
|
|
|
|
nextcloud:
|
|
image: nextcloud:apache
|
|
container_name: synctv-nextcloud-dev
|
|
profiles: ["media"]
|
|
environment:
|
|
NEXTCLOUD_ADMIN_USER: synctv
|
|
NEXTCLOUD_ADMIN_PASSWORD: synctv-nextcloud
|
|
SQLITE_DATABASE: nextcloud
|
|
NEXTCLOUD_TRUSTED_DOMAINS: "localhost 127.0.0.1 nextcloud"
|
|
ports:
|
|
- "127.0.0.1:8082:80"
|
|
volumes:
|
|
- nextcloud_dev_data:/var/www/html
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "curl -fsS http://127.0.0.1/status.php | grep -q 'installed'"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 30
|
|
start_period: 40s
|
|
networks:
|
|
- synctv-dev
|
|
restart: unless-stopped
|
|
|
|
nextcloud-init:
|
|
image: curlimages/curl:latest
|
|
container_name: synctv-nextcloud-init-dev
|
|
profiles: ["media"]
|
|
depends_on:
|
|
nextcloud:
|
|
condition: service_healthy
|
|
entrypoint:
|
|
- /bin/sh
|
|
- -ec
|
|
- |
|
|
endpoint=http://nextcloud
|
|
auth='synctv:synctv-nextcloud'
|
|
for path in /Movies /Movies/Nested /Playlists; do
|
|
curl -fsS -u "$$auth" -X MKCOL "$$endpoint/remote.php/dav/files/synctv$$path" || true
|
|
done
|
|
printf 'SyncTV Nextcloud development fixture\n' | curl -fsS -u "$$auth" -T - "$$endpoint/remote.php/dav/files/synctv/README.txt"
|
|
curl -fsS -u "$$auth" -X PROPPATCH \
|
|
-H 'Content-Type: application/xml; charset=utf-8' \
|
|
--data-binary '<propertyupdate xmlns="DAV:" xmlns:oc="http://owncloud.org/ns"><set><prop><oc:favorite>1</oc:favorite></prop></set></propertyupdate>' \
|
|
"$$endpoint/remote.php/dav/files/synctv/README.txt" || true
|
|
networks:
|
|
- synctv-dev
|
|
restart: "no"
|
|
|
|
seafile-db:
|
|
image: mariadb:10.11
|
|
container_name: synctv-seafile-db-dev
|
|
profiles: ["media"]
|
|
environment:
|
|
MARIADB_ROOT_PASSWORD: seafile-db-root
|
|
MARIADB_LOG_CONSOLE: "true"
|
|
MARIADB_AUTO_UPGRADE: "1"
|
|
volumes:
|
|
- seafile_dev_mysql:/var/lib/mysql
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "healthcheck.sh --connect --innodb_initialized"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 30
|
|
start_period: 30s
|
|
networks:
|
|
- synctv-dev
|
|
restart: unless-stopped
|
|
|
|
seafile-memcached:
|
|
image: memcached:1.6-alpine
|
|
container_name: synctv-seafile-memcached-dev
|
|
profiles: ["media"]
|
|
command: memcached -m 128
|
|
networks:
|
|
- synctv-dev
|
|
restart: unless-stopped
|
|
|
|
seafile:
|
|
image: seafileltd/seafile-mc:12.0-latest
|
|
container_name: synctv-seafile-dev
|
|
profiles: ["media"]
|
|
depends_on:
|
|
seafile-db:
|
|
condition: service_healthy
|
|
seafile-memcached:
|
|
condition: service_started
|
|
environment:
|
|
DB_HOST: seafile-db
|
|
DB_ROOT_PASSWD: seafile-db-root
|
|
TIME_ZONE: Asia/Shanghai
|
|
SEAFILE_SERVER_HOSTNAME: 127.0.0.1:8083
|
|
SEAFILE_SERVER_PROTOCOL: http
|
|
INIT_SEAFILE_ADMIN_EMAIL: synctv@example.com
|
|
INIT_SEAFILE_ADMIN_PASSWORD: synctv-seafile
|
|
JWT_PRIVATE_KEY: synctv-dev-seafile-jwt-private-key-2026
|
|
SEAFILE_LOG_TO_STDOUT: "true"
|
|
CACHE_PROVIDER: memcached
|
|
MEMCACHED_HOST: seafile-memcached
|
|
ports:
|
|
- "127.0.0.1:8083:80"
|
|
volumes:
|
|
- seafile_dev_data:/shared
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "curl -fsS http://127.0.0.1/api2/server-info/ | grep -q 'version'"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 60
|
|
start_period: 90s
|
|
networks:
|
|
- synctv-dev
|
|
restart: unless-stopped
|
|
|
|
seafile-init:
|
|
image: curlimages/curl:latest
|
|
container_name: synctv-seafile-init-dev
|
|
profiles: ["media"]
|
|
depends_on:
|
|
seafile:
|
|
condition: service_healthy
|
|
entrypoint:
|
|
- /bin/sh
|
|
- -ec
|
|
- |
|
|
endpoint=http://seafile
|
|
token="$$(curl -fsS -X POST "$$endpoint/api2/auth-token/" \
|
|
-d 'username=synctv@example.com' -d 'password=synctv-seafile' \
|
|
| sed -n 's/.*"token":"\([^"]*\)".*/\1/p')"
|
|
[ -n "$$token" ]
|
|
repos="$$(curl -fsS -H "Authorization: Token $$token" "$$endpoint/api2/repos/")"
|
|
if ! printf '%s' "$$repos" | grep -q 'SyncTV Dev Library'; then
|
|
curl -fsS -X POST -H "Authorization: Token $$token" \
|
|
-d 'name=SyncTV Dev Library' -d 'desc=SyncTV development media fixture' \
|
|
"$$endpoint/api2/repos/" >/dev/null
|
|
fi
|
|
networks:
|
|
- synctv-dev
|
|
restart: "no"
|
|
|
|
emby-init:
|
|
image: curlimages/curl:latest
|
|
container_name: synctv-emby-init-dev
|
|
profiles: ["media"]
|
|
depends_on:
|
|
emby:
|
|
condition: service_healthy
|
|
entrypoint:
|
|
- /bin/sh
|
|
- -ec
|
|
- |
|
|
emby=http://emby:8096
|
|
auth_header='X-Emby-Authorization: MediaBrowser Client="SyncTVDev", Device="curl", DeviceId="synctv-dev-emby", Version="1"'
|
|
|
|
until curl -fsS "$$emby/System/Info/Public" >/dev/null; do
|
|
sleep 2
|
|
done
|
|
|
|
user="$$(curl -fsS "$$emby/Startup/User" | sed -n 's/.*"Name":"\([^"]*\)".*/\1/p')"
|
|
if [ -z "$$user" ]; then
|
|
user=MyEmbyUser
|
|
fi
|
|
|
|
auth="$$(curl -fsS -X POST "$$emby/Users/AuthenticateByName" \
|
|
-H 'Content-Type: application/json' \
|
|
-H "$$auth_header" \
|
|
-d "{\"Username\":\"$$user\",\"Pw\":\"\"}" || true)"
|
|
if ! printf '%s' "$$auth" | grep -q '"AccessToken"'; then
|
|
auth="$$(curl -fsS -X POST "$$emby/Users/AuthenticateByName" \
|
|
-H 'Content-Type: application/json' \
|
|
-H "$$auth_header" \
|
|
-d "{\"Username\":\"$$user\",\"Pw\":\"synctv-emby\"}")"
|
|
fi
|
|
|
|
token="$$(printf '%s' "$$auth" | sed -n 's/.*"AccessToken":"\([^"]*\)".*/\1/p')"
|
|
user_id="$$(printf '%s' "$$auth" | sed -n 's/.*"User":{[^}]*"Id":"\([^"]*\)".*/\1/p')"
|
|
if [ -z "$$token" ] || [ -z "$$user_id" ]; then
|
|
printf "Emby login did not return token and user id.\n" >&2
|
|
exit 1
|
|
fi
|
|
|
|
curl -fsS -X POST "$$emby/Users/$$user_id/Password" \
|
|
-H "X-Emby-Token: $$token" \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"NewPw":"synctv-emby"}' >/dev/null
|
|
|
|
if ! curl -fsS "$$emby/Library/VirtualFolders" -H "X-Emby-Token: $$token" \
|
|
| grep -q '"Name":"SyncTV Dev Media"'; then
|
|
curl -fsS -X POST "$$emby/Library/VirtualFolders" \
|
|
-H "X-Emby-Token: $$token" \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"Name":"SyncTV Dev Media","CollectionType":"homevideos","RefreshLibrary":true,"LibraryOptions":{"ContentType":"homevideos","PathInfos":[{"Path":"/mnt/share1"}],"EnablePhotos":false,"EnableRealtimeMonitor":false,"SampleIgnoreSize":0}}' >/dev/null
|
|
fi
|
|
|
|
curl -fsS -X POST "$$emby/Library/Refresh" -H "X-Emby-Token: $$token" >/dev/null
|
|
networks:
|
|
- synctv-dev
|
|
restart: "no"
|
|
|
|
emby:
|
|
image: emby/embyserver:latest
|
|
container_name: synctv-emby-dev
|
|
profiles: ["media"]
|
|
environment:
|
|
UID: "1000"
|
|
GID: "1000"
|
|
GIDLIST: "1000"
|
|
ports:
|
|
- "127.0.0.1:8096:8096"
|
|
- "127.0.0.1:8920:8920"
|
|
volumes:
|
|
- emby_dev_config:/config
|
|
- emby_dev_media:/mnt/share1
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1:8096/System/Info/Public || exit 1"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 30
|
|
start_period: 40s
|
|
networks:
|
|
- synctv-dev
|
|
restart: unless-stopped
|
|
|
|
jellyfin:
|
|
image: jellyfin/jellyfin:latest
|
|
container_name: synctv-jellyfin-dev
|
|
profiles: ["media"]
|
|
ports:
|
|
- "127.0.0.1:8097:8096"
|
|
volumes:
|
|
- jellyfin_dev_config:/config
|
|
- jellyfin_dev_cache:/cache
|
|
- jellyfin_dev_media:/media
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:8096/System/Info/Public >/dev/null || exit 1"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 30
|
|
start_period: 40s
|
|
networks:
|
|
- synctv-dev
|
|
restart: unless-stopped
|
|
|
|
jellyfin-init:
|
|
image: curlimages/curl:latest
|
|
container_name: synctv-jellyfin-init-dev
|
|
profiles: ["media"]
|
|
depends_on:
|
|
jellyfin:
|
|
condition: service_healthy
|
|
entrypoint:
|
|
- /bin/sh
|
|
- -ec
|
|
- |
|
|
jellyfin=http://jellyfin:8096
|
|
auth_header='Authorization: MediaBrowser Client="SyncTVDev", Device="curl", DeviceId="synctv-dev-jellyfin", Version="1"'
|
|
|
|
until curl -fsS "$$jellyfin/System/Info/Public" >/dev/null; do
|
|
sleep 2
|
|
done
|
|
|
|
curl -fsS -X POST "$$jellyfin/Startup/Configuration" \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"ServerName":"SyncTV Jellyfin Dev","UICulture":"en-US","MetadataCountryCode":"US","PreferredMetadataLanguage":"en"}' >/dev/null || true
|
|
curl -fsS -X POST "$$jellyfin/Startup/RemoteAccess" \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"EnableRemoteAccess":true,"EnableAutomaticPortMapping":false}' >/dev/null || true
|
|
|
|
user="$$(curl -fsS "$$jellyfin/Startup/FirstUser" | sed -n 's/.*"Name":"\([^"]*\)".*/\1/p')"
|
|
if [ -z "$$user" ]; then
|
|
user=root
|
|
fi
|
|
|
|
auth="$$(curl -fsS -X POST "$$jellyfin/Users/AuthenticateByName" \
|
|
-H 'Content-Type: application/json' \
|
|
-H "$$auth_header" \
|
|
-d "{\"Username\":\"$$user\",\"Pw\":\"\"}" || true)"
|
|
if ! printf '%s' "$$auth" | grep -q '"AccessToken"'; then
|
|
auth="$$(curl -fsS -X POST "$$jellyfin/Users/AuthenticateByName" \
|
|
-H 'Content-Type: application/json' \
|
|
-H "$$auth_header" \
|
|
-d "{\"Username\":\"$$user\",\"Pw\":\"synctv-jellyfin\"}")"
|
|
fi
|
|
|
|
token="$$(printf '%s' "$$auth" | sed -n 's/.*"AccessToken":"\([^"]*\)".*/\1/p')"
|
|
user_id="$$(printf '%s' "$$auth" | sed -n 's/.*"User":{[^}]*"Id":"\([^"]*\)".*/\1/p')"
|
|
if [ -z "$$token" ] || [ -z "$$user_id" ]; then
|
|
printf "Jellyfin login did not return token and user id.\n" >&2
|
|
exit 1
|
|
fi
|
|
|
|
curl -fsS -X POST "$$jellyfin/Users/Password?userId=$$user_id" \
|
|
-H "X-Emby-Token: $$token" \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"CurrentPw":"","NewPw":"synctv-jellyfin"}' >/dev/null || true
|
|
curl -fsS -X POST "$$jellyfin/Startup/Complete" >/dev/null || true
|
|
|
|
if ! curl -fsS "$$jellyfin/Library/VirtualFolders" -H "X-Emby-Token: $$token" \
|
|
| grep -q '"Name":"SyncTV Dev Media"'; then
|
|
curl -fsS -X POST "$$jellyfin/Library/VirtualFolders?name=SyncTV%20Dev%20Media&collectionType=homevideos&paths=/media&refreshLibrary=true" \
|
|
-H "X-Emby-Token: $$token" \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"LibraryOptions":{"EnablePhotos":false,"EnableRealtimeMonitor":false}}' >/dev/null
|
|
fi
|
|
|
|
curl -fsS -X POST "$$jellyfin/Library/Refresh" -H "X-Emby-Token: $$token" >/dev/null
|
|
networks:
|
|
- synctv-dev
|
|
restart: "no"
|
|
|
|
casdoor:
|
|
image: casbin/casdoor:latest
|
|
container_name: synctv-casdoor-dev
|
|
profiles: ["auth"]
|
|
environment:
|
|
driverName: postgres
|
|
dataSourceName: "user=synctv password=synctv host=postgres port=5432 sslmode=disable dbname=casdoor"
|
|
runmode: dev
|
|
ports:
|
|
- "127.0.0.1:8000:8000"
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1:8000/ || exit 1"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 30
|
|
start_period: 30s
|
|
networks:
|
|
- synctv-dev
|
|
restart: unless-stopped
|
|
|
|
volumes:
|
|
postgres_dev_data:
|
|
driver: local
|
|
redis_dev_data:
|
|
driver: local
|
|
rustfs_dev_data:
|
|
driver: local
|
|
openlist_dev_data:
|
|
driver: local
|
|
openlist_dev_media:
|
|
driver: local
|
|
nextcloud_dev_data:
|
|
driver: local
|
|
seafile_dev_mysql:
|
|
driver: local
|
|
seafile_dev_data:
|
|
driver: local
|
|
emby_dev_config:
|
|
driver: local
|
|
emby_dev_media:
|
|
driver: local
|
|
jellyfin_dev_config:
|
|
driver: local
|
|
jellyfin_dev_cache:
|
|
driver: local
|
|
jellyfin_dev_media:
|
|
driver: local
|
|
|
|
networks:
|
|
synctv-dev:
|
|
driver: bridge
|