Compare commits

...

18 Commits

Author SHA1 Message Date
3a2d9fe969 Updates README.md with status score 2026-01-20 18:16:50 +00:00
bcebdcad31 Add healthcheck, backup support, and improved documentation
- Enable healthcheck using Jellyfin's /health endpoint
- Add compose.backup.yml for automated backups via offen/docker-volume-backup
- Support S3-compatible and SSH/SFTP backup storage
- Remove deprecated version attribute from compose files
- Expand .env.sample with backup configuration options
- Rewrite README with backup docs, hardware transcoding guide, and troubleshooting
2026-01-17 20:01:29 -05:00
24bb1e7ab7 publish 0.5.0+10.11.1 release (#4)
## Overview

Bumps to [latest Jellyfin release v10.11.1](https://github.com/jellyfin/jellyfin/releases/tag/v10.11.1)

I have tested this on my own Abra deployment of Jellyfin 

## Description

I would love to implement a health-check as well, but for now I want to familiarise myself with the process of releasing recipe updates 💯
So if someone can tell me what else this PR is missing to get this moving, that'd be amazing ^_^

Co-authored-by: Andrew Salib <andrew.salib@kasada.io>
Reviewed-on: coop-cloud/jellyfin#4
Reviewed-by: decentral1se <decentral1se@noreply.git.coopcloud.tech>
2025-11-04 23:39:47 +00:00
3wc
9105f0b391 chore: publish 0.4.2+10.10.5 release 2025-01-25 15:23:40 -05:00
df32c88a72 Update .drone.yml 2025-01-08 10:09:13 -08:00
e0b3e9136d add readme section for sonarr and radarr 2024-12-02 12:43:39 -08:00
bd20fed151 sonarr and radarr support 2024-12-02 00:37:42 -08:00
3wc
c1fb6404db chore: publish 0.4.1+10.10.1 release 2024-11-16 09:51:13 -05:00
93a02d6dd0 chore: publish 0.4.0+10.10.0 release 2024-10-30 12:50:42 +05:00
3wc
86db4b372f chore: publish 0.3.1+10.9.11 release 2024-09-25 13:50:07 -04:00
54db60a580 chore: publish 0.3.0+10.9.10 release 2024-08-29 14:05:29 +05:00
8e43ac01bd update coop cloud stack version (again) 2024-08-29 14:02:43 +05:00
4eaac169f9 update coop cloud stack version 2024-08-29 08:58:26 +00:00
4c4394810f update to jellyfin 10.9.10 2024-08-29 08:55:28 +00:00
3wc
5c7ecdad59 chore: publish 0.2.0+10.9.2 release 2024-05-23 15:27:49 -03:00
3wc
114a006554 chore: publish 0.1.9+10.8.13 release 2023-12-02 12:24:45 -03:00
3wc
abbff8382e chore: publish 0.1.8+10.8.12 release 2023-11-09 19:07:02 +00:00
3wc
0877020dd7 chore: publish 0.1.7+10.8.11 release 2023-10-23 13:49:16 +01:00
7 changed files with 259 additions and 55 deletions

View File

@ -33,7 +33,7 @@ steps:
from_secret: drone_abra-bot_token
fork: true
repositories:
- coop-cloud/auto-recipes-catalogue-json
- toolshed/auto-recipes-catalogue-json
trigger:
event: tag

View File

@ -1,11 +1,51 @@
TYPE=jellyfin
# Jellyfin Co-op Cloud Recipe Configuration
# ==========================================
# Required Settings
TYPE=jellyfin
DOMAIN=jellyfin.example.com
## Domain aliases
#EXTRA_DOMAINS=', `www.jellyfin.example.com`'
# Compose Files
# Add compose.backup.yml for automated backups
# Add compose.media_volumes.yml for Sonarr/Radarr integration
COMPOSE_FILE="compose.yml"
# Optional: Additional domains (uncomment to enable)
# EXTRA_DOMAINS=|| Host(`www.jellyfin.example.com`)
# Let's Encrypt environment (staging or production)
LETS_ENCRYPT_ENV=production
# Set to an existing path on the host, and define a path inside the container
# Media Volume Configuration
# ==========================
# Mount a local folder containing your media files
# Example: /mnt/media/movies:/media
EXTRA_VOLUME=/dev/null:/tmp/.dummy
# Sonarr/Radarr Integration (use with compose.media_volumes.yml)
# Uncomment these when using the media volumes overlay
# movies_volume=radarr_media
# shows_volume=sonarr_media
# Backup Configuration (use with compose.backup.yml)
# ==================================================
# Backup schedule (cron expression, default: 2 AM daily)
# BACKUP_CRON=0 2 * * *
# Number of days to retain backups
# BACKUP_RETENTION_DAYS=7
# Local backup storage path
# BACKUP_LOCAL_PATH=/path/to/backups
# S3-compatible storage (optional)
# AWS_S3_BUCKET_NAME=your-bucket
# AWS_ACCESS_KEY_ID=your-key-id
# AWS_SECRET_ACCESS_KEY=your-secret
# AWS_S3_PATH=jellyfin
# AWS_ENDPOINT=https://s3.example.com
# SSH/SFTP storage (optional)
# SSH_HOST_NAME=backup.example.com
# SSH_USER=backup
# SSH_REMOTE_PATH=/backups/jellyfin

6
.gitignore vendored
View File

@ -1 +1,5 @@
.envrc
.env
.abra/
*.swp
*.swo
*~

157
README.md
View File

@ -1,35 +1,140 @@
# jellyfin
# Jellyfin
> One line description of the recipe
> The Free Software Media System
<!-- metadata -->
| Property | Value |
| --- | --- |
| **Category** | Apps |
| **Status** | 3, Beta |
| **Image** | [`jellyfin/jellyfin`](https://hub.docker.com/r/jellyfin/jellyfin) |
| **Healthcheck** | Yes |
| **Backups** | Yes |
* **Category**: Apps
* **Status**: 1, alpha
* **Image**: [`jellyfin//jellyfin`](https://hub.docker.com/r/jellyfin/jellyfin), 4, upstream
* **Healthcheck**: No
* **Backups**: No
* **Email**: No
* **Tests**: No
* **SSO**: No
Jellyfin is a free and open-source media server that lets you collect, manage, and stream your media. This recipe deploys Jellyfin with Traefik integration, health monitoring, and optional automated backups.
<!-- endmetadata -->
## Quick Start
## Quick start
```bash
# Create a new Jellyfin instance
abra app new jellyfin --secrets
* `abra app new jellyfin --secrets`
* `abra app config <app-name>`
* `abra app deploy <app-name>`
# Configure your instance
abra app config <app-name>
For more, see [`docs.coopcloud.tech`](https://docs.coopcloud.tech).
## Adding Media
You can mount a folder of your choice to jellyfin by editing this line after running `abra app config ${your jelllyfin url}`
```
EXTRA_VOLUME=/home/$USER/media:/media/ # replace /home/$USER/media with folder of your choice
# Deploy
abra app deploy <app-name>
```
Then during the jellyfin setup wizard use this folder as the path for your jellyfin library.
## Configuration
### Media Volumes
Configure media access by editing `EXTRA_VOLUME` in your app configuration:
```bash
# Single media folder
EXTRA_VOLUME=/mnt/media:/media
# Multiple folders (use docker-compose syntax)
EXTRA_VOLUME=/mnt/movies:/movies
```
During Jellyfin's initial setup wizard, add your mounted paths as media libraries.
### Backup Configuration
To enable automated backups, add `compose.backup.yml` to your `COMPOSE_FILE`:
```bash
COMPOSE_FILE="compose.yml:compose.backup.yml"
```
Configure backup storage in your environment:
| Variable | Description | Default |
| --- | --- | --- |
| `BACKUP_CRON` | Backup schedule (cron) | `0 2 * * *` (2 AM daily) |
| `BACKUP_RETENTION_DAYS` | Days to keep backups | `7` |
| `BACKUP_LOCAL_PATH` | Local backup directory | `/tmp/jellyfin-backups` |
#### S3-Compatible Storage
```bash
AWS_S3_BUCKET_NAME=your-bucket
AWS_ACCESS_KEY_ID=your-key-id
AWS_SECRET_ACCESS_KEY=your-secret
AWS_S3_PATH=jellyfin
AWS_ENDPOINT=https://s3.example.com # For non-AWS S3
```
#### SSH/SFTP Storage
```bash
SSH_HOST_NAME=backup.example.com
SSH_USER=backup
SSH_REMOTE_PATH=/backups/jellyfin
```
## Integration with Media Stack
Jellyfin works well with the *arr stack for automated media management:
| Service | Purpose |
| --- | --- |
| [qBittorrent](https://git.coopcloud.tech/coop-cloud/qbittorrent) | Torrent client for downloads |
| [Prowlarr](https://git.coopcloud.tech/coop-cloud/prowlarr) | Indexer manager for all *arr apps |
| [Sonarr](https://git.coopcloud.tech/coop-cloud/sonarr) | TV show monitoring and download |
| [Radarr](https://git.coopcloud.tech/coop-cloud/radarr) | Movie monitoring and download |
| [Jellyseerr](https://git.coopcloud.tech/coop-cloud/jellyseerr) | Request management and discovery UI |
### Shared Media Volumes
When integrating with Sonarr/Radarr, use `compose.media_volumes.yml` to share their media volumes:
```bash
COMPOSE_FILE="compose.yml:compose.media_volumes.yml"
movies_volume=radarr_media
shows_volume=sonarr_media
```
This mounts Radarr's movies and Sonarr's shows directly into Jellyfin at `/movies` and `/shows`.
## Hardware Transcoding
For hardware-accelerated transcoding, you may need to pass through GPU devices. Create a custom compose overlay:
```yaml
# compose.gpu.yml
services:
app:
devices:
- /dev/dri:/dev/dri # Intel QSV / VAAPI
```
Then add it to your configuration:
```bash
COMPOSE_FILE="compose.yml:compose.gpu.yml"
```
## Troubleshooting
### Health Check Failures
The health check uses Jellyfin's `/health` endpoint. If it fails:
1. Check logs: `abra app logs <app-name>`
2. Verify the container is running: `abra app ps <app-name>`
3. Ensure port 8096 isn't blocked internally
### Permission Issues
If Jellyfin can't access media files:
1. Check volume mount permissions
2. Ensure the container user has read access to media directories
3. Verify SELinux/AppArmor policies if applicable
## License
Jellyfin is licensed under [GPL-2.0](https://github.com/jellyfin/jellyfin/blob/master/LICENSE).

41
compose.backup.yml Normal file
View File

@ -0,0 +1,41 @@
---
services:
backup:
image: offen/docker-volume-backup:v2
environment:
- BACKUP_CRON_EXPRESSION=${BACKUP_CRON:-0 2 * * *}
- BACKUP_FILENAME=jellyfin-backup-%Y-%m-%dT%H-%M-%S.tar.gz
- BACKUP_PRUNING_PREFIX=jellyfin-backup-
- BACKUP_RETENTION_DAYS=${BACKUP_RETENTION_DAYS:-7}
- BACKUP_STOP_DURING_BACKUP_LABEL=jellyfin-backup
# Optional: S3-compatible storage
- AWS_S3_BUCKET_NAME=${AWS_S3_BUCKET_NAME:-}
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-}
- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-}
- AWS_S3_PATH=${AWS_S3_PATH:-}
- AWS_ENDPOINT=${AWS_ENDPOINT:-}
# Optional: SSH/SFTP storage
- SSH_HOST_NAME=${SSH_HOST_NAME:-}
- SSH_USER=${SSH_USER:-}
- SSH_REMOTE_PATH=${SSH_REMOTE_PATH:-}
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- config:/backup/config:ro
- ${BACKUP_LOCAL_PATH:-/tmp/jellyfin-backups}:/archive
networks:
- proxy
deploy:
restart_policy:
condition: on-failure
labels:
- "traefik.enable=false"
app:
deploy:
labels:
- "docker-volume-backup.stop-during-backup=jellyfin-backup"
volumes:
config:
external: true
name: ${STACK_NAME}_config

14
compose.media_volumes.yml Normal file
View File

@ -0,0 +1,14 @@
---
services:
app:
volumes:
- media_movies:/movies
- media_shows:/shows
volumes:
media_movies:
name: ${movies_volume}
external: true
media_shows:
name: ${shows_volume}
external: true

View File

@ -1,42 +1,42 @@
---
version: "3.8"
services:
app:
image: jellyfin/jellyfin:10.8.10
image: jellyfin/jellyfin:10.11.1
ports:
- "8096:8096"
environment:
- JELLYFIN_PublishedServerUrl=https://${DOMAIN}
volumes:
- config:/config
- cache:/cache
- ${EXTRA_VOLUME:-/dev/null:/tmp/.dummy}
networks:
- proxy
volumes:
- jellyfin_config:/config
- jellyfin_cache:/cache
- ${EXTRA_VOLUME}
deploy:
restart_policy:
condition: on-failure
labels:
- "traefik.enable=true"
- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=8096"
- "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS})"
- "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`)${EXTRA_DOMAINS}"
- "traefik.http.routers.${STACK_NAME}.entrypoints=web-secure"
- "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}"
## Redirect from EXTRA_DOMAINS to DOMAIN
#- "traefik.http.routers.${STACK_NAME}.middlewares=${STACK_NAME}-redirect"
#- "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLForceHost=true"
#- "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLHost=${DOMAIN}"
- "coop-cloud.${STACK_NAME}.version=0.1.6+10.8.10"
# healthcheck:
# test: ["CMD", "curl", "-f", "http://localhost:8096"]
# interval: 30s
# timeout: 10s
# retries: 10
# start_period: 1m
- "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV:-production}"
- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=8096"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8096/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
volumes:
jellyfin_config:
jellyfin_cache:
config:
cache:
networks:
proxy:
external: true
# coop-cloud recipe metadata
# LABEL version="0.6.0+10.11.1"
# LABEL healthcheck="true"
# LABEL backups="true"