From e2060a70ec6dd690bae7da6a70c418553c1a9f4d Mon Sep 17 00:00:00 2001 From: John Date: Tue, 11 Nov 2025 01:25:04 +0000 Subject: [PATCH] unraid to swarm migration --- stacks/apps/peertube/README.md | 171 +++++++++++++++++++++++++++++++ stacks/apps/peertube/stack.yml | 90 ++++++++++++++++ stacks/core/postgres/stack.yml | 27 +++++ stacks/media/emby/stack.yml | 26 +++++ stacks/media/notifiarr/stack.yml | 21 ++++ stacks/media/prowlarr/stack.yml | 25 +++++ stacks/media/radarr/stack.yml | 26 +++++ stacks/media/sabNZB/stack.yml | 26 +++++ stacks/media/sonarr/stack.yml | 20 ++++ 9 files changed, 432 insertions(+) create mode 100644 stacks/apps/peertube/README.md create mode 100644 stacks/apps/peertube/stack.yml create mode 100644 stacks/core/postgres/stack.yml create mode 100644 stacks/media/emby/stack.yml create mode 100644 stacks/media/notifiarr/stack.yml create mode 100644 stacks/media/prowlarr/stack.yml create mode 100644 stacks/media/radarr/stack.yml create mode 100644 stacks/media/sabNZB/stack.yml create mode 100644 stacks/media/sonarr/stack.yml diff --git a/stacks/apps/peertube/README.md b/stacks/apps/peertube/README.md new file mode 100644 index 0000000..c704616 --- /dev/null +++ b/stacks/apps/peertube/README.md @@ -0,0 +1,171 @@ +# PeerTube Docker Swarm Setup + +## Prerequisites + +1. Traefik is running and configured +2. PostgreSQL is running (`postgresSQL` service) +3. The `homelab` network exists +4. DNS record for `videos.frostlabs.me` points to your server + +## Setup Steps + +### 1. Create PeerTube Database + +Connect to your existing PostgreSQL instance and create the PeerTube database: + +```bash +# Connect to PostgreSQL container +docker exec -it $(docker ps -q -f name=postgresSQL) psql -U admin -d postgres + +# Create database (user 'admin' already exists with postgres-master secret) +CREATE DATABASE peertube; +GRANT ALL PRIVILEGES ON DATABASE peertube TO admin; +\q +``` + +### 2. Create Docker Secret for PeerTube + +You already have the `postgres-master` secret for database access. You just need to create the PeerTube application secret: + +```bash +# Generate and create the PeerTube secret +echo "$(openssl rand -hex 32)" | docker secret create peertube-secret - + +# Verify the secret was created +docker secret ls | grep peertube +``` + +**Note:** The stack uses your existing `postgres-master` secret for database authentication with the `admin` user. + +### 3. Verify Data Directory Permissions + +```bash +# Check that the PeerTube appdata directory exists and has correct permissions +ls -la /home/doc/projects/unraid-appdata/PeerTube + +# If needed, fix permissions (UID 999 is the PeerTube user) +sudo chown -R 999:999 /home/doc/projects/unraid-appdata/PeerTube +``` + +### 4. Deploy the Stack + +```bash +docker stack deploy -c stack.yml peertube +``` + +### 5. Monitor Deployment + +```bash +# Watch the services +docker service ls | grep peertube + +# Check logs +docker service logs -f peertube_peertube + +# Check if healthy +docker ps | grep peertube +``` + +### 6. Access PeerTube + +Once deployed, access PeerTube at: https://videos.frostlabs.me + +The first time you access it, you'll need to: +1. Complete the setup wizard +2. Create an admin account +3. Configure additional settings in the admin panel + +## Configuration Notes + +### Database Connection +- Host: `postgresSQL` (existing Postgres service) +- Port: 5432 (internal) +- Database: `peertube` +- User: `admin` +- Password: From `postgres-master` secret + +### Redis Connection +- Host: `peertube-redis` (internal service) +- Port: 6379 (default) + +### SMTP/Email +- Host: `peertube-postfix` (internal service) +- Port: 25 +- From: noreply@videos.frostlabs.me + +### Ports +- **9000**: PeerTube HTTP (internal, proxied by Traefik) +- **1935**: RTMP for live streaming (published on host) + +### Traefik Integration +The stack is configured to use Traefik for: +- SSL/TLS certificates (Let's Encrypt) +- HTTPS on port 443 +- HTTP to HTTPS redirect +- Domain: videos.frostlabs.me + +## Storage Layout + +All data is stored in `/home/doc/projects/unraid-appdata/PeerTube`: +- Videos and media files +- Thumbnails and previews +- User uploads +- Logs +- Configuration + +## Troubleshooting + +### Check service status +```bash +docker service ps peertube_peertube --no-trunc +``` + +### View logs +```bash +docker service logs peertube_peertube +docker service logs peertube_peertube-redis +docker service logs peertube_peertube-postfix +``` + +### Database connection issues +```bash +# Test connection from PeerTube container +docker exec -it $(docker ps -q -f name=peertube_peertube) sh +nc -zv postgresSQL 5432 +``` + +### Restart services +```bash +docker service update --force peertube_peertube +``` + +### Remove and redeploy +```bash +docker stack rm peertube +# Wait for cleanup +docker stack deploy -c stack.yml peertube +``` + +## Updating PeerTube + +```bash +# Update the image +docker service update --image chocobozzz/peertube:production-bookworm peertube_peertube + +# Or redeploy the stack +docker stack deploy -c stack.yml peertube +``` + +## Security Considerations + +1. Change the default admin password after first login +2. Keep PEERTUBE_SECRET secure and never commit it to version control +3. Regularly update the PeerTube image for security patches +4. Configure proper email settings for notifications +5. Review and configure user registration settings in admin panel + +## Additional Resources + +- [PeerTube Documentation](https://docs.joinpeertube.org/) +- [PeerTube Production Guide](https://docs.joinpeertube.org/install/docker) +- [PeerTube Admin Documentation](https://docs.joinpeertube.org/admin/following-instances) diff --git a/stacks/apps/peertube/stack.yml b/stacks/apps/peertube/stack.yml new file mode 100644 index 0000000..e337130 --- /dev/null +++ b/stacks/apps/peertube/stack.yml @@ -0,0 +1,90 @@ +services: + peertube: + image: chocobozzz/peertube:production-bookworm + networks: + - homelab + environment: + # Database configuration - connecting to existing Postgres + - POSTGRES_USER=admin + - POSTGRES_PASSWORD_FILE=/run/secrets/postgres-master + - POSTGRES_DB=peertube + - POSTGRES_HOSTNAME=postgresSQL + # Redis configuration + - REDIS_HOSTNAME=peertube-redis + # PeerTube configuration + - PEERTUBE_WEBSERVER_HOSTNAME=videos.frostlabs.me + - PEERTUBE_WEBSERVER_PORT=443 + - PEERTUBE_WEBSERVER_HTTPS=true + - PEERTUBE_TRUST_PROXY=["127.0.0.1", "loopback", "172.18.0.0/16"] + # SMTP configuration - Gmail + - PEERTUBE_SMTP_HOSTNAME=smtp.gmail.com + - PEERTUBE_SMTP_PORT=587 + - PEERTUBE_SMTP_USERNAME=frostlabs25@gmail.com + - PEERTUBE_SMTP_PASSWORD_FILE=/run/secrets/gmail-app-password + - PEERTUBE_SMTP_FROM=frostlabs25@gmail.com + - PEERTUBE_SMTP_TLS=true + - PEERTUBE_ADMIN_EMAIL=frostlabs25@gmail.com + # Secrets - loaded from Docker secrets as files + - PEERTUBE_DB_SUFFIX=_prod + - PEERTUBE_SECRET_FILE=/run/secrets/peertube-key + secrets: + - postgres-master + - peertube-key + - gmail-app-password + ports: + - target: 9000 + published: 9000 + mode: host + - target: 1935 + published: 1935 + mode: host + volumes: + - /home/doc/projects/unraid-appdata/PeerTube:/data + - /home/doc/projects/unraid-appdata/PeerTube:/config + healthcheck: + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:9000/api/v1/config"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + deploy: + mode: replicated + replicas: 1 + labels: + - traefik.enable=true + - traefik.http.routers.peertube.rule=Host(`videos.frostlabs.me`) + - traefik.http.routers.peertube.entrypoints=websecure + - traefik.http.routers.peertube.tls=true + - traefik.http.routers.peertube.tls.certresolver=cloudflare + - traefik.http.services.peertube.loadbalancer.server.port=9000 + + peertube-redis: + image: redis:7-alpine + networks: + - homelab + volumes: + - peertube-redis-data:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 30s + timeout: 5s + retries: 3 + deploy: + mode: replicated + replicas: 1 + + +networks: + homelab: + external: true + +volumes: + peertube-redis-data: + +secrets: + postgres-master: + external: true + peertube-key: + external: true + gmail-app-password: + external: true diff --git a/stacks/core/postgres/stack.yml b/stacks/core/postgres/stack.yml new file mode 100644 index 0000000..5b9af6c --- /dev/null +++ b/stacks/core/postgres/stack.yml @@ -0,0 +1,27 @@ +services: + postgresSQL: + image: postgres:17-alpine + networks: + - homelab + environment: + - POSTGRES_USER=admin + - POSTGRES_PASSWORD=AllOfTheStars+1 + - PGDATA=/var/lib/postgresql/data + volumes: + - /home/doc/projects/unraid-appdata/postgres:/var/lib/postgresql/data + ports: + - target: 5432 + published: 5434 + mode: host + healthcheck: + test: [ "CMD-SHELL", "pg_isready -U admin -d postgres" ] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + deploy: + replicas: 1 + +networks: + homelab: + external: true diff --git a/stacks/media/emby/stack.yml b/stacks/media/emby/stack.yml new file mode 100644 index 0000000..8be4d86 --- /dev/null +++ b/stacks/media/emby/stack.yml @@ -0,0 +1,26 @@ +services: + emby: + image: lscr.io/linuxserver/emby:latest + networks: + - homelab + environment: + - PUID=1000 + - PGID=1000 + - TZ=Etc/UTC + volumes: + - /home/doc/projects/unraid-appdata/emby:/config + - /home/doc/projects/data/media/tv:/data/tvshows + - /home/doc/projects/data/media/movies:/data/movies + ports: + - 8096:8096 + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:8096/web/index.html" ] + interval: 30s + timeout: 10s + retries: 5 + start_period: 120s + deploy: + replicas: 1 +networks: + homelab: + external: true diff --git a/stacks/media/notifiarr/stack.yml b/stacks/media/notifiarr/stack.yml new file mode 100644 index 0000000..de7dfe5 --- /dev/null +++ b/stacks/media/notifiarr/stack.yml @@ -0,0 +1,21 @@ +services: + notifiarr: + image: golift/notifiarr:latest + hostname: notifiarr + networks: + - homelab + ports: + - "5454:5454" + volumes: + - /home/doc/projects/unraid-appdata/Notifiarr:/config + - /var/run/docker.sock:/var/run/docker.sock:ro + environment: + - TZ=America/New_York + - PUID=1000 + - PGID=1000 + deploy: + replicas: 1 + +networks: + homelab: + external: true diff --git a/stacks/media/prowlarr/stack.yml b/stacks/media/prowlarr/stack.yml new file mode 100644 index 0000000..2060836 --- /dev/null +++ b/stacks/media/prowlarr/stack.yml @@ -0,0 +1,25 @@ +services: + prowlarr: + image: lscr.io/linuxserver/prowlarr:latest + networks: + - homelab + ports: + - 9696:9696 + environment: + - PUID=1000 + - PGID=1000 + - TZ=Etc/UTC + volumes: + - /home/doc/projects/unraid-appdata/postgres:/config + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:9696/ping" ] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + deploy: + replicas: 1 + +networks: + homelab: + external: true diff --git a/stacks/media/radarr/stack.yml b/stacks/media/radarr/stack.yml new file mode 100644 index 0000000..a4607fe --- /dev/null +++ b/stacks/media/radarr/stack.yml @@ -0,0 +1,26 @@ +services: + radarr: + image: lscr.io/linuxserver/radarr:latest + networks: + - homelab + ports: + - 7878:7878 + environment: + - PUID=1000 + - PGID=1000 + - TZ=Etc/UTC + volumes: + - /home/doc/projects/unraid-appdata/radarr:/config + - /home/doc/projects/data:/data + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:7878/ping" ] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + deploy: + replicas: 1 + +networks: + homelab: + external: true diff --git a/stacks/media/sabNZB/stack.yml b/stacks/media/sabNZB/stack.yml new file mode 100644 index 0000000..86ce306 --- /dev/null +++ b/stacks/media/sabNZB/stack.yml @@ -0,0 +1,26 @@ +services: + sabnzbd: + image: lscr.io/linuxserver/sabnzbd:latest + networks: + - homelab + ports: + - 8080:8080 + environment: + - PUID=1000 + - PGID=1000 + - TZ=Etc/UTC + volumes: + - /home/doc/projects/unraid-appdata/sabnzbd:/config + - /home/doc/projects/data/usenet:/data/usenet + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:8080/api?mode=version" ] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + deploy: + replicas: 1 + +networks: + homelab: + external: true diff --git a/stacks/media/sonarr/stack.yml b/stacks/media/sonarr/stack.yml new file mode 100644 index 0000000..ed9a479 --- /dev/null +++ b/stacks/media/sonarr/stack.yml @@ -0,0 +1,20 @@ +services: + sonarr: + image: lscr.io/linuxserver/sonarr:latest + networks: + - homelab + ports: + - 8989:8989 + environment: + - PUID=1000 + - PGID=1000 + - TZ=Etc/UTC + volumes: + - /mnt/swarm-data/sonarr:/config + - /home/doc/projects/data:/data + deploy: + replicas: 1 + +networks: + homelab: + external: true