Jellyseerr is a fork of the popular Overseerr media discovery and request management application built for Plex. It extends your Jellyfin ecosystem to allow users to request media as well as automatically trigger monitoring on Radarr and Sonarr.
Jellyseerr integrates with Jellyfin, allowing users to log-in with their same account, and monitors your library for available media.
Deploying Jellyseerr with Terraform on Kubernetes is straightforward, it's a Node-based application that only requires a single container.
terraform {
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = "2.13.1"
}
}
}
provider "kubernetes" {
config_path = "~/.kube/config"
config_context = "homelab01"
}
locals {
namespace = "jellyseerr"
jellyseerr_data_pvc = "jellyseerr-data-pvc"
}
resource "kubernetes_namespace" "jellyseerr" {
metadata {
name = local.namespace
}
}
resource "kubernetes_deployment" "jellyseerr" {
metadata {
name = "jellyseerr"
namespace = kubernetes_namespace.jellyseerr.metadata.0.name
labels = {
"app" = "jellyseerr"
}
}
spec {
replicas = 1
selector {
match_labels = {
"app" = "jellyseerr"
}
}
template {
metadata {
labels = {
"app" = "jellyseerr"
}
}
spec {
container {
image = "fallenbagel/jellyseerr:latest"
name = "jellyseerr"
env_from {
config_map_ref {
name = kubernetes_config_map.jellyseerr.metadata.0.name
}
}
port {
container_port = 5055
name = "http"
}
volume_mount {
name = "data"
mount_path = "/app/config"
}
}
volume {
name = "data"
persistent_volume_claim {
claim_name = local.jellyseerr_data_pvc
}
}
}
}
}
}
resource "kubernetes_persistent_volume_claim" "jellyseerr_data" {
metadata {
name = local.jellyseerr_data_pvc
namespace = kubernetes_namespace.jellyseerr.metadata.0.name
}
spec {
access_modes = ["ReadWriteOnce"]
resources {
requests = {
storage = "15Gi"
}
}
storage_class_name = "local-path"
}
}
resource "kubernetes_service" "jellyseerr" {
metadata {
name = "jellyseerr"
namespace = kubernetes_namespace.jellyseerr.metadata.0.name
}
spec {
type = "ClusterIP"
selector = {
"app" = "jellyseerr"
}
port {
name = "http"
port = 5055
target_port = "http"
}
}
depends_on = [
kubernetes_deployment.jellyseerr
]
}
resource "kubernetes_config_map" "jellyseerr" {
metadata {
name = "jellyseerr"
namespace = kubernetes_namespace.jellyseerr.metadata.0.name
}
data = {
"LOG_LEVEL" = "debug"
"TZ" = "Europe/Zurich"
}
}
You can add an Ingress to Jellyseerr to expose it publicly to the web. This can be done with the Kubernetes Ingress
CRD which Traefik supports.
resource "kubernetes_ingress_v1" "jellyseerr" {
metadata {
name = "jellyseerr"
namespace = kubernetes_namespace.jellyseerr.metadata.0.name
annotations = {
"traefik.ingress.kubernetes.io/router.entrypoints" = "websecure"
"traefik.ingress.kubernetes.io/router.tls.certresolver" = "letsencrypt"
}
}
spec {
rule {
host = var.host
http {
path {
path = "/"
path_type = "Prefix"
backend {
service {
name = kubernetes_service.jellyseerr.metadata.0.name
port {
name = kubernetes_service.jellyseerr.spec.port.0.name
}
}
}
}
}
}
}
}