Compare commits

..

1 Commits

Author SHA1 Message Date
Gauthier
497d629207 feat: refresh monitored downloads before getting queue items
Currently, we sync with sonarr/radarr with whatever value those return. Radarr/Sonarr syncs the
activity from the download clients every few minutes. This leads to inaccurate estimated download
times, because of the refresh delay with Jellyseerr and the *arrs.

This PR fixes this by making a request to the *arrs to refresh the monitored downloads just before
we get these downloads information.

re #866
2024-10-03 18:04:27 +02:00
511 changed files with 21761 additions and 41506 deletions

444
.all-contributorsrc Normal file
View File

@@ -0,0 +1,444 @@
{
"files": [
"README.md"
],
"imageSize": 100,
"commit": false,
"badgeTemplate": "<a href=\"#contributors-\"><img alt=\"All Contributors\" src=\"https://img.shields.io/badge/all_contributors-<%= contributors.length %>-orange.svg\"/></a>",
"contributorsPerLine": 7,
"projectName": "jellyseerr",
"projectOwner": "Fallenbagel",
"repoType": "github",
"repoHost": "https://github.com",
"skipCi": true,
"commitConvention": "angular",
"commitType": "docs",
"contributors": [
{
"login": "Fallenbagel",
"name": "Fallenbagel",
"avatar_url": "https://avatars.githubusercontent.com/u/98979876?v=4",
"profile": "https://github.com/Fallenbagel",
"contributions": [
"code",
"maintenance"
]
},
{
"login": "seanzhang98",
"name": "Sean",
"avatar_url": "https://avatars.githubusercontent.com/u/34902361?v=4",
"profile": "https://github.com/seanzhang98",
"contributions": [
"translation",
"code"
]
},
{
"login": "notfakie",
"name": "notfakie",
"avatar_url": "https://avatars.githubusercontent.com/u/103784113?v=4",
"profile": "https://github.com/notfakie",
"contributions": [
"code"
]
},
{
"login": "Jumail",
"name": "Mohamed Jumail",
"avatar_url": "https://avatars.githubusercontent.com/u/7672055?v=4",
"profile": "https://github.com/Jumail",
"contributions": [
"review"
]
},
{
"login": "jsl9208",
"name": "Shilong Jiang",
"avatar_url": "https://avatars.githubusercontent.com/u/4048787?v=4",
"profile": "https://www.heywhale.com",
"contributions": [
"code"
]
},
{
"login": "boring-dragon",
"name": "Boring Dragon",
"avatar_url": "https://avatars.githubusercontent.com/u/28459081?v=4",
"profile": "https://jinas.me",
"contributions": [
"code"
]
},
{
"login": "sambartik",
"name": "Samuel Bartík",
"avatar_url": "https://avatars.githubusercontent.com/u/63553146?v=4",
"profile": "https://github.com/sambartik",
"contributions": [
"code"
]
},
{
"login": "CyferShepard",
"name": "Thegan Govender",
"avatar_url": "https://avatars.githubusercontent.com/u/24864904?v=4",
"profile": "https://github.com/CyferShepard",
"contributions": [
"code"
]
},
{
"login": "jab416171",
"name": "jab416171",
"avatar_url": "https://avatars.githubusercontent.com/u/345752?v=4",
"profile": "https://github.com/jab416171",
"contributions": [
"doc"
]
},
{
"login": "NicolaiVdS",
"name": "Nicolai Van der Storm",
"avatar_url": "https://avatars.githubusercontent.com/u/5257222?v=4",
"profile": "https://nvds.be",
"contributions": [
"code"
]
},
{
"login": "Smexhy",
"name": "Smexhy",
"avatar_url": "https://avatars.githubusercontent.com/u/4880625?v=4",
"profile": "https://github.com/Smexhy",
"contributions": [
"translation"
]
},
{
"login": "dd060606",
"name": "dd060606",
"avatar_url": "https://avatars.githubusercontent.com/u/58089504?v=4",
"profile": "https://dd06-dev.fr",
"contributions": [
"code"
]
},
{
"login": "darmiel",
"name": "Daniel",
"avatar_url": "https://avatars.githubusercontent.com/u/71837281?v=4",
"profile": "https://qwer.tz",
"contributions": [
"code"
]
},
{
"login": "undone37",
"name": "undone37",
"avatar_url": "https://avatars.githubusercontent.com/u/10513808?v=4",
"profile": "https://github.com/undone37",
"contributions": [
"translation"
]
},
{
"login": "CheChu10",
"name": "Chechu García",
"avatar_url": "https://avatars.githubusercontent.com/u/32913133?v=4",
"profile": "https://github.com/CheChu10",
"contributions": [
"translation"
]
},
{
"login": "DimitriDR",
"name": "Dimitri",
"avatar_url": "https://avatars.githubusercontent.com/u/56969769?v=4",
"profile": "https://github.com/DimitriDR",
"contributions": [
"translation"
]
},
{
"login": "andrey4korop",
"name": "andrey4korop",
"avatar_url": "https://avatars.githubusercontent.com/u/24610708?v=4",
"profile": "https://github.com/andrey4korop",
"contributions": [
"code",
"translation"
]
},
{
"login": "GeoffreyCoulaud",
"name": "Geoffrey Coulaud",
"avatar_url": "https://avatars.githubusercontent.com/u/20744730?v=4",
"profile": "https://geoffrey-coulaud.fr",
"contributions": [
"translation"
]
},
{
"login": "Pikachu920",
"name": "Pikachu920",
"avatar_url": "https://avatars.githubusercontent.com/u/28607612?v=4",
"profile": "https://github.com/Pikachu920",
"contributions": [
"code"
]
},
{
"login": "yalagin",
"name": "Maxim Yalagin",
"avatar_url": "https://avatars.githubusercontent.com/u/12879142?v=4",
"profile": "https://github.com/yalagin",
"contributions": [
"code"
]
},
{
"login": "jeaboswell",
"name": "Jesse Boswell",
"avatar_url": "https://avatars.githubusercontent.com/u/11653068?v=4",
"profile": "https://github.com/jeaboswell",
"contributions": [
"code"
]
},
{
"login": "d-fendrich",
"name": "d-fendrich",
"avatar_url": "https://avatars.githubusercontent.com/u/27904138?v=4",
"profile": "https://github.com/d-fendrich",
"contributions": [
"translation"
]
},
{
"login": "davidfdezalcoba",
"name": "David Fernández Alcoba",
"avatar_url": "https://avatars.githubusercontent.com/u/15996018?v=4",
"profile": "https://github.com/davidfdezalcoba",
"contributions": [
"code"
]
},
{
"login": "Gauvino",
"name": "Gauvino",
"avatar_url": "https://avatars.githubusercontent.com/u/68083474?v=4",
"profile": "https://github.com/Gauvino",
"contributions": [
"translation"
]
},
{
"login": "EthanArmbrust",
"name": "EthanArmbrust",
"avatar_url": "https://avatars.githubusercontent.com/u/22754714?v=4",
"profile": "https://github.com/EthanArmbrust",
"contributions": [
"code"
]
},
{
"login": "SirMartin",
"name": "Eduardo",
"avatar_url": "https://avatars.githubusercontent.com/u/854646?v=4",
"profile": "http://www.piribisoft.com",
"contributions": [
"doc"
]
},
{
"login": "RickLuiken",
"name": "RickLuiken",
"avatar_url": "https://avatars.githubusercontent.com/u/34110371?v=4",
"profile": "https://github.com/RickLuiken",
"contributions": [
"code"
]
},
{
"login": "Br33ce",
"name": "Br33ce",
"avatar_url": "https://avatars.githubusercontent.com/u/124933490?v=4",
"profile": "https://github.com/Br33ce",
"contributions": [
"translation"
]
},
{
"login": "athphane",
"name": "Athfan Khaleel",
"avatar_url": "https://avatars.githubusercontent.com/u/13810742?v=4",
"profile": "https://athfan.com",
"contributions": [
"doc"
]
},
{
"login": "mdll23",
"name": "Michael Dallinger",
"avatar_url": "https://avatars.githubusercontent.com/u/142844478?v=4",
"profile": "https://github.com/mdll23",
"contributions": [
"translation"
]
},
{
"login": "xeruf",
"name": "Janek",
"avatar_url": "https://avatars.githubusercontent.com/u/13354331?v=4",
"profile": "https://github.com/xeruf",
"contributions": [
"doc"
]
},
{
"login": "aleksasiriski",
"name": "Aleksa Siriški",
"avatar_url": "https://avatars.githubusercontent.com/u/31509435?v=4",
"profile": "https://aleksasiriski.dev",
"contributions": [
"infra"
]
},
{
"login": "Danish-H",
"name": "Danish Humair",
"avatar_url": "https://avatars.githubusercontent.com/u/121830048?v=4",
"profile": "http://danishhumair.com",
"contributions": [
"code"
]
},
{
"login": "trackmastersteve",
"name": "Stephen Harris",
"avatar_url": "https://avatars.githubusercontent.com/u/16858514?v=4",
"profile": "https://arm0.red",
"contributions": [
"doc"
]
},
{
"login": "joshuaboniface",
"name": "Joshua M. Boniface",
"avatar_url": "https://avatars.githubusercontent.com/u/4031396?v=4",
"profile": "https://www.boniface.me",
"contributions": [
"code"
]
},
{
"login": "gauthier-th",
"name": "Gauthier",
"avatar_url": "https://avatars.githubusercontent.com/u/37781713?v=4",
"profile": "https://gauthierth.fr/",
"contributions": [
"code"
]
},
{
"login": "Kara-Zor-El",
"name": "Kara",
"avatar_url": "https://avatars.githubusercontent.com/u/69772087?v=4",
"profile": "https://github.com/Kara-Zor-El",
"contributions": [
"infra"
]
},
{
"login": "JoaquinOlivero",
"name": "Joaquin Olivero",
"avatar_url": "https://avatars.githubusercontent.com/u/66050823?v=4",
"profile": "https://joaquinolivero.com",
"contributions": [
"code"
]
},
{
"login": "Bretterteig",
"name": "Julian Behr",
"avatar_url": "https://avatars.githubusercontent.com/u/47298401?v=4",
"profile": "https://github.com/Bretterteig",
"contributions": [
"translation"
]
},
{
"login": "ThowZzy",
"name": "ThowZzy",
"avatar_url": "https://avatars.githubusercontent.com/u/61882536?v=4",
"profile": "https://github.com/ThowZzy",
"contributions": [
"code"
]
},
{
"login": "j0srisk",
"name": "Joseph Risk",
"avatar_url": "https://avatars.githubusercontent.com/u/18372584?v=4",
"profile": "http://josephrisk.com",
"contributions": [
"code"
]
},
{
"login": "Loetwiek",
"name": "Loetwiek",
"avatar_url": "https://avatars.githubusercontent.com/u/79059734?v=4",
"profile": "https://github.com/Loetwiek",
"contributions": [
"code"
]
},
{
"login": "Fuochi",
"name": "Fuochi",
"avatar_url": "https://avatars.githubusercontent.com/u/4720478?v=4",
"profile": "https://github.com/Fuochi",
"contributions": [
"doc"
]
},
{
"login": "mobihen",
"name": "Nir Israel Hen",
"avatar_url": "https://avatars.githubusercontent.com/u/35529491?v=4",
"profile": "https://mobihen.com",
"contributions": [
"translation"
]
},
{
"login": "XDark187",
"name": "Baraa",
"avatar_url": "https://avatars.githubusercontent.com/u/39034192?v=4",
"profile": "https://github.com/XDark187",
"contributions": [
"code"
]
},
{
"login": "franciscofsales",
"name": "Francisco Sales",
"avatar_url": "https://avatars.githubusercontent.com/u/7977645?v=4",
"profile": "https://github.com/franciscofsales",
"contributions": [
"code"
]
},
{
"login": "myselfolli",
"name": "Oliver Laing",
"avatar_url": "https://avatars.githubusercontent.com/u/37535998?v=4",
"profile": "https://github.com/myselfolli",
"contributions": [
"code"
]
}
]
}

View File

@@ -1,29 +1,29 @@
**/*.md
**/.gitkeep
**/.vscode
.all-contributorsrc
.dockerignore
.editorconfig
.eslintrc.js
.git
.gitbook.yaml
.gitconfig
.github
.gitignore
.husky
.next
.prettierignore
.vscode
charts
config/db/*
config/logs/*
config/*.json
cypress
dist
Dockerfile*
compose.yaml
gen-docs
docker-compose.yml
docs
LICENSE
node_modules
public/os_logo_filled.png
public/preview.jpg
snap
stylelint.config.js
cypress

3
.gitattributes vendored
View File

@@ -37,9 +37,10 @@ docs export-ignore
*ignore export-ignore
*.md export-ignore
.all-contributorsrc export-ignore
.editorconfig export-ignore
Dockerfile.local export-ignore
compose.yaml export-ignore
docker-compose.yml export-ignore
stylelint.config.js export-ignore
public/os_logo_filled.png export-ignore

5
.gitbook.yaml Normal file
View File

@@ -0,0 +1,5 @@
root: ./docs
structure:
readme: README.md
summary: SUMMARY.md

2
.github/CODEOWNERS vendored
View File

@@ -1,2 +1,2 @@
# Global code ownership
* @seerr-team/seerr-core
* @Fallenbagel @gauthier-th

2
.github/FUNDING.yml vendored
View File

@@ -1 +1 @@
open_collective: seerr
buy_me_a_coffee: fallen.bagel

View File

@@ -19,7 +19,7 @@ body:
id: version
attributes:
label: Version
description: What version of Seerr are you running? (You can find this in Settings → About → Version.)
description: What version of Jellyseerr are you running? (You can find this in Settings → About → Version.)
validations:
required: true
- type: textarea
@@ -55,16 +55,6 @@ body:
- tablet
validations:
required: true
- type: dropdown
id: database
attributes:
options:
- SQLite (default)
- PostgreSQL
label: Database
description: Which database backend are you using?
validations:
required: true
- type: input
id: device
attributes:
@@ -95,7 +85,7 @@ body:
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/seerr-team/seerr/blob/develop/CODE_OF_CONDUCT.md)
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/fallenbagel/jellyseerr/blob/develop/CODE_OF_CONDUCT.md)
options:
- label: I agree to follow Seerr's Code of Conduct
- label: I agree to follow Jellyseerr's Code of Conduct
required: true

View File

@@ -1,8 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: 💬 Support via Discord
url: https://discord.gg/seerr
about: Chat with other users and the Seerr dev team
url: https://discord.gg/ckbvBtDJgC
about: Chat with other users and the Jellyseerr dev team
- name: 💬 Support via GitHub Discussions
url: https://github.com/seerr-team/seerr/discussions
url: https://github.com/fallenbagel/jellyseerr/discussions
about: Ask questions and discuss with other community members

View File

@@ -31,7 +31,7 @@ body:
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/seerr-team/seerr/blob/develop/CODE_OF_CONDUCT.md)
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/fallenbagel/jellyseerr/blob/develop/CODE_OF_CONDUCT.md)
options:
- label: I agree to follow Seerr's Code of Conduct
- label: I agree to follow Jellyseerr's Code of Conduct
required: true

View File

@@ -1,33 +1,13 @@
<!--
Please read contributing guide before submitting
your pull request. Please fill in each section below to help us better prioritize your pull request. Thanks!
-->
#### Description
## Description
#### Screenshot (if UI-related)
<!--- Describe your changes in detail -->
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
#### To-Dos
- Fixes #XXXX
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->
## Screenshots / Logs (if applicable)
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [ ] I have read and followed the contribution [guidelines](https://github.com/seerr-team/seerr/blob/develop/CONTRIBUTING.md).
- [ ] Disclosed any use of AI (see our [policy](https://github.com/seerr-team/seerr/blob/develop/CONTRIBUTING.md#ai-assistance-notice))
- [ ] I have updated the documentation accordingly.
- [ ] All new and existing tests passed.
- [ ] Successful build `pnpm build`
- [ ] Translation keys `pnpm i18n:extract`
- [ ] Database migration (if required)
#### Issues Fixed or Closed
- Fixes #XXXX

94
.github/cliff.toml vendored
View File

@@ -1,94 +0,0 @@
# git-cliff ~ configuration
# https://git-cliff.org/docs/configuration
[changelog]
header = ""
body = """
{%- macro remote_url() -%}
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
{%- endmacro -%}
{%- set excluded_users = ["github-actions[bot]", "dependabot[bot]", "renovate[bot]"] -%}
{% macro print_commit(commit) -%}
- {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
{% if commit.breaking %}[**breaking**] {% endif %}\
{{ commit.message | upper_first }} - \
([{{ commit.id | truncate(length=7, end="") }}]({{ self::remote_url() }}/commit/{{ commit.id }}))\
{% endmacro -%}
{% if version %}\
{% if previous.version %}\
## [{{ version | trim_start_matches(pat="v") }}]({{ self::remote_url() }}/compare/{{ previous.version }}..{{ version }}) - {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% endif %}\
{% else %}\
## [unreleased]
{% endif %}\
{%- for group, commits in commits | group_by(attribute="group") %}
### {{ group | striptags | trim | upper_first }}
{%- for commit in commits | filter(attribute="scope") | sort(attribute="scope") %}
{{ self::print_commit(commit=commit) }}
{%- endfor %}
{%- for commit in commits %}
{%- if not commit.scope -%}
{{ self::print_commit(commit=commit) }}
{%- endif -%}
{%- endfor -%}
{%- endfor -%}
{%- set valid_contributors = [] -%}
{%- for c in github.contributors | filter(attribute="is_first_time", value=true) %}
{%- if c.username and c.username not in excluded_users and c.username not in valid_contributors %}
{%- set_global valid_contributors = valid_contributors | concat(with=c.username) %}
{%- endif %}
{%- endfor %}
{%- if valid_contributors | length > 0 %}
## New Contributors ❤️
{%- for username in valid_contributors %}
* @{{ username }} made their first contribution
{%- endfor %}
{%- endif %}
"""
footer = """
<!-- generated by git-cliff -->
"""
trim = true
postprocessors = []
[git]
conventional_commits = true
filter_unconventional = true
split_commits = false
filter_commits = true
commit_preprocessors = [
{ pattern = '.*\[skip ci\].*', replace = "" },
{ pattern = '.*\[ci skip\].*', replace = "" },
]
commit_parsers = [
{ message = "^feat", group = "<!-- 0 -->🚀 Features" },
{ message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
{ message = "^doc", group = "<!-- 3 -->📖 Documentation" },
{ message = "^perf", group = "<!-- 4 -->⚡ Performance" },
{ message = "^refactor", group = "<!-- 2 -->🚜 Refactor" },
{ message = "^style", group = "<!-- 5 -->🎨 Styling" },
{ message = "^test", group = "<!-- 6 -->🧪 Testing" },
{ message = "^chore\\(release\\): prepare for", skip = true },
{ message = "^chore\\(deps.*\\)", skip = true },
{ message = "^chore\\(pr\\)", skip = true },
{ message = "^chore\\(pull\\)", skip = true },
{ message = "^chore\\(git-sync\\)", skip = true },
{ message = "^chore|^ci", group = "<!-- 7 -->⚙️ Miscellaneous Tasks" },
{ body = ".*security", group = "<!-- 8 -->🛡️ Security" },
{ message = "^revert", group = "<!-- 9 -->◀️ Revert" },
{ message = '.*\[skip ci\].*', skip = true },
{ message = '.*\[ci skip\].*', skip = true },
]
protect_breaking_commits = false
tag_pattern = "v?[0-9]+\\.[0-9]+\\.[0-9]+.*"
skip_tags = "beta|alpha|rc"
topo_order = false
sort_commits = "newest"

5
.github/holopin.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
organization: overseerr
defaultSticker: clcyagj1j329008l468ya8pu2
stickers:
- id: clcyagj1j329008l468ya8pu2
alias: overseerr-contributor

38
.github/lock.yml vendored Normal file
View File

@@ -0,0 +1,38 @@
# Configuration for Lock Threads - https://github.com/dessant/lock-threads-app
# Number of days of inactivity before a closed issue or pull request is locked
daysUntilLock: 365
# Skip issues and pull requests created before a given timestamp. Timestamp must
# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable
skipCreatedBefore: false
# Issues and pull requests with these labels will be ignored. Set to `[]` to disable
exemptLabels:
- dependencies
# Label to add before locking, such as `outdated`. Set to `false` to disable
lockLabel: false
# Comment to post before locking. Set to `false` to disable
lockComment: >
This thread has been automatically locked since there has not been
any recent activity after it was closed. Please open a new issue for
related bugs.
# Assign `resolved` as the reason for locking. Set to `false` to disable
setLockReason: true
# Limit to only `issues` or `pulls`
# only: issues
# Optionally, specify configuration settings just for `issues` or `pulls`
# issues:
# exemptLabels:
# - help-wanted
# lockLabel: outdated
# pulls:
# daysUntilLock: 30
# Repository to extend settings from
# _extends: repo

View File

@@ -1,25 +0,0 @@
{
$schema: 'https://docs.renovatebot.com/renovate-schema.json',
extends: [
'config:recommended',
':dependencyDashboard',
':timezone(UTC)',
'group:allNonMajor',
'group:nextjsMonorepo',
'group:reactMonorepo',
'group:typescript-eslintMonorepo',
'group:tailwindcssMonorepo',
'github>seerr-team/seerr//.github/renovate/actions.json5',
'github>seerr-team/seerr//.github/renovate/docker.json5',
'github>seerr-team/seerr//.github/renovate/groups.json5',
'github>seerr-team/seerr//.github/renovate/helm.json5',
'github>seerr-team/seerr//.github/renovate/labels.json5',
'github>seerr-team/seerr//.github/renovate/pnpm.json5',
'github>seerr-team/seerr//.github/renovate/semanticCommits.json5',
],
dependencyDashboardTitle: 'Renovate Dashboard 🤖',
suppressNotifications: ['prEditedNotification', 'prIgnoreNotification'],
rebaseWhen: 'conflicted',
labels: ['dependencies'],
minimumReleaseAge: '7 days',
}

View File

@@ -1,13 +0,0 @@
{
$schema: 'https://docs.renovatebot.com/renovate-schema.json',
extends: ['helpers:pinGitHubActionDigests'],
packageRules: [
// All GitHub Actions need manual review
{
matchManagers: ['github-actions'],
groupName: 'GitHub Actions',
},
],
}

View File

@@ -1,15 +0,0 @@
{
$schema: 'https://docs.renovatebot.com/renovate-schema.json',
extends: [
'docker:enableMajor',
'docker:pinDigests'
],
packageRules: [
{
matchManagers: ['docker-compose'],
pinDigests: false,
},
],
}

View File

@@ -1,19 +0,0 @@
{
$schema: 'https://docs.renovatebot.com/renovate-schema.json',
packageRules: [
// Node.js
{
matchPackageNames: ['node'],
matchManagers: ['dockerfile', 'npm'],
groupName: 'Node.js',
commitMessageTopic: 'Node.js',
},
// Database packages
{
matchPackageNames: ['pg', 'sqlite3', 'typeorm'],
groupName: 'Database',
},
],
}

View File

@@ -1,24 +0,0 @@
{
$schema: 'https://docs.renovatebot.com/renovate-schema.json',
packageRules: [
{
matchManagers: ['helm-values'],
matchFileNames: ['charts/*/values.yaml'],
minimumReleaseAge: '0',
pinDigests: false,
},
],
customManagers: [
{
customType: 'regex',
description: 'Update appVersion in Chart.yaml to match Docker image',
fileMatch: ['(^|/)Chart\\.yaml$'],
matchStrings: [
'#\\s+renovate:\\s+image=(?<depName>\\S*)\nappVersion:\\s+"(?<currentValue>\\S*)"',
],
datasourceTemplate: 'docker',
},
],
}

View File

@@ -1,29 +0,0 @@
{
$schema: 'https://docs.renovatebot.com/renovate-schema.json',
packageRules: [
// JavaScript/npm packages
{
matchManagers: ['npm'],
addLabels: ['javascript'],
},
// GitHub Actions
{
matchManagers: ['github-actions'],
addLabels: ['github_actions'],
},
// Docker images
{
matchManagers: ['dockerfile', 'docker-compose'],
addLabels: ['docker'],
},
// Helm charts
{
matchManagers: ['helm-values'],
addLabels: ['helm'],
},
],
}

View File

@@ -1,11 +0,0 @@
{
$schema: 'https://docs.renovatebot.com/renovate-schema.json',
// Run pnpm dedupe after dependency updates
postUpdateOptions: ['pnpmDedupe'],
lockFileMaintenance: {
enabled: true,
},
}

View File

@@ -1,33 +0,0 @@
{
$schema: 'https://docs.renovatebot.com/renovate-schema.json',
packageRules: [
// Default for all dependencies
{
matchPackagePatterns: ['*'],
semanticCommitType: 'chore',
semanticCommitScope: 'deps',
},
// Node.js runtime
{
matchPackageNames: ['node'],
semanticCommitType: 'build',
semanticCommitScope: 'node',
},
// GitHub Actions
{
matchManagers: ['github-actions'],
semanticCommitType: 'ci',
semanticCommitScope: 'actions',
},
// Docker
{
matchManagers: ['dockerfile'],
semanticCommitType: 'build',
semanticCommitScope: 'docker',
},
],
}

44
.github/stale.yml vendored Normal file
View File

@@ -0,0 +1,44 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 60
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 7
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
- pinned
- security
- dependencies
- never-stale
- priority:high
- priority:medium
# Label to use when marking as stale
staleLabel: stale
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when removing the stale label.
# unmarkComment: >
# Your comment here.
# Comment to post when closing a stale Issue or Pull Request.
# closeComment: >
# Your comment here.
# Limit to only `issues` or `pulls`
# only: issues
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
pulls:
markComment: >
This pull request has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.

View File

@@ -1,6 +1,4 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Seerr CI
name: Jellyseerr CI
on:
pull_request:
@@ -9,150 +7,71 @@ on:
push:
branches:
- develop
workflow_dispatch:
permissions:
contents: read
env:
DOCKER_HUB: seerr/seerr
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
name: Lint & Test Build
if: github.event_name == 'pull_request'
runs-on: ubuntu-24.04
container: node:22.20.0-alpine3.22@sha256:dbcedd8aeab47fbc0f4dd4bffa55b7c3c729a707875968d467aaaea42d6225af
runs-on: ubuntu-22.04
container: node:20-alpine
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
uses: actions/checkout@v4
- name: Pnpm Setup
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
uses: pnpm/action-setup@v4
with:
version: 9
- name: Get pnpm store directory
shell: sh
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
env:
CI: true
HUSKY: 0
run: pnpm install
- name: Lint
run: pnpm lint
- name: Formatting
run: pnpm format:check
- name: Build
run: pnpm build
build:
name: Build (per-arch, native runners)
build_and_push:
name: Build & Publish Docker Images
if: github.ref == 'refs/heads/develop' && !contains(github.event.head_commit.message, '[skip ci]')
strategy:
matrix:
include:
- runner: ubuntu-24.04
platform: linux/amd64
arch: amd64
- runner: ubuntu-24.04-arm
platform: linux/arm64
arch: arm64
runs-on: ${{ matrix.runner }}
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Commit timestamp
id: ts
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Warm cache (no push) — ${{ matrix.platform }}
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: .
file: ./Dockerfile
platforms: ${{ matrix.platform }}
push: false
build-args: |
COMMIT_TAG=${{ github.sha }}
BUILD_VERSION=develop
SOURCE_DATE_EPOCH=${{ steps.ts.outputs.TIMESTAMP }}
cache-from: type=gha,scope=${{ matrix.platform }}
cache-to: type=gha,mode=max,scope=${{ matrix.platform }}
provenance: false
publish:
name: Publish multi-arch image
needs: build
runs-on: ubuntu-24.04
permissions:
contents: read
packages: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Commit timestamp
id: ts
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
with:
images: |
${{ env.DOCKER_HUB }}
ghcr.io/${{ github.repository }}
tags: |
type=raw,value=develop
type=sha
labels: |
org.opencontainers.image.created=${{ steps.ts.outputs.TIMESTAMP }}
- name: Build & Push (multi-arch, single tag)
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
- name: Set lower case owner name
run: |
echo "OWNER_LC=${OWNER,,}" >>${GITHUB_ENV}
env:
OWNER: ${{ github.repository_owner }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
@@ -160,52 +79,31 @@ jobs:
push: true
build-args: |
COMMIT_TAG=${{ github.sha }}
BUILD_VERSION=develop
SOURCE_DATE_EPOCH=${{ steps.ts.outputs.TIMESTAMP }}
labels: ${{ steps.meta.outputs.labels }}
tags: ${{ steps.meta.outputs.tags }}
cache-from: |
type=gha,scope=linux/amd64
type=gha,scope=linux/arm64
cache-to: type=gha,mode=max
provenance: false
tags: |
fallenbagel/jellyseerr:develop
ghcr.io/${{ env.OWNER_LC }}/jellyseerr:develop
discord:
name: Send Discord Notification
needs: publish
needs: build_and_push
if: always() && github.event_name != 'pull_request' && !contains(github.event.head_commit.message, '[skip ci]')
runs-on: ubuntu-24.04
runs-on: ubuntu-22.04
steps:
- name: Determine Workflow Status
- name: Get Build Job Status
uses: technote-space/workflow-conclusion-action@v3
- name: Combine Job Status
id: status
run: |
case "${{ needs.publish.result }}" in
success) echo "status=Success" >> $GITHUB_OUTPUT; echo "colour=3066993" >> $GITHUB_OUTPUT ;;
failure) echo "status=Failure" >> $GITHUB_OUTPUT; echo "colour=15158332" >> $GITHUB_OUTPUT ;;
cancelled) echo "status=Cancelled" >> $GITHUB_OUTPUT; echo "colour=10181046" >> $GITHUB_OUTPUT ;;
*) echo "status=Skipped" >> $GITHUB_OUTPUT; echo "colour=9807270" >> $GITHUB_OUTPUT ;;
esac
- name: Send Discord notification
shell: bash
run: |
WEBHOOK="${{ secrets.DISCORD_WEBHOOK }}"
PAYLOAD=$(cat <<EOF
{
"embeds": [{
"title": "${{ steps.status.outputs.status }}: ${{ github.workflow }}",
"color": ${{ steps.status.outputs.colour }},
"fields": [
{ "name": "Repository", "value": "[${{ github.repository }}](${{ github.server_url }}/${{ github.repository }})", "inline": true },
{ "name": "Ref", "value": "${{ github.ref }}", "inline": true },
{ "name": "Event", "value": "${{ github.event_name }}", "inline": true },
{ "name": "Triggered by", "value": "${{ github.actor }}", "inline": true },
{ "name": "Workflow", "value": "[${{ github.workflow }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})", "inline": true }
],
}]
}
EOF
)
curl -sS -H "Content-Type: application/json" -X POST -d "$PAYLOAD" "$WEBHOOK" || true
failures=(neutral, skipped, timed_out, action_required)
if [[ ${array[@]} =~ $WORKFLOW_CONCLUSION ]]; then
echo "status=failure" >> $GITHUB_OUTPUT
else
echo "status=$WORKFLOW_CONCLUSION" >> $GITHUB_OUTPUT
fi
- name: Post Status to Discord
uses: sarisia/actions-status-discord@v1
with:
webhook: ${{ secrets.DISCORD_WEBHOOK }}
status: ${{ steps.status.outputs.status }}
title: ${{ github.workflow }}
nofail: true

View File

@@ -1,56 +1,41 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: 'CodeQL'
on:
push:
branches: ['develop']
paths-ignore:
- '**/*.md'
- 'docs/**'
pull_request:
branches: ['develop']
paths-ignore:
- '**/*.md'
- 'docs/**'
schedule:
- cron: '50 7 * * 5'
permissions:
contents: read
concurrency:
group: codeql-${{ github.ref }}
cancel-in-progress: true
jobs:
analyze:
name: Analyze
runs-on: ubuntu-24.04
timeout-minutes: 10
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [actions, javascript]
language: [javascript]
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
queries: +security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7
uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7
uses: github/codeql-action/analyze@v2
with:
category: '/language:${{ matrix.language }}'

View File

@@ -1,33 +1,25 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Merge Conflict Labeler
on:
push:
branches: [develop]
branches:
- develop
pull_request_target:
branches: [develop]
types: [opened, synchronize, reopened]
permissions:
contents: read
concurrency:
group: merge-conflict-${{ github.ref }}
cancel-in-progress: true
branches:
- develop
types: [synchronize]
jobs:
label:
name: Labeling
runs-on: ubuntu-24.04
timeout-minutes: 10
runs-on: ubuntu-latest
if: ${{ github.repository == 'Fallenbagel/jellyseerr' }}
permissions:
contents: read
pull-requests: write
steps:
- name: Apply label
uses: eps1lon/actions-label-merge-conflict@1df065ebe6e3310545d4f4c4e862e43bdca146f0 # v3.0.3
uses: eps1lon/actions-label-merge-conflict@v3
with:
dirtyLabel: 'merge conflict'
commentOnDirty: 'This pull request has merge conflicts. Please resolve the conflicts so the PR can be successfully reviewed and merged.'

View File

@@ -1,75 +1,30 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Cypress Tests
on:
pull_request:
branches: ['*']
paths:
- '{src,server,config,cypress}/**'
- 'cypress.config.ts'
- 'package.json'
- 'pnpm-lock.yaml'
- 'next.config.js'
- 'tsconfig.json'
- '.github/workflows/cypress.yml'
branches:
- '*'
push:
branches: [develop]
paths:
- '{src,server,config,cypress}/**'
- 'cypress.config.ts'
- 'package.json'
- 'pnpm-lock.yaml'
- 'next.config.js'
- 'tsconfig.json'
- '.github/workflows/cypress.yml'
permissions:
contents: read
concurrency:
group: cypress-${{ github.ref }}
cancel-in-progress: true
branches:
- develop
jobs:
cypress-run:
name: Cypress Run
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
uses: actions/setup-node@v4
with:
node-version-file: package.json
package-manager-cache: false
node-version: 20
- name: Pnpm Setup
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Setup cypress cache
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: pnpm/action-setup@v4
with:
path: ~/.cache/Cypress
key: ${{ runner.os }}-cypress-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-cypress-store-
- name: Install Cypress binary
env:
CYPRESS_CACHE_FOLDER: ~/.cache/Cypress
run: pnpm exec cypress install
version: 9
- name: Cypress run
uses: cypress-io/github-action@b8ba51a856ba5f4c15cf39007636d4ab04f23e3c # v6.10.2
uses: cypress-io/github-action@v6
with:
install: false
build: pnpm cypress:build
start: pnpm start
wait-on: 'http://localhost:5055'

View File

@@ -1,41 +1,31 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Deploy to GitHub Pages
on:
workflow_dispatch:
push:
branches:
- legacy-jellyseerr
- develop
paths:
- 'docs/**'
- 'gen-docs/**'
permissions:
contents: read
concurrency:
group: pages
cancel-in-progress: true
jobs:
build:
name: Build Docusaurus
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Set up Node.js
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
uses: actions/setup-node@v4
with:
node-version-file: package.json
package-manager-cache: false
node-version: 20
- name: Pnpm Setup
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
uses: pnpm/action-setup@v4
with:
version: 9
- name: Get pnpm store directory
shell: sh
@@ -43,7 +33,7 @@ jobs:
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
@@ -56,26 +46,38 @@ jobs:
pnpm install --frozen-lockfile
- name: Build website
working-directory: gen-docs
run: pnpm build
run: |
cd gen-docs
pnpm build
- name: Upload Build Artifact
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b6 # v4.0.0
uses: actions/upload-pages-artifact@v3
with:
path: gen-docs/build
deploy:
name: Deploy to GitHub Pages
needs: build
runs-on: ubuntu-24.04
concurrency: build-deploy-pages
# Grant GITHUB_TOKEN the permissions required to make a Pages deployment
permissions:
contents: read
pages: write
id-token: write
pages: write # to deploy to Pages
id-token: write # to verify the deployment originates from an appropriate source
# Deploy to the github-pages environment
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
# - name: Download Build Artifact
# uses: actions/download-artifact@v4
# with:
# name: docusaurus-build
# path: gen-docs/build
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5
uses: actions/deploy-pages@v4

View File

@@ -1,69 +0,0 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Check Docs Links
on:
pull_request:
branches:
- '*'
paths:
- 'docs/**'
- 'gen-docs/**'
- '.github/workflows/docs-link-check.yml'
push:
branches:
- develop
paths:
- 'docs/**'
- 'gen-docs/**'
- '.github/workflows/docs-link-check.yml'
schedule:
- cron: '50 7 * * 5'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: docs-link-check-${{ github.ref }}
cancel-in-progress: true
jobs:
link-check:
name: Verify external links in Markdown and MDX
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
persist-credentials: false
- name: Run Lychee link checker
uses: lycheeverse/lychee-action@885c65f3dc543b57c898c8099f4e08c8afd178a2 # v2.6.1
with:
fail: false
args: >-
--verbose
--no-progress
--accept 200..204,300..304,307,308,404,429,999
--exclude '^file://'
--exclude '^https?://(localhost|127\.0\.0\.1|0\.0\.0\.0|\[::1\]|\[::\])'
--exclude '^https?://support\.discord\.com'
'./docs/**/*.md'
'./docs/**/*.mdx'
'./gen-docs/**/*.md'
'./gen-docs/**/*.mdx'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload Lychee report
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: lychee-report
path: |
lychee/out.md
lychee/results.json
if-no-files-found: ignore

View File

@@ -1,186 +0,0 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Release Charts
on:
push:
branches:
- develop
paths:
- 'charts/**'
- '.github/workflows/release-charts.yml'
permissions:
contents: read
concurrency:
group: helm-charts
cancel-in-progress: true
jobs:
package-helm-chart:
name: Package helm chart
runs-on: ubuntu-24.04
permissions:
contents: read
packages: read
outputs:
has_artifacts: ${{ steps.check-artifacts.outputs.has_artifacts }}
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
persist-credentials: false
- name: Install helm
uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1
- name: Install Oras
uses: oras-project/setup-oras@22ce207df3b08e061f537244349aac6ae1d214f6 # v1.2.4
- name: Login to GitHub Container Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Package helm charts
run: |
mkdir -p ./.cr-release-packages
for chart_path in ./charts/*; do
if [ -d "$chart_path" ] && [ -f "$chart_path/Chart.yaml" ]; then
chart_name=$(grep '^name:' "$chart_path/Chart.yaml" | awk '{print $2}')
# get current version
current_version=$(grep '^version:' "$chart_path/Chart.yaml" | awk '{print $2}')
# try to get current release version
if oras manifest fetch "ghcr.io/${{ github.repository }}/${chart_name}:${current_version}" >/dev/null 2>&1; then
echo "No version change for $chart_name. Skipping."
else
helm dependency build "$chart_path"
helm package "$chart_path" --destination ./.cr-release-packages
fi
else
echo "Skipping $chart_name: Not a valid Helm chart"
fi
done
- name: Check if artifacts exist
id: check-artifacts
run: |
if ls .cr-release-packages/*.tgz >/dev/null 2>&1; then
echo "has_artifacts=true" >> $GITHUB_OUTPUT
else
echo "has_artifacts=false" >> $GITHUB_OUTPUT
fi
- name: Upload artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: steps.check-artifacts.outputs.has_artifacts == 'true'
with:
name: artifacts
include-hidden-files: true
path: .cr-release-packages/
publish:
name: Publish to ghcr.io
runs-on: ubuntu-24.04
permissions:
packages: write
id-token: write
needs: [package-helm-chart]
if: needs.package-helm-chart.outputs.has_artifacts == 'true'
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
persist-credentials: false
- name: Install helm
uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1
- name: Install Oras
uses: oras-project/setup-oras@22ce207df3b08e061f537244349aac6ae1d214f6 # v1.2.4
- name: Install Cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
- name: Downloads artifacts
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: artifacts
path: .cr-release-packages/
- name: Login to GitHub Container Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Push charts to GHCR
env:
COSIGN_YES: true
run: |
for chart_path in `find .cr-release-packages -name '*.tgz' -print`; do
# push chart to OCI
chart_release_file=$(basename "$chart_path")
chart_name=${chart_release_file%-*}
helm push ${chart_path} oci://ghcr.io/${{ github.repository }} |& tee helm-push-output.log
chart_digest=$(awk -F "[, ]+" '/Digest/{print $NF}' < helm-push-output.log)
# sign chart
cosign sign "ghcr.io/${{ github.repository }}/${chart_name}@${chart_digest}"
# push artifacthub-repo.yml to OCI
oras push \
ghcr.io/${{ github.repository }}/${chart_name}:artifacthub.io \
--config /dev/null:application/vnd.cncf.artifacthub.config.v1+yaml \
charts/$chart_name/artifacthub-repo.yml:application/vnd.cncf.artifacthub.repository-metadata.layer.v1.yaml \
|& tee oras-push-output.log
artifacthub_digest=$(grep "Digest:" oras-push-output.log | awk '{print $2}')
# sign artifacthub-repo.yml
cosign sign "ghcr.io/${{ github.repository }}/${chart_name}:artifacthub.io@${artifacthub_digest}"
done
verify:
name: Verify signatures for each chart tag
needs: [publish]
runs-on: ubuntu-24.04
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
persist-credentials: false
- name: Install Cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
- name: Downloads artifacts
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: artifacts
path: .cr-release-packages/
- name: Login to GitHub Container Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Verify signatures for each chart tag
run: |
for chart_path in $(find .cr-release-packages -name '*.tgz' -print); do
chart_release_file=$(basename "$chart_path")
chart_name=${chart_release_file%-*}
version=${chart_release_file#$chart_name-}
version=${version%.tgz}
cosign verify "ghcr.io/${{ github.repository }}/${chart_name}:${version}" \
--certificate-identity "https://github.com/${{ github.workflow_ref }}" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
done

View File

@@ -1,56 +0,0 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Lint and Test Charts
on:
pull_request:
branches:
- develop
paths:
- '.github/workflows/lint-helm-charts.yml'
- 'charts/**'
push:
branches: [develop]
paths:
- 'charts/**'
permissions:
contents: read
concurrency:
group: charts-lint-${{ github.ref }}
cancel-in-progress: true
jobs:
lint-test:
runs-on: ubuntu-24.04
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
persist-credentials: false
- name: Set up Helm
uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1
- name: Set up chart-testing
uses: helm/chart-testing-action@0d28d3144d3a25ea2cc349d6e59901c4ff469b3b # v2.7.0
- name: Ensure documentation is updated
uses: docker://jnorwood/helm-docs:v1.14.2@sha256:7e562b49ab6b1dbc50c3da8f2dd6ffa8a5c6bba327b1c6335cc15ce29267979c
- name: Run chart-testing (list-changed)
id: list-changed
run: |
changed=$(ct list-changed --target-branch ${{ github.event.repository.default_branch }})
if [[ -n "$changed" ]]; then
echo "changed=true" >> "$GITHUB_OUTPUT"
echo "$changed"
fi
- name: Run chart-testing
if: steps.list-changed.outputs.changed == 'true'
run: ct lint --target-branch ${{ github.event.repository.default_branch }} --validate-maintainers=false

View File

@@ -1,133 +1,31 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Seerr Preview
name: Jellyseerr Preview
on:
push:
tags:
- 'preview-*'
workflow_dispatch:
permissions:
contents: read
env:
DOCKER_HUB: seerr/seerr
concurrency:
group: preview-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: Build (per-arch, native runners)
strategy:
matrix:
include:
- runner: ubuntu-24.04
platform: linux/amd64
arch: amd64
- runner: ubuntu-24.04-arm
platform: linux/arm64
arch: arm64
runs-on: ${{ matrix.runner }}
build_and_push:
name: Build & Publish Docker Preview Images
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Commit timestamp
id: ts
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
uses: actions/checkout@v4
- name: Get the version
id: get_version
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Derive preview version from tag
id: ver
shell: bash
run: |
TAG="${GITHUB_REF_NAME}"
VER="${TAG#preview-}"
VER="${VER#v}"
echo "version=${VER}" >> "$GITHUB_OUTPUT"
echo "Building preview version: ${VER}"
- name: Warm cache (no push) — ${{ matrix.platform }}
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: .
file: ./Dockerfile
platforms: ${{ matrix.platform }}
push: false
build-args: |
COMMIT_TAG=${{ github.sha }}
BUILD_VERSION=${{ steps.ver.outputs.version }}
SOURCE_DATE_EPOCH=${{ steps.ts.outputs.TIMESTAMP }}
cache-from: type=gha,scope=${{ matrix.platform }}
cache-to: type=gha,mode=max,scope=${{ matrix.platform }}
provenance: false
publish:
name: Publish multi-arch image
needs: build
runs-on: ubuntu-24.04
permissions:
contents: read
packages: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Commit timestamp
id: ts
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Derive preview version from tag
id: ver
shell: bash
run: |
TAG="${GITHUB_REF_NAME}"
VER="${TAG#preview-}"
VER="${VER#v}"
echo "version=${VER}" >> "$GITHUB_OUTPUT"
echo "Publishing preview version: ${VER}"
- name: Extract metadata
id: meta
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
with:
images: |
${{ env.DOCKER_HUB }}
ghcr.io/${{ github.repository }}
tags: |
type=raw,value=preview-${{ steps.ver.outputs.version }}
labels: |
org.opencontainers.image.version=preview-${{ steps.ver.outputs.version }}
org.opencontainers.image.created=${{ steps.ts.outputs.TIMESTAMP }}
- name: Build & Push (multi-arch, single tag)
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
@@ -135,12 +33,5 @@ jobs:
push: true
build-args: |
COMMIT_TAG=${{ github.sha }}
BUILD_VERSION=${{ steps.ver.outputs.version }}
SOURCE_DATE_EPOCH=${{ steps.ts.outputs.TIMESTAMP }}
labels: ${{ steps.meta.outputs.labels }}
tags: ${{ steps.meta.outputs.tags }}
cache-from: |
type=gha,scope=linux/amd64
type=gha,scope=linux/arm64
cache-to: type=gha,mode=max
provenance: false
tags: |
fallenbagel/jellyseerr:${{ steps.get_version.outputs.VERSION }}

View File

@@ -1,345 +1,130 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Seerr Release
name: Jellyseer Release
on:
push:
tags:
- 'v*'
permissions:
contents: read
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: true
env:
DOCKER_HUB: seerr/seerr
on: workflow_dispatch
jobs:
changelog:
name: Generate changelog
runs-on: ubuntu-24.04
permissions:
contents: read
outputs:
release_body: ${{ steps.git-cliff.outputs.content }}
semantic-release:
name: Tag and release latest version
runs-on: ubuntu-22.04
env:
HUSKY: 0
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Generate changelog
id: git-cliff
uses: orhun/git-cliff-action@d77b37db2e3f7398432d34b72a12aa3e2ba87e51 # v4.6.0
- name: Set up Node.js
uses: actions/setup-node@v4
with:
config: .github/cliff.toml
args: -vv --current
env:
OUTPUT: CHANGELOG.md
GITHUB_REPO: ${{ github.repository }}
create-draft-release:
name: Create draft release
runs-on: ubuntu-24.04
permissions:
contents: write
needs: changelog
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Draft Release
run: gh release create ${GITHUB_REF_NAME} -t "Release ${GITHUB_REF_NAME}" -n "${RELEASE_BODY}" --draft
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_BODY: ${{ needs.changelog.outputs.release_body }}
build:
name: Build (${{ matrix.arch }})
strategy:
matrix:
include:
- runner: ubuntu-24.04
platform: linux/amd64
arch: amd64
- runner: ubuntu-24.04-arm
platform: linux/arm64
arch: arm64
runs-on: ${{ matrix.runner }}
env:
VERSION: ${{ github.ref_name }}
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Commit timestamp
id: ts
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
node-version: 20
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Warm cache [${{ matrix.platform }}]
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: .
file: ./Dockerfile
platforms: ${{ matrix.platform }}
push: false
build-args: |
COMMIT_TAG=${{ github.sha }}
BUILD_VERSION=${{ env.VERSION }}
SOURCE_DATE_EPOCH=${{ steps.ts.outputs.TIMESTAMP }}
cache-from: type=gha,scope=${{ matrix.platform }}
cache-to: type=gha,mode=max,scope=${{ matrix.platform }}
provenance: false
publish:
name: Publish multi-arch manifests
needs: build
runs-on: ubuntu-24.04
permissions:
contents: read
packages: write
outputs:
image_digest: ${{ steps.digests.outputs.IMAGE_DIGEST }}
env:
VERSION: ${{ github.ref_name }}
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Commit timestamp
id: ts
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
- name: Pnpm Setup
uses: pnpm/action-setup@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
version: 9
- name: Get pnpm store directory
shell: sh
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache
uses: actions/cache@v4
with:
images: |
${{ env.DOCKER_HUB }}
ghcr.io/${{ github.repository }}
tags: |
type=raw,value=${{ env.VERSION }}
labels: |
org.opencontainers.image.created=${{ steps.ts.outputs.TIMESTAMP }}
- name: Build & Push (multi-arch)
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: true
build-args: |
COMMIT_TAG=${{ github.sha }}
BUILD_VERSION=${{ env.VERSION }}
SOURCE_DATE_EPOCH=${{ steps.ts.outputs.TIMESTAMP }}
labels: ${{ steps.meta.outputs.labels }}
tags: ${{ steps.meta.outputs.tags }}
cache-from: |
type=gha,scope=linux/amd64
type=gha,scope=linux/arm64
cache-to: type=gha,mode=max
provenance: false
- name: Resolve manifest digest
id: digests
run: |
DIGEST=$(docker buildx imagetools inspect "${{ env.DOCKER_HUB }}:${{ env.VERSION }}" --format '{{json .Manifest.Digest}}' | tr -d '"')
echo "IMAGE_DIGEST=$DIGEST" >> $GITHUB_OUTPUT
- name: Also tag :latest (non-pre-release only)
shell: bash
if: ${{ !contains(env.VERSION, '-') }}
run: |
docker buildx imagetools create \
-t ${{ env.DOCKER_HUB }}:latest \
${{ env.DOCKER_HUB }}:${{ env.VERSION }}
docker buildx imagetools create \
-t ghcr.io/${{ github.repository }}:latest \
ghcr.io/${{ github.repository }}:${{ env.VERSION }}
sign:
name: Sign images and create SBOM attestations
needs: publish
runs-on: ubuntu-24.04
permissions:
contents: read
id-token: write
packages: write
env:
VERSION: ${{ github.ref_name }}
COSIGN_YES: 'true'
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Install Cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
- name: Install Trivy
uses: aquasecurity/setup-trivy@e6c2c5e321ed9123bda567646e2f96565e34abe1 # v0.2.4
- name: Log in to Docker Hub
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Sign images
run: |
cosign sign --recursive "ghcr.io/${{ github.repository }}@${{ needs.publish.outputs.image_digest }}"
cosign sign --recursive "${{ env.DOCKER_HUB }}@${{ needs.publish.outputs.image_digest }}"
- name: Generate SBOMs
run: |
trivy image --format cyclonedx --output seerr-ghcr-image-${{ env.VERSION }}.sbom \
"ghcr.io/${{ github.repository }}@${{ needs.publish.outputs.image_digest }}"
trivy image --format cyclonedx --output seerr-dockerhub-image-${{ env.VERSION }}.sbom \
"${{ env.DOCKER_HUB }}@${{ needs.publish.outputs.image_digest }}"
- name: Attest SBOMs
run: |
cosign attest \
--type cyclonedx \
--predicate seerr-ghcr-image-${{ env.VERSION }}.sbom \
"ghcr.io/${{ github.repository }}@${{ needs.publish.outputs.image_digest }}"
cosign attest \
--type cyclonedx \
--predicate seerr-dockerhub-image-${{ env.VERSION }}.sbom \
"${{ env.DOCKER_HUB }}@${{ needs.publish.outputs.image_digest }}"
- name: Upload SBOMs
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: sboms-${{ env.VERSION }}
path: '*.sbom'
if-no-files-found: error
retention-days: 1
verify:
name: Verify signatures and attestations
needs: [publish, sign]
runs-on: ubuntu-24.04
permissions:
contents: read
env:
VERSION: ${{ github.ref_name }}
steps:
- name: Install Cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
- name: Verify signatures
run: |
cosign verify "ghcr.io/${{ github.repository }}@${{ needs.publish.outputs.image_digest }}" \
--certificate-identity "https://github.com/${{ github.workflow_ref }}" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
cosign verify "${{ env.DOCKER_HUB }}@${{ needs.publish.outputs.image_digest }}" \
--certificate-identity "https://github.com/${{ github.workflow_ref }}" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
- name: Verify attestations
run: |
cosign verify-attestation "ghcr.io/${{ github.repository }}@${{ needs.publish.outputs.image_digest }}" \
--type cyclonedx \
--certificate-identity "https://github.com/${{ github.workflow_ref }}" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" > /dev/null
cosign verify-attestation "${{ env.DOCKER_HUB }}@${{ needs.publish.outputs.image_digest }}" \
--type cyclonedx \
--certificate-identity "https://github.com/${{ github.workflow_ref }}" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" > /dev/null
publish-release:
name: Publish release
needs: [create-draft-release, verify]
runs-on: ubuntu-24.04
permissions:
contents: write
env:
VERSION: ${{ github.ref_name }}
steps:
- name: Publish release
run: gh release edit "${{ env.VERSION }}" --draft=false --repo "${{ github.repository }}"
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install
- name: Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
run: npx semantic-release
# build-snap:
# name: Build Snap Package (${{ matrix.architecture }})
# needs: semantic-release
# runs-on: ubuntu-22.04
# strategy:
# fail-fast: false
# matrix:
# architecture:
# - amd64
# - arm64
# steps:
# - name: Checkout Code
# uses: actions/checkout@v4
# with:
# fetch-depth: 0
# - name: Switch to main branch
# run: git checkout main
# - name: Pull latest changes
# run: git pull
# - name: Prepare
# id: prepare
# run: |
# git fetch --prune --tags
# if [[ $GITHUB_REF == refs/tags/* || $GITHUB_REF == refs/heads/master ]]; then
# echo "RELEASE=stable" >> $GITHUB_OUTPUT
# else
# echo "RELEASE=edge" >> $GITHUB_OUTPUT
# fi
# - name: Set Up QEMU
# uses: docker/setup-qemu-action@v3
# with:
# image: tonistiigi/binfmt@sha256:df15403e06a03c2f461c1f7938b171fda34a5849eb63a70e2a2109ed5a778bde
# - name: Build Snap Package
# uses: diddlesnaps/snapcraft-multiarch-action@v1
# id: build
# with:
# architecture: ${{ matrix.architecture }}
# - name: Upload Snap Package
# uses: actions/upload-artifact@v4
# with:
# name: jellyseerr-snap-package-${{ matrix.architecture }}
# path: ${{ steps.build.outputs.snap }}
# - name: Review Snap Package
# uses: diddlesnaps/snapcraft-review-tools-action@v1
# with:
# snap: ${{ steps.build.outputs.snap }}
# - name: Publish Snap Package
# uses: snapcore/action-publish@v1
# env:
# SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_LOGIN }}
# with:
# snap: ${{ steps.build.outputs.snap }}
# release: ${{ steps.prepare.outputs.RELEASE }}
discord:
name: Send Discord Notification
needs: publish-release
needs: semantic-release
if: always()
runs-on: ubuntu-24.04
runs-on: ubuntu-22.04
steps:
- name: Determine status
- name: Get Build Job Status
uses: technote-space/workflow-conclusion-action@v3
- name: Combine Job Status
id: status
run: |
case "${{ needs.publish-release.result }}" in
success) echo "status=Success" >> $GITHUB_OUTPUT; echo "colour=3066993" >> $GITHUB_OUTPUT ;;
failure) echo "status=Failure" >> $GITHUB_OUTPUT; echo "colour=15158332" >> $GITHUB_OUTPUT ;;
cancelled) echo "status=Cancelled" >> $GITHUB_OUTPUT; echo "colour=10181046" >> $GITHUB_OUTPUT ;;
*) echo "status=Skipped" >> $GITHUB_OUTPUT; echo "colour=9807270" >> $GITHUB_OUTPUT ;;
esac
- name: Send notification
run: |
WEBHOOK="${{ secrets.DISCORD_WEBHOOK }}"
PAYLOAD=$(cat <<EOF
{
"embeds": [{
"title": "${{ steps.status.outputs.status }}: ${{ github.workflow }}",
"color": ${{ steps.status.outputs.colour }},
"fields": [
{ "name": "Repository", "value": "[${{ github.repository }}](${{ github.server_url }}/${{ github.repository }})", "inline": true },
{ "name": "Ref", "value": "${{ github.ref }}", "inline": true },
{ "name": "Event", "value": "${{ github.event_name }}", "inline": true },
{ "name": "Triggered by", "value": "${{ github.actor }}", "inline": true },
{ "name": "Workflow", "value": "[${{ github.workflow }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})", "inline": true }
]
}]
}
EOF
)
curl -sS -H "Content-Type: application/json" -X POST -d "$PAYLOAD" "$WEBHOOK" || true
failures=(neutral, skipped, timed_out, action_required)
if [[ ${array[@]} =~ $WORKFLOW_CONCLUSION ]]; then
echo "status=failure" >> $GITHUB_OUTPUT
else
echo "status=$WORKFLOW_CONCLUSION" >> $GITHUB_OUTPUT
fi
- name: Post Status to Discord
uses: sarisia/actions-status-discord@v1
with:
webhook: ${{ secrets.DISCORD_WEBHOOK }}
status: ${{ steps.status.outputs.status }}
title: ${{ github.workflow }}
nofail: true

View File

@@ -1,181 +0,0 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Renovate Helm Hooks
on:
pull_request:
branches:
- develop
paths:
- 'charts/**'
permissions: {}
concurrency:
group: renovate-helm-hooks-${{ github.ref }}
cancel-in-progress: true
jobs:
renovate-post-run:
name: Renovate Bump Chart Version
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
if: github.actor == 'renovate[bot]'
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
id: app-token
with:
app-id: 2138788
private-key: ${{ secrets.APP_SEERR_HELM_PRIVATE_KEY }}
- name: Set up chart-testing
uses: helm/chart-testing-action@0d28d3144d3a25ea2cc349d6e59901c4ff469b3b # v2.7.0
- name: Run chart-testing (list-changed)
id: list-changed
run: |
changed="$(ct list-changed --target-branch ${TARGET_BRANCH})"
if [[ -n "$changed" ]]; then
echo "changed=true" >> "$GITHUB_OUTPUT"
echo "changed_list=${changed//$'\n'/ }" >> "$GITHUB_OUTPUT"
fi
env:
TARGET_BRANCH: ${{ github.event.repository.default_branch }}
- name: Bump chart version
if: steps.list-changed.outputs.changed == 'true'
env:
CHART: ${{ steps.list-changed.outputs.changed_list }}
run: |
if [[ ! -d "${CHART}" ]]; then
echo "${CHART} directory not found"
exit 0
fi
# Extract current appVersion and chart version from Chart.yaml
APP_VERSION=$(grep -e "^appVersion:" "$CHART/Chart.yaml" | cut -d ":" -f 2 | tr -d '[:space:]' | tr -d '"')
CHART_VERSION=$(grep -e "^version:" "$CHART/Chart.yaml" | cut -d ":" -f 2 | tr -d '[:space:]' | tr -d '"')
# Extract major, minor and patch versions of appVersion
APP_MAJOR_VERSION=$(printf '%s' "$APP_VERSION" | cut -d "." -f 1)
APP_MINOR_VERSION=$(printf '%s' "$APP_VERSION" | cut -d "." -f 2)
APP_PATCH_VERSION=$(printf '%s' "$APP_VERSION" | cut -d "." -f 3)
# Extract major, minor and patch versions of chart version
CHART_MAJOR_VERSION=$(printf '%s' "$CHART_VERSION" | cut -d "." -f 1)
CHART_MINOR_VERSION=$(printf '%s' "$CHART_VERSION" | cut -d "." -f 2)
CHART_PATCH_VERSION=$(printf '%s' "$CHART_VERSION" | cut -d "." -f 3)
# Get previous appVersion from the base commit of the pull request
BASE_COMMIT=$(git merge-base origin/main HEAD)
PREV_APP_VERSION=$(git show "$BASE_COMMIT":"$CHART/Chart.yaml" | grep -e "^appVersion:" | cut -d ":" -f 2 | tr -d '[:space:]' | tr -d '"')
# Extract major, minor and patch versions of previous appVersion
PREV_APP_MAJOR_VERSION=$(printf '%s' "$PREV_APP_VERSION" | cut -d "." -f 1)
PREV_APP_MINOR_VERSION=$(printf '%s' "$PREV_APP_VERSION" | cut -d "." -f 2)
PREV_APP_PATCH_VERSION=$(printf '%s' "$PREV_APP_VERSION" | cut -d "." -f 3)
# Check if the major, minor, or patch version of appVersion has changed
if [[ "$APP_MAJOR_VERSION" != "$PREV_APP_MAJOR_VERSION" ]]; then
# Bump major version of the chart and reset minor and patch versions to 0
CHART_MAJOR_VERSION=$((CHART_MAJOR_VERSION+1))
CHART_MINOR_VERSION=0
CHART_PATCH_VERSION=0
elif [[ "$APP_MINOR_VERSION" != "$PREV_APP_MINOR_VERSION" ]]; then
# Bump minor version of the chart and reset patch version to 0
CHART_MINOR_VERSION=$((CHART_MINOR_VERSION+1))
CHART_PATCH_VERSION=0
elif [[ "$APP_PATCH_VERSION" != "$PREV_APP_PATCH_VERSION" ]]; then
# Bump patch version of the chart
CHART_PATCH_VERSION=$((CHART_PATCH_VERSION+1))
fi
# Update the chart version in Chart.yaml
CHART_NEW_VERSION="${CHART_MAJOR_VERSION}.${CHART_MINOR_VERSION}.${CHART_PATCH_VERSION}"
sed -i "s/^version:.*/version: ${CHART_NEW_VERSION}/" "$CHART/Chart.yaml"
- name: Ensure documentation is updated
if: steps.list-changed.outputs.changed == 'true'
uses: docker://jnorwood/helm-docs:v1.14.2@sha256:7e562b49ab6b1dbc50c3da8f2dd6ffa8a5c6bba327b1c6335cc15ce29267979c
- name: Commit changes
if: steps.list-changed.outputs.changed == 'true'
env:
CHART: ${{ steps.list-changed.outputs.changed_list }}
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
GITHUB_HEAD_REF: ${{ github.head_ref }}
run: |
# Define the target directory
TARGET_DIR="$CHART"
# Fetch deleted files in the target directory
DELETED_FILES=$(git diff --diff-filter=D --name-only HEAD -- "$TARGET_DIR")
# Fetch added/modified files in the target directory
MODIFIED_FILES=$(git diff --diff-filter=ACM --name-only HEAD -- "$TARGET_DIR")
# Create a temporary file for JSON output
FILE_CHANGES_JSON_FILE=$(mktemp)
# Initialize JSON structure in the file
echo '{ "deletions": [], "additions": [] }' > "$FILE_CHANGES_JSON_FILE"
# Add deletions
for file in $DELETED_FILES; do
jq --arg path "$file" '.deletions += [{"path": $path}]' "$FILE_CHANGES_JSON_FILE" > "$FILE_CHANGES_JSON_FILE.tmp"
mv "$FILE_CHANGES_JSON_FILE.tmp" "$FILE_CHANGES_JSON_FILE"
done
# Add additions (new or modified files)
for file in $MODIFIED_FILES; do
BASE64_CONTENT=$(base64 -w 0 <"$file") # Encode file content
jq --arg path "$file" --arg content "$BASE64_CONTENT" \
'.additions += [{"path": $path, "contents": $content}]' "$FILE_CHANGES_JSON_FILE" > "$FILE_CHANGES_JSON_FILE.tmp"
mv "$FILE_CHANGES_JSON_FILE.tmp" "$FILE_CHANGES_JSON_FILE"
done
# Create a temporary file for the final JSON payload
JSON_PAYLOAD_FILE=$(mktemp)
# Construct the final JSON using jq and store it in a file
jq -n --arg repo "$GITHUB_REPOSITORY" \
--arg branch "$GITHUB_HEAD_REF" \
--arg message "fix: post upgrade changes from renovate" \
--arg expectedOid "$GITHUB_SHA" \
--slurpfile fileChanges "$FILE_CHANGES_JSON_FILE" \
'{
query: "mutation ($input: CreateCommitOnBranchInput!) {
createCommitOnBranch(input: $input) {
commit {
url
}
}
}",
variables: {
input: {
branch: {
repositoryNameWithOwner: $repo,
branchName: $branch
},
message: { headline: $message },
fileChanges: $fileChanges[0],
expectedHeadOid: $expectedOid
}
}
}' > "$JSON_PAYLOAD_FILE"
# Call GitHub API
curl https://api.github.com/graphql -f \
-sSf -H "Authorization: Bearer $GITHUB_TOKEN" \
--data "@$JSON_PAYLOAD_FILE"
# Clean up temporary files
rm "$FILE_CHANGES_JSON_FILE" "$JSON_PAYLOAD_FILE"

View File

@@ -1,111 +0,0 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: 'Seerr Labeller'
on:
pull_request_target:
types: [labeled, unlabeled, reopened]
issues:
types: [labeled, unlabeled, reopened]
permissions: {}
jobs:
ai-generated-support:
if: >
github.event_name == 'pull_request_target' &&
(github.event.label.name == 'ai-generated' || (github.event.action == 'reopened' && contains(github.event.pull_request.labels.*.name, 'ai-generated')))
runs-on: ubuntu-24.04
concurrency:
group: ai-generated-${{ github.event.pull_request.number }}
cancel-in-progress: true
permissions:
pull-requests: write
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.pull_request.number }}
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
steps:
- name: Label added, comment and close pull request
if: github.event.action == 'labeled' && github.event.label.name == 'ai-generated'
shell: bash
env:
BODY: >
:wave: @${{ env.PR_AUTHOR }}, thank you for your contribution!
However, this pull request has been closed because it appears to contain a significant amount of AI-generated code without sufficient human review or supervision.
AI-generated code can often introduce subtle bugs, poor design patterns, or inconsistent styles that make long-term maintenance difficult and reduce overall code quality. For the sake of the project's future stability and readability, we require that all contributions meet our established coding standards and demonstrate clear developer oversight.
This pull request is also too large for effective human review. Please discuss with us on how to break down these changes into smaller, more focused PRs to ensure a thorough and efficient review process.
If you'd like to revise and resubmit your changes with careful review and cleanup, we'd be happy to take another look.
run: |
retry() { n=0; until "$@"; do n=$((n+1)); [ $n -ge 3 ] && break; echo "retry $n: $*" >&2; sleep 2; done; }
retry gh pr comment "$NUMBER" -R "$GH_REPO" -b "$BODY" || true
retry gh pr close "$NUMBER" -R "$GH_REPO" || true
gh pr lock "$NUMBER" -R "$GH_REPO" -r "spam" || true
- name: Label removed, reopen and unlock pull request
if: github.event.action == 'unlabeled' && github.event.label.name == 'ai-generated'
shell: bash
run: |
retry() { n=0; until "$@"; do n=$((n+1)); [ $n -ge 3 ] && break; echo "retry $n: $*" >&2; sleep 2; done; }
retry gh pr reopen "$NUMBER" -R "$GH_REPO" || true
gh pr unlock "$NUMBER" -R "$GH_REPO" || true
- name: Remove AI-generated label on manual reopen
if: github.event.action == 'reopened'
shell: bash
run: |
gh pr edit "$NUMBER" -R "$GH_REPO" --remove-label "ai-generated" || true
gh pr unlock "$NUMBER" -R "$GH_REPO" || true
support:
if: >
github.event_name == 'issues' &&
(github.event.label.name == 'support' ||
(github.event.action == 'reopened' && contains(github.event.issue.labels.*.name, 'support')))
runs-on: ubuntu-24.04
concurrency:
group: support-${{ github.event.issue.number }}
cancel-in-progress: true
permissions:
issues: write
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.issue.number }}
ISSUE_AUTHOR: ${{ github.event.issue.user.login }}
steps:
- name: Label added, comment and close issue
if: github.event.action == 'labeled' && github.event.label.name == 'support'
shell: bash
env:
BODY: >
:wave: @${{ env.ISSUE_AUTHOR }}, we use the issue tracker exclusively
for bug reports and feature requests. However, this issue appears
to be a support request. Please use our support channels
to get help with Seerr.
- [Discord](https://discord.gg/seerr)
run: |
retry() { n=0; until "$@"; do n=$((n+1)); [ $n -ge 3 ] && break; echo "retry $n: $*" >&2; sleep 2; done; }
retry gh issue comment "$NUMBER" -R "$GH_REPO" -b "$BODY" || true
retry gh issue close "$NUMBER" -R "$GH_REPO" || true
gh issue lock "$NUMBER" -R "$GH_REPO" -r "off_topic" || true
- name: Label removed, reopen and unlock issue
if: github.event.action == 'unlabeled' && github.event.label.name == 'support'
shell: bash
run: |
retry() { n=0; until "$@"; do n=$((n+1)); [ $n -ge 3 ] && break; echo "retry $n: $*" >&2; sleep 2; done; }
retry gh issue reopen "$NUMBER" -R "$GH_REPO" || true
gh issue unlock "$NUMBER" -R "$GH_REPO" || true
- name: Remove support label on manual reopen
if: github.event.action == 'reopened'
shell: bash
run: |
gh issue edit "$NUMBER" -R "$GH_REPO" --remove-label "support" || true
gh issue unlock "$NUMBER" -R "$GH_REPO" || true

94
.github/workflows/snap.yaml vendored Normal file
View File

@@ -0,0 +1,94 @@
name: Publish Snap
# turn off edge snap builds temporarily and make it manual
# on:
# push:
# branches:
# - develop
on: workflow_dispatch
jobs:
jobs:
name: Job Check
runs-on: ubuntu-22.04
if: "!contains(github.event.head_commit.message, '[skip ci]')"
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.12.1
with:
access_token: ${{ secrets.GITHUB_TOKEN }}
build-snap:
name: Build Snap Package (${{ matrix.architecture }})
needs: jobs
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
architecture:
- amd64
- arm64
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Prepare
id: prepare
run: |
git fetch --prune --unshallow --tags
if [[ $GITHUB_REF == refs/tags/* || $GITHUB_REF == refs/heads/master ]]; then
echo "RELEASE=stable" >> $GITHUB_OUTPUT
else
echo "RELEASE=edge" >> $GITHUB_OUTPUT
fi
- name: Set Up QEMU
uses: docker/setup-qemu-action@v3
- name: Configure Git
run: git config --add safe.directory /data/parts/jellyseerr/src
- name: Build Snap Package
uses: diddlesnaps/snapcraft-multiarch-action@v1
id: build
with:
architecture: ${{ matrix.architecture }}
- name: Upload Snap Package
uses: actions/upload-artifact@v4
with:
name: jellyseerr-snap-package-${{ matrix.architecture }}
path: ${{ steps.build.outputs.snap }}
- name: Review Snap Package
uses: diddlesnaps/snapcraft-review-tools-action@v1
with:
snap: ${{ steps.build.outputs.snap }}
- name: Publish Snap Package
uses: snapcore/action-publish@v1
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_LOGIN }}
with:
snap: ${{ steps.build.outputs.snap }}
release: ${{ steps.prepare.outputs.RELEASE }}
discord:
name: Send Discord Notification
needs: build-snap
if: always() && !contains(github.event.head_commit.message, '[skip ci]')
runs-on: ubuntu-22.04
steps:
- name: Get Build Job Status
uses: technote-space/workflow-conclusion-action@v3
- name: Combine Job Status
id: status
run: |
failures=(neutral, skipped, timed_out, action_required)
if [[ ${array[@]} =~ $WORKFLOW_CONCLUSION ]]; then
echo "status=failure" >> $GITHUB_OUTPUT
else
echo "status=$WORKFLOW_CONCLUSION" >> $GITHUB_OUTPUT
fi
- name: Post Status to Discord
uses: sarisia/actions-status-discord@v1
with:
webhook: ${{ secrets.DISCORD_WEBHOOK }}
status: ${{ steps.status.outputs.status }}
title: ${{ github.workflow }}
nofail: true

View File

@@ -1,35 +0,0 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Close Stale Issues and PRs
on:
schedule:
- cron: '0 7 * * *'
permissions: {}
concurrency:
group: close-stale-${{ github.ref }}
cancel-in-progress: true
jobs:
stale:
name: Close stale issues and PRs
runs-on: ubuntu-24.04
permissions:
actions: write
issues: write
pull-requests: write
steps:
- uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0
with:
any-of-labels: "pending author's response"
exempt-issue-labels: 'confirmed'
days-before-stale: 30
days-before-close: 30
stale-issue-label: 'stale'
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Please provide an update or the requested information to keep it open.'
close-issue-message: 'This issue was closed because it has been stalled for 30 days with no activity. Feel free to reopen it once you provide the required update or information.'
stale-pr-label: 'stale'
stale-pr-message: 'This PR is stale because it has been open 30 days with no activity. Please address the feedback or provide an update to keep it open.'
close-pr-message: 'This PR was closed because it has been stalled for 30 days with no activity. You can reopen it once you address the feedback or provide the requested changes.'

25
.github/workflows/support.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: 'Support requests'
on:
issues:
types: [labeled, unlabeled, reopened]
jobs:
support:
runs-on: ubuntu-latest
steps:
- uses: dessant/support-requests@v4
with:
github-token: ${{ github.token }}
support-label: 'support'
issue-comment: >
:wave: @{issue-author}, we use the issue tracker exclusively
for bug reports and feature requests. However, this issue appears
to be a support request. Please use our support channels
to get help with Jellyseerr.
- [Discord](https://discord.gg/ckbvBtDJgC)
close-issue: true
lock-issue: true
issue-lock-reason: 'off-topic'

View File

@@ -1,42 +1,31 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Test Docs deployment
on:
pull_request:
branches:
- develop
paths:
path:
- 'docs/**'
- 'gen-docs/**'
permissions:
contents: read
concurrency:
group: docs-pr-${{ github.ref }}
cancel-in-progress: true
jobs:
test-deploy:
name: Test deployment
runs-on: ubuntu-24.04
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Set up Node.js
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
uses: actions/setup-node@v4
with:
node-version-file: package.json
package-manager-cache: false
node-version: 20
- name: Pnpm Setup
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
uses: pnpm/action-setup@v4
with:
version: 9
- name: Get pnpm store directory
shell: sh
@@ -44,7 +33,7 @@ jobs:
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
@@ -53,7 +42,7 @@ jobs:
- name: Install dependencies
run: |
cd gen-docs
cd gen-docs
pnpm install --frozen-lockfile
- name: Build website

View File

@@ -1,61 +0,0 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Trivy Container Vulnerability Scan
on:
workflow_run:
workflows:
- Seerr Release
types:
- completed
schedule:
- cron: '50 7 * * 5'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: trivy-scan-${{ github.ref }}
cancel-in-progress: true
jobs:
trivy:
if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
name: Scan latest container image
runs-on: ubuntu-24.04
permissions:
contents: read
security-events: write
env:
TRIVY_CACHE_DIR: .trivycache
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
persist-credentials: false
- name: Cache Trivy DB
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: .trivycache
key: trivy-${{ runner.os }}-${{ hashFiles('**/Dockerfile') }}
restore-keys: |
trivy-${{ runner.os }}-
- name: Run Trivy image scan
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # 0.33.1
with:
image-ref: ghcr.io/${{ github.repository }}:latest
format: sarif
output: trivy.sarif
ignore-unfixed: true
- name: Upload SARIF to code scanning
uses: github/codeql-action/upload-sarif@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7
with:
sarif_file: trivy.sarif

4
.gitignore vendored
View File

@@ -34,7 +34,6 @@ yarn-error.log*
# database
config/db/*.sqlite3*
config/settings.json
config/settings.old.json
# logs
config/logs/*.log*
@@ -71,6 +70,3 @@ tsconfig.tsbuildinfo
# Config Cache Directory
config/cache
# Docker compose
compose.override.yaml

View File

@@ -2,17 +2,10 @@
.next/
dist/
config/
CHANGELOG.md
pnpm-lock.yaml
cypress/config/settings.cypress.json
# assets
src/assets/
public/
!public/sw.js
docs/
!/public/
/public/*
!/public/sw.js
# helm charts
**/charts

View File

@@ -15,17 +15,5 @@ module.exports = {
rangeEnd: 0, // default: Infinity
},
},
{
files: 'charts/**',
options: {
rangeEnd: 0, // default: Infinity
},
},
{
files: 'cypress/config/settings.cypress.json',
options: {
rangeEnd: 0,
},
},
],
};

9
.stoplight.json Normal file
View File

@@ -0,0 +1,9 @@
{
"formats": {
"openapi": {
"rootDir": ".",
"include": ["**"]
}
},
"exclude": ["docs"]
}

View File

@@ -19,9 +19,5 @@
"typescript.preferences.importModuleSpecifier": "non-relative",
"files.associations": {
"globals.css": "tailwindcss"
},
"i18n-ally.localesPaths": [
"src/i18n/locale"
],
"yaml.format.singleQuote": true
}
}

1216
CHANGELOG.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,53 +1,14 @@
# Contributing to Seerr
# Contributing to Jellyseerr
All help is welcome and greatly appreciated! If you would like to contribute to the project, the following instructions should get you started...
## AI Assistance Notice
> [!IMPORTANT]
>
> If you are using **any kind of AI assistance** to contribute to Seerr,
> it must be disclosed in the pull request.
If you are using any kind of AI assistance while contributing to Seerr,
**this must be disclosed in the pull request**, along with the extent to
which AI assistance was used (e.g. docs only vs. code generation).
If PR responses are being generated by an AI, disclose that as well.
As a small exception, trivial tab-completion doesn't need to be disclosed,
so long as it is limited to single keywords or short phrases.
An example disclosure:
> This PR was written primarily by Claude Code.
Or a more detailed disclosure:
> I consulted ChatGPT to understand the codebase but the solution
> was fully authored manually by myself.
Failure to disclose this is first and foremost rude to the human operators
on the other end of the pull request, but it also makes it difficult to
determine how much scrutiny to apply to the contribution.
In a perfect world, AI assistance would produce equal or higher quality
work than any human. That isn't the world we live in today, and in most cases
it's generating slop. I say this despite being a fan of and using them
successfully myself (with heavy supervision)!
When using AI assistance, we expect contributors to understand the code
that is produced and be able to answer critical questions about it. It
isn't a maintainers job to review a PR so broken that it requires
significant rework to be acceptable.
Please be respectful to maintainers and disclose AI assistance.
## Development
### Tools Required
- HTML/Typescript/Javascript editor
- [VSCode](https://code.visualstudio.com/) is recommended. Upon opening the project, a few extensions will be automatically recommended for install.
- [NodeJS](https://nodejs.org/en/download/) (Node 22.x)
- [NodeJS](https://nodejs.org/en/download/) (Node 20.x)
- [Pnpm](https://pnpm.io/cli/install)
- [Git](https://git-scm.com/downloads)
@@ -56,14 +17,14 @@ Please be respectful to maintainers and disclose AI assistance.
1. [Fork](https://help.github.com/articles/fork-a-repo/) the repository to your own GitHub account and [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device:
```bash
git clone https://github.com/YOUR_USERNAME/seerr.git
cd seerr/
git clone https://github.com/YOUR_USERNAME/jellyseerr.git
cd jellyseerr/
```
2. Add the remote `upstream`:
```bash
git remote add upstream https://github.com/seerr-team/seerr.git
git remote add upstream https://github.com/fallenbagel/jellyseerr.git
```
3. Create a new branch:
@@ -87,40 +48,25 @@ Please be respectful to maintainers and disclose AI assistance.
4. Run the development environment:
```bash
pnpm install
pnpm
pnpm dev
```
- Alternatively, you can use [Docker](https://www.docker.com/) with `docker compose up -d`. This method does not require installing NodeJS or Yarn on your machine directly.
- Alternatively, you can use [Docker](https://www.docker.com/) with `docker-compose up -d`. This method does not require installing NodeJS or Yarn on your machine directly.
5. Create your patch and test your changes.
- Be sure to follow both the [code](#contributing-code) and [UI text](#ui-text-style) guidelines.
- Should you need to update your fork, you can do so by rebasing from `upstream`:
```bash
git fetch upstream
git rebase upstream/develop
git push origin BRANCH_NAME -f
```
### Helm Chart
Tools Required:
- [Helm](https://helm.sh/docs/intro/install/)
- [helm-docs](https://github.com/norwoodj/helm-docs)
Steps:
1. Make the necessary changes.
2. Test your changes.
3. Update the `version` in `charts/seerr-chart/Chart.yaml` following [Semantic Versioning (SemVer)](https://semver.org/).
4. Run the `helm-docs` command to regenerate the chart's README.
### Contributing Code
- If you are taking on an existing bug or feature ticket, please comment on the [issue](/../../issues) to avoid multiple people working on the same thing.
- If you are taking on an existing bug or feature ticket, please comment on the [issue](https://github.com/fallenbagel/jellyseerr/issues) to avoid multiple people working on the same thing.
- All commits **must** follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
- Pull requests with commits not following this standard will **not** be merged.
- Please make meaningful commits, or squash them prior to opening a pull request.
@@ -130,7 +76,7 @@ Steps:
- You can create a "draft" pull request early to get feedback on your work.
- Your code **must** be formatted correctly, or the tests will fail.
- We use Prettier to format our code base. It should automatically run with a Git hook, but it is recommended to have the Prettier extension installed in your editor and format on save.
- If you have questions or need help, you can reach out via [Discussions](/../../discussions) or our [Discord server](https://discord.gg/seerr).
- If you have questions or need help, you can reach out via [Discussions](https://github.com/fallenbagel/jellyseerr/discussions) or our [Discord server](https://discord.gg/ckbvBtDJgC).
- Only open pull requests to `develop`, never `master`! Any pull requests opened to `master` will be closed.
### UI Text Style
@@ -147,54 +93,14 @@ When adding new UI text, please try to adhere to the following guidelines:
8. If an additional description or "tip" is required for a form field, it should be styled using the global CSS class `label-tip`.
9. In full sentences, abbreviations like "info" or "auto" should not be used in place of full words, unless referencing the name/label of a specific setting or option which has an abbreviation in its name.
10. Do your best to check for spelling errors and grammatical mistakes.
11. Do not misspell "Seerr."
11. Do not misspell "Jellyseerr."
## Translation
We use [Weblate](https://translate.seerr.dev/projects/seerr/seerr-frontend/) for our translations, and your help with localizing Seerr would be greatly appreciated! If your language is not listed below, please [open a feature request](/../../issues/new/choose).
We use [Weblate](https://jellyseerr.borgcube.de/projects/jellyseerr/jellyseerr-frontend/) for our translations, and your help with localizing Overseerr would be greatly appreciated! If your language is not listed below, please [open a feature request](https://github.com/fallenbagel/jellyseerr/issues/new/choose).
<a href="https://translate.seerr.dev/engage/seerr/"><img src="https://translate.seerr.dev/widget/seerr/multi-auto.svg" alt="Translation status" /></a>
## Migrations
If you are adding a new feature that requires a database migration, you will need to create 2 migrations: one for SQLite and one for PostgreSQL. Here is how you could do it:
1. Create a PostgreSQL database or use an existing one:
```bash
sudo docker run --name postgres-seerr -e POSTGRES_PASSWORD=postgres -d -p 127.0.0.1:5432:5432/tcp postgres:latest
```
2. Reset the SQLite database and the PostgreSQL database:
```bash
rm config/db/db.*
rm config/settings.*
PGPASSWORD=postgres sudo docker exec -it postgres-seerr /usr/bin/psql -h 127.0.0.1 -U postgres -c "DROP DATABASE IF EXISTS seerr;"
PGPASSWORD=postgres sudo docker exec -it postgres-seerr /usr/bin/psql -h 127.0.0.1 -U postgres -c "CREATE DATABASE seerr;"
```
3. Checkout the `develop` branch and create the original database for SQLite and PostgreSQL so that TypeORM can automatically generate the migrations:
```bash
git checkout develop
pnpm i
rm -r .next dist; pnpm build
pnpm start
DB_TYPE="postgres" DB_USER=postgres DB_PASS=postgres pnpm start
```
(You can shutdown the server once the message "Server ready on 5055" appears)
4. Let TypeORM generate the migrations:
```bash
git checkout -b your-feature-branch
pnpm i
pnpm migration:generate server/migration/sqlite/YourMigrationName
DB_TYPE="postgres" DB_USER=postgres DB_PASS=postgres pnpm migration:generate server/migration/postgres/YourMigrationName
```
<a href="https://jellyseerr.borgcube.de/engage/jellysseerr/"><img src="https://jellyseerr.borgcube.de/widget/jellyseerr/multi-auto.svg" alt="Translation status" /></a>
## Attribution
This contribution guide was inspired by the [Next.js](https://github.com/vercel/next.js), [Radarr](https://github.com/Radarr/Radarr), and [Ghostty](https://github.com/ghostty-org/ghostty) contribution guides.
This contribution guide was inspired by the [Next.js](https://github.com/vercel/next.js), [Radarr](https://github.com/Radarr/Radarr), and [Overseerr](https://github.com/sct/Overseerr) contribution guides.

View File

@@ -1,22 +1,9 @@
FROM node:22.20.0-alpine3.22@sha256:cb3143549582cc5f74f26f0992cdef4a422b22128cb517f94173a5f910fa4ee7 AS base
ARG SOURCE_DATE_EPOCH
ARG TARGETPLATFORM
ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64}
FROM node:20-alpine AS BUILD_IMAGE
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
COPY . ./app
WORKDIR /app
FROM base AS prod-deps
RUN --mount=type=cache,id=pnpm,target=/pnpm/store CI=true pnpm install --prod --frozen-lockfile
FROM base AS build
ARG COMMIT_TAG
ENV COMMIT_TAG=${COMMIT_TAG}
ARG TARGETPLATFORM
ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64}
RUN \
case "${TARGETPLATFORM}" in \
@@ -27,32 +14,43 @@ RUN \
;; \
esac
RUN --mount=type=cache,id=pnpm,target=/pnpm/store CYPRESS_INSTALL_BINARY=0 pnpm install --frozen-lockfile
RUN npm install --global pnpm
COPY package.json pnpm-lock.yaml postinstall-win.js ./
RUN CYPRESS_INSTALL_BINARY=0 pnpm install --frozen-lockfile
COPY . ./
ARG COMMIT_TAG
ENV COMMIT_TAG=${COMMIT_TAG}
RUN pnpm build
RUN rm -rf .next/cache
# remove development dependencies
RUN pnpm prune --prod --ignore-scripts
FROM node:22.20.0-alpine3.22@sha256:cb3143549582cc5f74f26f0992cdef4a422b22128cb517f94173a5f910fa4ee7
ARG SOURCE_DATE_EPOCH
ARG COMMIT_TAG
ENV NODE_ENV=production
ENV COMMIT_TAG=${COMMIT_TAG}
RUN rm -rf src server .next/cache
RUN apk add --no-cache tzdata
RUN touch config/DOCKER
USER node:node
RUN echo "{\"commitTag\": \"${COMMIT_TAG}\"}" > committag.json
FROM node:20-alpine
# Metadata for Github Package Registry
LABEL org.opencontainers.image.source="https://github.com/Fallenbagel/jellyseerr"
WORKDIR /app
COPY --chown=node:node . .
COPY --chown=node:node --from=prod-deps /app/node_modules ./node_modules
COPY --chown=node:node --from=build /app/.next ./.next
COPY --chown=node:node --from=build /app/dist ./dist
RUN apk add --no-cache tzdata tini && rm -rf /tmp/*
RUN touch config/DOCKER && \
echo "{\"commitTag\": \"${COMMIT_TAG}\"}" > committag.json
RUN npm install -g pnpm
# copy from build image
COPY --from=BUILD_IMAGE /app ./
ENTRYPOINT [ "/sbin/tini", "--" ]
CMD [ "pnpm", "start" ]
EXPOSE 5055
CMD [ "npm", "start" ]

View File

@@ -1,12 +1,10 @@
FROM node:22.20.0-alpine3.22@sha256:cb3143549582cc5f74f26f0992cdef4a422b22128cb517f94173a5f910fa4ee7
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
FROM node:20-alpine
COPY . /app
WORKDIR /app
Run npm install --global pnpm
RUN pnpm install
CMD pnpm dev

286
README.md
View File

@@ -1,40 +1,52 @@
<div align="center">⚠️ <strong>NOTE:</strong> We are currently in the process of merging Overseerr and Jellyseerr into this unified repository.</div>
<h1 align="center" style="font-size: 4em;">🚧 Seerr</h1>
<p align="center">
<img src="https://github.com/seerr-team/seerr/actions/workflows/release.yml/badge.svg" alt="Seerr Release" />
<img src="https://github.com/seerr-team/seerr/actions/workflows/ci.yml/badge.svg" alt="Seerr CI">
<img src="./public/logo_full.svg" alt="Jellyseerr" style="margin: 20px 0;">
</p>
<p align="center">
<a href="https://discord.gg/seerr"><img src="https://img.shields.io/discord/783137440809746482" alt="Discord"></a>
<a href="https://hub.docker.com/r/seerr/seerr"><img src="https://img.shields.io/docker/pulls/seerr/seerr" alt="Docker pulls"></a>
<a href="https://translate.seerr.dev/engage/seerr/"><img src="https://translate.seerr.dev/widget/seerr/seerr-frontend/svg-badge.svg" alt="Translation status" /></a>
<a href="https://github.com/seerr-team/seerr/blob/develop/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/seerr-team/seerr"></a>
<img src="https://github.com/Fallenbagel/jellyseerr/actions/workflows/release.yml/badge.svg" alt="Jellyseerr Release" />
<img src="https://github.com/Fallenbagel/jellyseerr/actions/workflows/ci.yml/badge.svg" alt="Jellyseerr CI">
</p>
<p align="center">
<a href="https://discord.gg/ckbvBtDJgC"><img src="https://img.shields.io/discord/952656177924300932" alt="Discord"></a>
<a href="https://hub.docker.com/r/fallenbagel/jellyseerr"><img src="https://img.shields.io/docker/pulls/fallenbagel/jellyseerr" alt="Docker pulls"></a>
<a href="http://translate.jellyseerr.dev/engage/jellyseerr/"><img src="http://translate.jellyseerr.dev/widget/jellyseerr/jellyseerr-frontend/svg-badge.svg" alt="Translation status" /></a>
<a href="https://github.com/fallenbagel/jellyseerr/blob/develop/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/fallenbagel/jellyseerr"></a>
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
<a href="#contributors-"><img alt="All Contributors" src="https://img.shields.io/badge/all_contributors-47-orange.svg"/></a>
<!-- ALL-CONTRIBUTORS-BADGE:END -->
**Seerr** is a free and open source software application for managing requests for your media library. It integrates with the media server of your choice: [Jellyfin](https://jellyfin.org), [Plex](https://plex.tv), and [Emby](https://emby.media/). In addition, it integrates with your existing services, such as **[Sonarr](https://sonarr.tv/)**, **[Radarr](https://radarr.video/)**.
**Jellyseerr** is a free and open source software application for managing requests for your media library.
It is a fork of [Overseerr](https://github.com/sct/overseerr) built to bring support for [Jellyfin](https://github.com/jellyfin/jellyfin) & [Emby](https://github.com/MediaBrowser/Emby) media servers!
## Current Features
- Full Jellyfin/Emby/Plex integration including authentication with user import & management.
- Support for **PostgreSQL** and **SQLite** databases.
- Supports Movies, Shows and Mixed Libraries.
- Ability to change email addresses for SMTP purposes.
- Easy integration with your existing services. Currently, Seerr supports Sonarr and Radarr. More to come!
- Full Jellyfin/Emby/Plex integration including authentication with user import & management
- Supports Movies, Shows and Mixed Libraries
- Ability to change email addresses for smtp purposes
- Easy integration with your existing services. Currently, Jellyseerr supports Sonarr and Radarr. More to come!
- Jellyfin/Emby/Plex library scan, to keep track of the titles which are already available.
- Customizable request system, which allows users to request individual seasons or movies in a friendly, easy-to-use interface.
- Incredibly simple request management UI. Don't dig through the app to simply approve recent requests!
- Granular permission system.
- Support for various notification agents.
- Mobile-friendly design, for when you need to approve requests on the go!
- Support for watchlisting & blacklisting media.
With more features on the way! Check out our [issue tracker](/../../issues) to see the features which have already been requested.
(Upcoming Features include: Multiple Server Instances, and much more!)
With more features on the way! Check out our [issue tracker](https://github.com/fallenbagel/jellyseerr/issues) to see the features which have already been requested.
## Getting Started
Check out our documentation for instructions on how to install and run Seerr:
Check out our documentation for instructions on how to install and run Jellyseerr:
https://docs.seerr.dev/getting-started/
https://docs.jellyseerr.dev/getting-started/
### Packages:
Archlinux: [AUR](https://aur.archlinux.org/packages/jellyseerr)
Nix: [Nixpkg](https://search.nixos.org/packages?channel=unstable&show=jellyseerr)
~Snap: [Snap](https://snapcraft.io/jellyseerr)~(Deprecated)
## Preview
@@ -42,30 +54,242 @@ https://docs.seerr.dev/getting-started/
## Support
- Check out the [Seerr Documentation](https://docs.seerr.dev) before asking for help. Your question might already be in the docs!
- You can get support on [Discord](https://discord.gg/seerr).
- You can ask questions in the Help category of our [GitHub Discussions](/../../discussions).
- Bug reports and feature requests can be submitted via [GitHub Issues](/../../issues).
- Check out the [Jellyseerr Documentation](https://docs.jellyseerr.dev) before asking for help. Your question might already be in the docs!
- You can get support on [Discord](https://discord.gg/ckbvBtDJgC).
- You can ask questions in the Help category of our [GitHub Discussions](https://github.com/fallenbagel/jellyseerr/discussions).
- Bug reports and feature requests can be submitted via [GitHub Issues](https://github.com/fallenbagel/jellyseerr/issues).
## API Documentation
You can access the API documentation from your local Seerr install at http://localhost:5055/api-docs
You can access the API documentation from your local Jellyseerr install at http://localhost:5055/api-docs
## Community
You can ask questions, share ideas, and more in [GitHub Discussions](/../../discussions).
You can ask questions, share ideas, and more in [GitHub Discussions](https://github.com/fallenbagel/jellyseerr/discussions).
If you would like to chat with other members of our growing community, [join the Seerr Discord server](https://discord.gg/seerr)!
If you would like to chat with other members of our growing community, [join the Jellyseerr Discord server](https://discord.gg/ckbvBtDJgC)!
Our [Code of Conduct](./CODE_OF_CONDUCT.md) applies to all Seerr community channels.
Our [Code of Conduct](https://github.com/fallenbagel/jellyseerr/blob/develop/CODE_OF_CONDUCT.md) applies to all Jellyseerr community channels.
## Contributing
You can help improve Seerr too! Check out our [Contribution Guide](./CONTRIBUTING.md) to get started.
You can help improve Jellyseerr too! Check out our [Contribution Guide](https://github.com/fallenbagel/jellyseerr/blob/develop/CONTRIBUTING.md) to get started.
## Contributors ✨
[![Contributors](https://opencollective.com/seerr/contributors.svg?width=890)](https://opencollective.com/seerr/#backers)
Thanks goes to these wonderful people from Overseerr ([emoji key](https://allcontributors.org/docs/en/emoji-key)) and all those that contributed directly to Jellyseerr:
[![Become a Backer](https://opencollective.com/seerr/backers.svg)](https://opencollective.com/seerr/#backers)
[![Become a Sponsor](https://opencollective.com/seerr/sponsors.svg)](https://opencollective.com/seerr/#sponsors)
### Jellyseerr Contributors ✨
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Fallenbagel"><img src="https://avatars.githubusercontent.com/u/98979876?v=4?s=100" width="100px;" alt="Fallenbagel"/><br /><sub><b>Fallenbagel</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=Fallenbagel" title="Code">💻</a> <a href="#maintenance-Fallenbagel" title="Maintenance">🚧</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/seanzhang98"><img src="https://avatars.githubusercontent.com/u/34902361?v=4?s=100" width="100px;" alt="Sean"/><br /><sub><b>Sean</b></sub></a><br /><a href="#translation-seanzhang98" title="Translation">🌍</a> <a href="https://github.com/Fallenbagel/jellyseerr/commits?author=seanzhang98" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/notfakie"><img src="https://avatars.githubusercontent.com/u/103784113?v=4?s=100" width="100px;" alt="notfakie"/><br /><sub><b>notfakie</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=notfakie" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Jumail"><img src="https://avatars.githubusercontent.com/u/7672055?v=4?s=100" width="100px;" alt="Mohamed Jumail"/><br /><sub><b>Mohamed Jumail</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/pulls?q=is%3Apr+reviewed-by%3AJumail" title="Reviewed Pull Requests">👀</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.heywhale.com"><img src="https://avatars.githubusercontent.com/u/4048787?v=4?s=100" width="100px;" alt="Shilong Jiang"/><br /><sub><b>Shilong Jiang</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=jsl9208" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://jinas.me"><img src="https://avatars.githubusercontent.com/u/28459081?v=4?s=100" width="100px;" alt="Boring Dragon"/><br /><sub><b>Boring Dragon</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=boring-dragon" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sambartik"><img src="https://avatars.githubusercontent.com/u/63553146?v=4?s=100" width="100px;" alt="Samuel Bartík"/><br /><sub><b>Samuel Bartík</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=sambartik" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CyferShepard"><img src="https://avatars.githubusercontent.com/u/24864904?v=4?s=100" width="100px;" alt="Thegan Govender"/><br /><sub><b>Thegan Govender</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=CyferShepard" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jab416171"><img src="https://avatars.githubusercontent.com/u/345752?v=4?s=100" width="100px;" alt="jab416171"/><br /><sub><b>jab416171</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=jab416171" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://nvds.be"><img src="https://avatars.githubusercontent.com/u/5257222?v=4?s=100" width="100px;" alt="Nicolai Van der Storm"/><br /><sub><b>Nicolai Van der Storm</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=NicolaiVdS" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Smexhy"><img src="https://avatars.githubusercontent.com/u/4880625?v=4?s=100" width="100px;" alt="Smexhy"/><br /><sub><b>Smexhy</b></sub></a><br /><a href="#translation-Smexhy" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://dd06-dev.fr"><img src="https://avatars.githubusercontent.com/u/58089504?v=4?s=100" width="100px;" alt="dd060606"/><br /><sub><b>dd060606</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=dd060606" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://qwer.tz"><img src="https://avatars.githubusercontent.com/u/71837281?v=4?s=100" width="100px;" alt="Daniel"/><br /><sub><b>Daniel</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=darmiel" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/undone37"><img src="https://avatars.githubusercontent.com/u/10513808?v=4?s=100" width="100px;" alt="undone37"/><br /><sub><b>undone37</b></sub></a><br /><a href="#translation-undone37" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CheChu10"><img src="https://avatars.githubusercontent.com/u/32913133?v=4?s=100" width="100px;" alt="Chechu García"/><br /><sub><b>Chechu García</b></sub></a><br /><a href="#translation-CheChu10" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DimitriDR"><img src="https://avatars.githubusercontent.com/u/56969769?v=4?s=100" width="100px;" alt="Dimitri"/><br /><sub><b>Dimitri</b></sub></a><br /><a href="#translation-DimitriDR" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/andrey4korop"><img src="https://avatars.githubusercontent.com/u/24610708?v=4?s=100" width="100px;" alt="andrey4korop"/><br /><sub><b>andrey4korop</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=andrey4korop" title="Code">💻</a> <a href="#translation-andrey4korop" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://geoffrey-coulaud.fr"><img src="https://avatars.githubusercontent.com/u/20744730?v=4?s=100" width="100px;" alt="Geoffrey Coulaud"/><br /><sub><b>Geoffrey Coulaud</b></sub></a><br /><a href="#translation-GeoffreyCoulaud" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Pikachu920"><img src="https://avatars.githubusercontent.com/u/28607612?v=4?s=100" width="100px;" alt="Pikachu920"/><br /><sub><b>Pikachu920</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=Pikachu920" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yalagin"><img src="https://avatars.githubusercontent.com/u/12879142?v=4?s=100" width="100px;" alt="Maxim Yalagin"/><br /><sub><b>Maxim Yalagin</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=yalagin" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jeaboswell"><img src="https://avatars.githubusercontent.com/u/11653068?v=4?s=100" width="100px;" alt="Jesse Boswell"/><br /><sub><b>Jesse Boswell</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=jeaboswell" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/d-fendrich"><img src="https://avatars.githubusercontent.com/u/27904138?v=4?s=100" width="100px;" alt="d-fendrich"/><br /><sub><b>d-fendrich</b></sub></a><br /><a href="#translation-d-fendrich" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/davidfdezalcoba"><img src="https://avatars.githubusercontent.com/u/15996018?v=4?s=100" width="100px;" alt="David Fernández Alcoba"/><br /><sub><b>David Fernández Alcoba</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=davidfdezalcoba" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Gauvino"><img src="https://avatars.githubusercontent.com/u/68083474?v=4?s=100" width="100px;" alt="Gauvino"/><br /><sub><b>Gauvino</b></sub></a><br /><a href="#translation-Gauvino" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/EthanArmbrust"><img src="https://avatars.githubusercontent.com/u/22754714?v=4?s=100" width="100px;" alt="EthanArmbrust"/><br /><sub><b>EthanArmbrust</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=EthanArmbrust" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.piribisoft.com"><img src="https://avatars.githubusercontent.com/u/854646?v=4?s=100" width="100px;" alt="Eduardo"/><br /><sub><b>Eduardo</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=SirMartin" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/RickLuiken"><img src="https://avatars.githubusercontent.com/u/34110371?v=4?s=100" width="100px;" alt="RickLuiken"/><br /><sub><b>RickLuiken</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=RickLuiken" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Br33ce"><img src="https://avatars.githubusercontent.com/u/124933490?v=4?s=100" width="100px;" alt="Br33ce"/><br /><sub><b>Br33ce</b></sub></a><br /><a href="#translation-Br33ce" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://athfan.com"><img src="https://avatars.githubusercontent.com/u/13810742?v=4?s=100" width="100px;" alt="Athfan Khaleel"/><br /><sub><b>Athfan Khaleel</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=athphane" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mdll23"><img src="https://avatars.githubusercontent.com/u/142844478?v=4?s=100" width="100px;" alt="Michael Dallinger"/><br /><sub><b>Michael Dallinger</b></sub></a><br /><a href="#translation-mdll23" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xeruf"><img src="https://avatars.githubusercontent.com/u/13354331?v=4?s=100" width="100px;" alt="Janek"/><br /><sub><b>Janek</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=xeruf" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://aleksasiriski.dev"><img src="https://avatars.githubusercontent.com/u/31509435?v=4?s=100" width="100px;" alt="Aleksa Siriški"/><br /><sub><b>Aleksa Siriški</b></sub></a><br /><a href="#infra-aleksasiriski" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://danishhumair.com"><img src="https://avatars.githubusercontent.com/u/121830048?v=4?s=100" width="100px;" alt="Danish Humair"/><br /><sub><b>Danish Humair</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=Danish-H" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://arm0.red"><img src="https://avatars.githubusercontent.com/u/16858514?v=4?s=100" width="100px;" alt="Stephen Harris"/><br /><sub><b>Stephen Harris</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=trackmastersteve" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.boniface.me"><img src="https://avatars.githubusercontent.com/u/4031396?v=4?s=100" width="100px;" alt="Joshua M. Boniface"/><br /><sub><b>Joshua M. Boniface</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=joshuaboniface" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://gauthierth.fr/"><img src="https://avatars.githubusercontent.com/u/37781713?v=4?s=100" width="100px;" alt="Gauthier"/><br /><sub><b>Gauthier</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=gauthier-th" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Kara-Zor-El"><img src="https://avatars.githubusercontent.com/u/69772087?v=4?s=100" width="100px;" alt="Kara"/><br /><sub><b>Kara</b></sub></a><br /><a href="#infra-Kara-Zor-El" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://joaquinolivero.com"><img src="https://avatars.githubusercontent.com/u/66050823?v=4?s=100" width="100px;" alt="Joaquin Olivero"/><br /><sub><b>Joaquin Olivero</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=JoaquinOlivero" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Bretterteig"><img src="https://avatars.githubusercontent.com/u/47298401?v=4?s=100" width="100px;" alt="Julian Behr"/><br /><sub><b>Julian Behr</b></sub></a><br /><a href="#translation-Bretterteig" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ThowZzy"><img src="https://avatars.githubusercontent.com/u/61882536?v=4?s=100" width="100px;" alt="ThowZzy"/><br /><sub><b>ThowZzy</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=ThowZzy" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://josephrisk.com"><img src="https://avatars.githubusercontent.com/u/18372584?v=4?s=100" width="100px;" alt="Joseph Risk"/><br /><sub><b>Joseph Risk</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=j0srisk" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Loetwiek"><img src="https://avatars.githubusercontent.com/u/79059734?v=4?s=100" width="100px;" alt="Loetwiek"/><br /><sub><b>Loetwiek</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=Loetwiek" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Fuochi"><img src="https://avatars.githubusercontent.com/u/4720478?v=4?s=100" width="100px;" alt="Fuochi"/><br /><sub><b>Fuochi</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=Fuochi" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://mobihen.com"><img src="https://avatars.githubusercontent.com/u/35529491?v=4?s=100" width="100px;" alt="Nir Israel Hen"/><br /><sub><b>Nir Israel Hen</b></sub></a><br /><a href="#translation-mobihen" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/XDark187"><img src="https://avatars.githubusercontent.com/u/39034192?v=4?s=100" width="100px;" alt="Baraa"/><br /><sub><b>Baraa</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=XDark187" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/franciscofsales"><img src="https://avatars.githubusercontent.com/u/7977645?v=4?s=100" width="100px;" alt="Francisco Sales"/><br /><sub><b>Francisco Sales</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=franciscofsales" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/myselfolli"><img src="https://avatars.githubusercontent.com/u/37535998?v=4?s=100" width="100px;" alt="Oliver Laing"/><br /><sub><b>Oliver Laing</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=myselfolli" title="Code">💻</a></td>
</tr>
</tbody>
</table>
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
### Overseerr Contributors ✨
<table>
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://sct.dev"><img src="https://avatars1.githubusercontent.com/u/234213?v=4?s=100" width="100px;" alt="sct"/><br /><sub><b>sct</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=sct" title="Code">💻</a> <a href="#design-sct" title="Design">🎨</a> <a href="#ideas-sct" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/azoitos"><img src="https://avatars2.githubusercontent.com/u/26529049?v=4?s=100" width="100px;" alt="Alex Zoitos"/><br /><sub><b>Alex Zoitos</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=azoitos" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/OwsleyJr"><img src="https://avatars3.githubusercontent.com/u/8635678?v=4?s=100" width="100px;" alt="Brandon Cohen"/><br /><sub><b>Brandon Cohen</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=OwsleyJr" title="Code">💻</a> <a href="https://github.com/sct/overseerr/commits?author=OwsleyJr" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Ahreluth"><img src="https://avatars2.githubusercontent.com/u/75682440?v=4?s=100" width="100px;" alt="Ahreluth"/><br /><sub><b>Ahreluth</b></sub></a><br /><a href="#translation-Ahreluth" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/KovalevArtem"><img src="https://avatars0.githubusercontent.com/u/36500228?v=4?s=100" width="100px;" alt="KovalevArtem"/><br /><sub><b>KovalevArtem</b></sub></a><br /><a href="#translation-KovalevArtem" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GiyomuWeb"><img src="https://avatars0.githubusercontent.com/u/62489209?v=4?s=100" width="100px;" alt="GiyomuWeb"/><br /><sub><b>GiyomuWeb</b></sub></a><br /><a href="#translation-GiyomuWeb" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/angrycuban13"><img src="https://avatars3.githubusercontent.com/u/39564898?v=4?s=100" width="100px;" alt="Angry Cuban"/><br /><sub><b>Angry Cuban</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=angrycuban13" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jvennik"><img src="https://avatars3.githubusercontent.com/u/6672637?v=4?s=100" width="100px;" alt="jvennik"/><br /><sub><b>jvennik</b></sub></a><br /><a href="#translation-jvennik" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/darknessgp"><img src="https://avatars0.githubusercontent.com/u/1521243?v=4?s=100" width="100px;" alt="darknessgp"/><br /><sub><b>darknessgp</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=darknessgp" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/saltydk"><img src="https://avatars1.githubusercontent.com/u/6587950?v=4?s=100" width="100px;" alt="salty"/><br /><sub><b>salty</b></sub></a><br /><a href="#infra-saltydk" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Shutruk"><img src="https://avatars2.githubusercontent.com/u/9198633?v=4?s=100" width="100px;" alt="Shutruk"/><br /><sub><b>Shutruk</b></sub></a><br /><a href="#translation-Shutruk" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/krystiancharubin"><img src="https://avatars2.githubusercontent.com/u/17775600?v=4?s=100" width="100px;" alt="Krystian Charubin"/><br /><sub><b>Krystian Charubin</b></sub></a><br /><a href="#design-krystiancharubin" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kieron"><img src="https://avatars2.githubusercontent.com/u/8655212?v=4?s=100" width="100px;" alt="Kieron Boswell"/><br /><sub><b>Kieron Boswell</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=kieron" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/samwiseg0"><img src="https://avatars1.githubusercontent.com/u/2241731?v=4?s=100" width="100px;" alt="samwiseg0"/><br /><sub><b>samwiseg0</b></sub></a><br /><a href="#question-samwiseg0" title="Answering Questions">💬</a> <a href="#infra-samwiseg0" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ecelebi29"><img src="https://avatars2.githubusercontent.com/u/8337120?v=4?s=100" width="100px;" alt="ecelebi29"/><br /><sub><b>ecelebi29</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=ecelebi29" title="Code">💻</a> <a href="https://github.com/sct/overseerr/commits?author=ecelebi29" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mmozeiko"><img src="https://avatars3.githubusercontent.com/u/1665010?v=4?s=100" width="100px;" alt="Mārtiņš Možeiko"/><br /><sub><b>Mārtiņš Možeiko</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=mmozeiko" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mazzetta86"><img src="https://avatars2.githubusercontent.com/u/45591560?v=4?s=100" width="100px;" alt="mazzetta86"/><br /><sub><b>mazzetta86</b></sub></a><br /><a href="#translation-mazzetta86" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Panzer1119"><img src="https://avatars1.githubusercontent.com/u/23016343?v=4?s=100" width="100px;" alt="Paul Hagedorn"/><br /><sub><b>Paul Hagedorn</b></sub></a><br /><a href="#translation-Panzer1119" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Shagon94"><img src="https://avatars3.githubusercontent.com/u/9140783?v=4?s=100" width="100px;" alt="Shagon94"/><br /><sub><b>Shagon94</b></sub></a><br /><a href="#translation-Shagon94" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sebstrgg"><img src="https://avatars3.githubusercontent.com/u/27026694?v=4?s=100" width="100px;" alt="sebstrgg"/><br /><sub><b>sebstrgg</b></sub></a><br /><a href="#translation-sebstrgg" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/danshilm"><img src="https://avatars2.githubusercontent.com/u/20923978?v=4?s=100" width="100px;" alt="Danshil Mungur"/><br /><sub><b>Danshil Mungur</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=danshilm" title="Code">💻</a> <a href="https://github.com/sct/overseerr/commits?author=danshilm" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/doob187"><img src="https://avatars1.githubusercontent.com/u/60312740?v=4?s=100" width="100px;" alt="doob187"/><br /><sub><b>doob187</b></sub></a><br /><a href="#infra-doob187" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/johnpyp"><img src="https://avatars2.githubusercontent.com/u/20625636?v=4?s=100" width="100px;" alt="johnpyp"/><br /><sub><b>johnpyp</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=johnpyp" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ankarhem"><img src="https://avatars1.githubusercontent.com/u/14110063?v=4?s=100" width="100px;" alt="Jakob Ankarhem"/><br /><sub><b>Jakob Ankarhem</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=ankarhem" title="Documentation">📖</a> <a href="https://github.com/sct/overseerr/commits?author=ankarhem" title="Code">💻</a> <a href="#translation-ankarhem" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jayesh100"><img src="https://avatars1.githubusercontent.com/u/8022175?v=4?s=100" width="100px;" alt="Jayesh"/><br /><sub><b>Jayesh</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=jayesh100" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/flying-sausages"><img src="https://avatars1.githubusercontent.com/u/23618693?v=4?s=100" width="100px;" alt="flying-sausages"/><br /><sub><b>flying-sausages</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=flying-sausages" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hirenshah"><img src="https://avatars2.githubusercontent.com/u/418112?v=4?s=100" width="100px;" alt="hirenshah"/><br /><sub><b>hirenshah</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=hirenshah" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TheCatLady"><img src="https://avatars0.githubusercontent.com/u/52870424?v=4?s=100" width="100px;" alt="TheCatLady"/><br /><sub><b>TheCatLady</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=TheCatLady" title="Code">💻</a> <a href="#translation-TheCatLady" title="Translation">🌍</a> <a href="https://github.com/sct/overseerr/commits?author=TheCatLady" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/chriscpritchard"><img src="https://avatars1.githubusercontent.com/u/1839074?v=4?s=100" width="100px;" alt="Chris Pritchard"/><br /><sub><b>Chris Pritchard</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=chriscpritchard" title="Code">💻</a> <a href="https://github.com/sct/overseerr/commits?author=chriscpritchard" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Tamberlox"><img src="https://avatars3.githubusercontent.com/u/56069014?v=4?s=100" width="100px;" alt="Tamberlox"/><br /><sub><b>Tamberlox</b></sub></a><br /><a href="#translation-Tamberlox" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://hmnd.io"><img src="https://avatars.githubusercontent.com/u/12853597?v=4?s=100" width="100px;" alt="David"/><br /><sub><b>David</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=hmnd" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.douglas-parker.com"><img src="https://avatars.githubusercontent.com/u/18235822?v=4?s=100" width="100px;" alt="Douglas Parker"/><br /><sub><b>Douglas Parker</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=douglasparker" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dancarter"><img src="https://avatars.githubusercontent.com/u/4387516?v=4?s=100" width="100px;" alt="Daniel Carter"/><br /><sub><b>Daniel Carter</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=dancarter" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://nuro.dev"><img src="https://avatars.githubusercontent.com/u/4991309?v=4?s=100" width="100px;" alt="nuro"/><br /><sub><b>nuro</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=NuroDev" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/onedr0p"><img src="https://avatars.githubusercontent.com/u/213795?v=4?s=100" width="100px;" alt="ᗪєνιη ᗷυнʟ"/><br /><sub><b>ᗪєνιη ᗷυнʟ</b></sub></a><br /><a href="#infra-onedr0p" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/JonnyWong16"><img src="https://avatars.githubusercontent.com/u/9099342?v=4?s=100" width="100px;" alt="JonnyWong16"/><br /><sub><b>JonnyWong16</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=JonnyWong16" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Roxedus"><img src="https://avatars.githubusercontent.com/u/7110194?v=4?s=100" width="100px;" alt="Roxedus"/><br /><sub><b>Roxedus</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=Roxedus" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/WoisWoi"><img src="https://avatars.githubusercontent.com/u/75491231?v=4?s=100" width="100px;" alt="WoisWoi"/><br /><sub><b>WoisWoi</b></sub></a><br /><a href="#translation-WoisWoi" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/HubDuck"><img src="https://avatars.githubusercontent.com/u/77843475?v=4?s=100" width="100px;" alt="HubDuck"/><br /><sub><b>HubDuck</b></sub></a><br /><a href="#translation-HubDuck" title="Translation">🌍</a> <a href="https://github.com/sct/overseerr/commits?author=HubDuck" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/costaht"><img src="https://avatars.githubusercontent.com/u/50637431?v=4?s=100" width="100px;" alt="costaht"/><br /><sub><b>costaht</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=costaht" title="Documentation">📖</a> <a href="#translation-costaht" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Shjosan"><img src="https://avatars.githubusercontent.com/u/20847626?v=4?s=100" width="100px;" alt="Shjosan"/><br /><sub><b>Shjosan</b></sub></a><br /><a href="#translation-Shjosan" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kobaubarr"><img src="https://avatars.githubusercontent.com/u/28481522?v=4?s=100" width="100px;" alt="kobaubarr"/><br /><sub><b>kobaubarr</b></sub></a><br /><a href="#translation-kobaubarr" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/notorius28"><img src="https://avatars.githubusercontent.com/u/1621513?v=4?s=100" width="100px;" alt="Ricardo González"/><br /><sub><b>Ricardo González</b></sub></a><br /><a href="#translation-notorius28" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://torkili.uz"><img src="https://avatars.githubusercontent.com/u/460764?v=4?s=100" width="100px;" alt="Torkil"/><br /><sub><b>Torkil</b></sub></a><br /><a href="#translation-Torkiliuz" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.jagandeepbrar.io"><img src="https://avatars.githubusercontent.com/u/3048295?v=4?s=100" width="100px;" alt="Jagandeep Brar"/><br /><sub><b>Jagandeep Brar</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=JagandeepBrar" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://dtalens.com"><img src="https://avatars.githubusercontent.com/u/6631832?v=4?s=100" width="100px;" alt="dtalens"/><br /><sub><b>dtalens</b></sub></a><br /><a href="#translation-dtalens" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/acortelyou"><img src="https://avatars.githubusercontent.com/u/1689668?v=4?s=100" width="100px;" alt="Alex Cortelyou"/><br /><sub><b>Alex Cortelyou</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=acortelyou" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://nz.linkedin.com/in/jonocairns"><img src="https://avatars.githubusercontent.com/u/182836?v=4?s=100" width="100px;" alt="Jono Cairns"/><br /><sub><b>Jono Cairns</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=jonocairns" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://scias.net/"><img src="https://avatars.githubusercontent.com/u/439655?v=4?s=100" width="100px;" alt="DJScias"/><br /><sub><b>DJScias</b></sub></a><br /><a href="#translation-DJScias" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Dabu-dot"><img src="https://avatars.githubusercontent.com/u/52525576?v=4?s=100" width="100px;" alt="Dabu-dot"/><br /><sub><b>Dabu-dot</b></sub></a><br /><a href="#translation-Dabu-dot" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Jabster28"><img src="https://avatars.githubusercontent.com/u/29015942?v=4?s=100" width="100px;" alt="Jabster28"/><br /><sub><b>Jabster28</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=Jabster28" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/littlerooster"><img src="https://avatars.githubusercontent.com/u/83890654?v=4?s=100" width="100px;" alt="littlerooster"/><br /><sub><b>littlerooster</b></sub></a><br /><a href="#translation-littlerooster" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dphildebrandt"><img src="https://avatars.githubusercontent.com/u/154459?v=4?s=100" width="100px;" alt="Dustin Hildebrandt"/><br /><sub><b>Dustin Hildebrandt</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=dphildebrandt" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Generator"><img src="https://avatars.githubusercontent.com/u/44146?v=4?s=100" width="100px;" alt="Bruno Guerreiro"/><br /><sub><b>Bruno Guerreiro</b></sub></a><br /><a href="#translation-Generator" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/iceHtwoO"><img src="https://avatars.githubusercontent.com/u/27020492?v=4?s=100" width="100px;" alt="Alexander Neuhäuser"/><br /><sub><b>Alexander Neuhäuser</b></sub></a><br /><a href="#translation-iceHtwoO" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.unext.co.jp"><img src="https://avatars.githubusercontent.com/u/37431541?v=4?s=100" width="100px;" alt="Livio"/><br /><sub><b>Livio</b></sub></a><br /><a href="#design-liviokanone" title="Design">🎨</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tangentThought"><img src="https://avatars.githubusercontent.com/u/25516090?v=4?s=100" width="100px;" alt="tangentThought"/><br /><sub><b>tangentThought</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=tangentThought" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/nicospz"><img src="https://avatars.githubusercontent.com/u/31373060?v=4?s=100" width="100px;" alt="Nicolás Espinoza"/><br /><sub><b>Nicolás Espinoza</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=nicospz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sootylunatic"><img src="https://avatars.githubusercontent.com/u/36486087?v=4?s=100" width="100px;" alt="sootylunatic"/><br /><sub><b>sootylunatic</b></sub></a><br /><a href="#translation-sootylunatic" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/JoKerIsCraZy"><img src="https://avatars.githubusercontent.com/u/47474211?v=4?s=100" width="100px;" alt="JoKerIsCraZy"/><br /><sub><b>JoKerIsCraZy</b></sub></a><br /><a href="#translation-JoKerIsCraZy" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://daddie.dev"><img src="https://avatars.githubusercontent.com/u/33762262?v=4?s=100" width="100px;" alt="Daddie0"/><br /><sub><b>Daddie0</b></sub></a><br /><a href="#translation-GoByeBye" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://ungaro.me"><img src="https://avatars.githubusercontent.com/u/43807696?v=4?s=100" width="100px;" alt="Simone"/><br /><sub><b>Simone</b></sub></a><br /><a href="#translation-Simoneu01" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/adan89lion"><img src="https://avatars.githubusercontent.com/u/6585644?v=4?s=100" width="100px;" alt="Seohyun Joo"/><br /><sub><b>Seohyun Joo</b></sub></a><br /><a href="#translation-adan89lion" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ty4ko"><img src="https://avatars.githubusercontent.com/u/21213535?v=4?s=100" width="100px;" alt="Sergey"/><br /><sub><b>Sergey</b></sub></a><br /><a href="#translation-ty4ko" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/skafte1990"><img src="https://avatars.githubusercontent.com/u/31465453?v=4?s=100" width="100px;" alt="Shaaft"/><br /><sub><b>Shaaft</b></sub></a><br /><a href="#translation-skafte1990" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sr093906"><img src="https://avatars.githubusercontent.com/u/8369201?v=4?s=100" width="100px;" alt="sr093906"/><br /><sub><b>sr093906</b></sub></a><br /><a href="#translation-sr093906" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Nackophilz"><img src="https://avatars.githubusercontent.com/u/61667226?v=4?s=100" width="100px;" alt="Nackophilz"/><br /><sub><b>Nackophilz</b></sub></a><br /><a href="#translation-Nackophilz" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/schambers"><img src="https://avatars.githubusercontent.com/u/31563?v=4?s=100" width="100px;" alt="Sean Chambers"/><br /><sub><b>Sean Chambers</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=schambers" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/deniscerri"><img src="https://avatars.githubusercontent.com/u/64997243?v=4?s=100" width="100px;" alt="deniscerri"/><br /><sub><b>deniscerri</b></sub></a><br /><a href="#translation-deniscerri" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tomgacz"><img src="https://avatars.githubusercontent.com/u/14138209?v=4?s=100" width="100px;" alt="tomgacz"/><br /><sub><b>tomgacz</b></sub></a><br /><a href="#translation-tomgacz" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Andersborrits"><img src="https://avatars.githubusercontent.com/u/29452218?v=4?s=100" width="100px;" alt="Andersborrits"/><br /><sub><b>Andersborrits</b></sub></a><br /><a href="#translation-Andersborrits" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://maxentrouault.fr"><img src="https://avatars.githubusercontent.com/u/67283154?v=4?s=100" width="100px;" alt="Maxent"/><br /><sub><b>Maxent</b></sub></a><br /><a href="#translation-Maxentr" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sambartik"><img src="https://avatars.githubusercontent.com/u/63553146?v=4?s=100" width="100px;" alt="Samuel Bartík"/><br /><sub><b>Samuel Bartík</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=sambartik" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/frank-cywong"><img src="https://avatars.githubusercontent.com/u/90653148?v=4?s=100" width="100px;" alt="Chun Yeung Wong"/><br /><sub><b>Chun Yeung Wong</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=frank-cywong" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TheMeanCanEHdian"><img src="https://avatars.githubusercontent.com/u/16025103?v=4?s=100" width="100px;" alt="TheMeanCanEHdian"/><br /><sub><b>TheMeanCanEHdian</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=TheMeanCanEHdian" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Gylesie"><img src="https://avatars.githubusercontent.com/u/86306812?v=4?s=100" width="100px;" alt="Gylesie"/><br /><sub><b>Gylesie</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=Gylesie" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Fhd-pro"><img src="https://avatars.githubusercontent.com/u/82862079?v=4?s=100" width="100px;" alt="Fhd-pro"/><br /><sub><b>Fhd-pro</b></sub></a><br /><a href="#translation-Fhd-pro" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/PovilasID"><img src="https://avatars.githubusercontent.com/u/396243?v=4?s=100" width="100px;" alt="PovilasID"/><br /><sub><b>PovilasID</b></sub></a><br /><a href="#translation-PovilasID" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/byakurau"><img src="https://avatars.githubusercontent.com/u/1811683?v=4?s=100" width="100px;" alt="byakurau"/><br /><sub><b>byakurau</b></sub></a><br /><a href="#translation-byakurau" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/miknii"><img src="https://avatars.githubusercontent.com/u/109232569?v=4?s=100" width="100px;" alt="miknii"/><br /><sub><b>miknii</b></sub></a><br /><a href="#translation-miknii" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Eclipseop"><img src="https://avatars.githubusercontent.com/u/5846213?v=4?s=100" width="100px;" alt="Mackenzie"/><br /><sub><b>Mackenzie</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=Eclipseop" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/s0up4200"><img src="https://avatars.githubusercontent.com/u/18177310?v=4?s=100" width="100px;" alt="soup"/><br /><sub><b>soup</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=s0up4200" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ceptonit"><img src="https://avatars.githubusercontent.com/u/12678743?v=4?s=100" width="100px;" alt="ceptonit"/><br /><sub><b>ceptonit</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=ceptonit" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aedelbro"><img src="https://avatars.githubusercontent.com/u/36162221?v=4?s=100" width="100px;" alt="aedelbro"/><br /><sub><b>aedelbro</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=aedelbro" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="http://twitter.com/lunks/"><img src="https://avatars.githubusercontent.com/u/91118?v=4?s=100" width="100px;" alt="Pedro Nascimento"/><br /><sub><b>Pedro Nascimento</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=lunks" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://voke.dev"><img src="https://avatars.githubusercontent.com/u/1899334?v=4?s=100" width="100px;" alt="Owen Voke"/><br /><sub><b>Owen Voke</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=owenvoke" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Nimelrian"><img src="https://avatars.githubusercontent.com/u/8960836?v=4?s=100" width="100px;" alt="Sebastian K"/><br /><sub><b>Sebastian K</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=Nimelrian" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jariz"><img src="https://avatars.githubusercontent.com/u/1415847?v=4?s=100" width="100px;" alt="jariz"/><br /><sub><b>jariz</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=jariz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://arouillard.fr"><img src="https://avatars.githubusercontent.com/u/13947260?v=4?s=100" width="100px;" alt="Alex"/><br /><sub><b>Alex</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=Alexays" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Zebebles"><img src="https://avatars.githubusercontent.com/u/11425451?v=4?s=100" width="100px;" alt="Zeb Muller"/><br /><sub><b>Zeb Muller</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=Zebebles" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://smoores.dev"><img src="https://avatars.githubusercontent.com/u/5354254?v=4?s=100" width="100px;" alt="Shane Friedman"/><br /><sub><b>Shane Friedman</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=SMores" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://izaacj.me"><img src="https://avatars.githubusercontent.com/u/711323?v=4?s=100" width="100px;" alt="Izaac Brånn"/><br /><sub><b>Izaac Brånn</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=IzaacJ" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/SalmanTariq"><img src="https://avatars.githubusercontent.com/u/13284494?v=4?s=100" width="100px;" alt="Salman Tariq"/><br /><sub><b>Salman Tariq</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=SalmanTariq" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/andrew-kennedy"><img src="https://avatars.githubusercontent.com/u/2387159?v=4?s=100" width="100px;" alt="Andrew Kennedy"/><br /><sub><b>Andrew Kennedy</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=andrew-kennedy" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Fallenbagel"><img src="https://avatars.githubusercontent.com/u/98979876?v=4?s=100" width="100px;" alt="Fallenbagel"/><br /><sub><b>Fallenbagel</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=Fallenbagel" title="Jellyseerr">🪼⌨️</a> <a href="https://github.com/sct/overseerr/commits?author=Fallenbagel" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://aidoge.xyz"><img src="https://avatars.githubusercontent.com/u/9427639?v=4?s=100" width="100px;" alt="Anton K. (ai Doge)"/><br /><sub><b>Anton K. (ai Doge)</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=scorp200" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://marcofaggian.com"><img src="https://avatars.githubusercontent.com/u/19221001?v=4?s=100" width="100px;" alt="Marco Faggian"/><br /><sub><b>Marco Faggian</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=marcofaggian" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://nemchik.com/"><img src="https://avatars.githubusercontent.com/u/725456?v=4?s=100" width="100px;" alt="Eric Nemchik"/><br /><sub><b>Eric Nemchik</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=nemchik" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/RemiRigal"><img src="https://avatars.githubusercontent.com/u/19256051?v=4?s=100" width="100px;" alt="RemiRigal"/><br /><sub><b>RemiRigal</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=RemiRigal" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://josephrisk.com"><img src="https://avatars.githubusercontent.com/u/18372584?v=4?s=100" width="100px;" alt="Joseph Risk"/><br /><sub><b>Joseph Risk</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=j0srisk" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Loetwiek"><img src="https://avatars.githubusercontent.com/u/79059734?v=4?s=100" width="100px;" alt="Loetwiek"/><br /><sub><b>Loetwiek</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=Loetwiek" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Fuochi"><img src="https://avatars.githubusercontent.com/u/4720478?v=4?s=100" width="100px;" alt="Fuochi"/><br /><sub><b>Fuochi</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=Fuochi" title="Documentation">📖</a></td>
</tr>
</tbody>
</table>

View File

@@ -1,52 +0,0 @@
# Security Policy
## Reporting Security Issues
Maintainers and community take security bugs seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
To report a security issue, please use the GitHub Security Advisory ["Report a Vulnerability"](../../security/advisories/new) tab.
**Please do not report security vulnerabilities through public GitHub issues, discussions, or Discord.**
## What to Include in Your Report
To help us better understand and resolve the issue, please include as much of the following information as possible:
- Full paths of source file(s) related to the manifestation of the issue
- The location of the affected source code (tag/branch/commit or direct URL)
- Any special configuration required to reproduce the issue
- Step-by-step instructions to reproduce the issue
- Proof-of-concept or exploit code (if possible)
- Impact of the issue
## Response Timeline
We will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
## Disclosure Policy
- Security issues will be disclosed in a coordinated manner
- We will credit reporters in the security advisory unless anonymity is requested
- We request that you do not publicly disclose the issue until we have released a fix
## Third-Party Dependencies
If you discover a security vulnerability in a third-party dependency used by Seerr, please report it directly to the maintainers of that module. You can also notify us through our security advisory process so we can:
- Track the issue and monitor for updates
- Apply patches or workarounds if available
- Coordinate with upstream maintainers when necessary
- Communicate the impact to our users
We regularly monitor and update our dependencies to address known security vulnerabilities.
## Security Updates
Security updates and advisories will be published on our [GitHub Security Advisories page](../../security/advisories).
## Community
For general questions and support (non-security related):
- [GitHub Discussions](../../discussions)
- [Discord](https://discord.gg/seerr)

View File

@@ -1,9 +0,0 @@
#!/usr/bin/env node
/**
* Do not run husky in CI environments
*/
const isCi = process.env.CI !== undefined;
if (!isCi) {
require('husky').install();
}

View File

@@ -1,25 +0,0 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
# go template
*.gotmpl

View File

@@ -1,14 +0,0 @@
apiVersion: v2
kubeVersion: '>=1.23.0-0'
name: seerr-chart
description: Seerr helm chart for Kubernetes
type: application
version: 3.0.0
# renovate: image=ghcr.io/seerr-team/seerr
appVersion: '3.0.0'
maintainers:
- name: Seerr Team
url: https://github.com/orgs/seerr-team/people
sources:
- https://github.com/seerr-team/seerr/tree/main/charts/seerr
home: https://github.com/seerr-team/seerr

View File

@@ -1,95 +0,0 @@
# seerr-chart
![Version: 3.0.0](https://img.shields.io/badge/Version-3.0.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 3.0.0](https://img.shields.io/badge/AppVersion-3.0.0-informational?style=flat-square)
Seerr helm chart for Kubernetes
**Homepage:** <https://github.com/seerr-team/seerr>
## Maintainers
| Name | Email | Url |
| ---- | ------ | --- |
| Seerr Team | | <https://github.com/orgs/seerr-team/people> |
## Source Code
* <https://github.com/seerr-team/seerr/tree/main/charts/seerr>
## Requirements
Kubernetes: `>=1.23.0-0`
## Installation
Refer to [Seerr kubernetes documentation](https://docs.seerr.dev/getting-started/kubernetes)
## Update Notes
### Updating to 3.0.0
Nothing has changed; we just rebranded the `jellyseerr` Helm chart to `seerr` 🥳 refer to our [Migration guide](https://docs.seerr.dev/migration-guide).
### Updating to 2.7.0
Seerr is a stateful application and it is not designed to have multiple replicas. In version 2.7.0 we address this by:
- replacing `Deployment` with `StatefulSet`
- removing `replicaCount` value
If `replicaCount` value was used - remove it. Helm update should work fine after that.
## Values
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| affinity | object | `{}` | |
| config | object | `{"persistence":{"accessModes":["ReadWriteOnce"],"annotations":{},"name":"","size":"5Gi","volumeName":""}}` | Creating PVC to store configuration |
| config.persistence.accessModes | list | `["ReadWriteOnce"]` | Access modes of persistent disk |
| config.persistence.annotations | object | `{}` | Annotations for PVCs |
| config.persistence.name | string | `""` | Config name |
| config.persistence.size | string | `"5Gi"` | Size of persistent disk |
| config.persistence.volumeName | string | `""` | Name of the permanent volume to reference in the claim. Can be used to bind to existing volumes. |
| extraEnv | list | `[]` | Environment variables to add to the seerr pods |
| extraEnvFrom | list | `[]` | Environment variables from secrets or configmaps to add to the seerr pods |
| fullnameOverride | string | `""` | |
| image.pullPolicy | string | `"IfNotPresent"` | |
| image.registry | string | `"ghcr.io"` | |
| image.repository | string | `"seerr-team/seerr"` | |
| image.sha | string | `""` | |
| image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. |
| imagePullSecrets | list | `[]` | |
| ingress.annotations | object | `{}` | |
| ingress.enabled | bool | `false` | |
| ingress.hosts[0].host | string | `"chart-example.local"` | |
| ingress.hosts[0].paths[0].path | string | `"/"` | |
| ingress.hosts[0].paths[0].pathType | string | `"ImplementationSpecific"` | |
| ingress.ingressClassName | string | `""` | |
| ingress.tls | list | `[]` | |
| nameOverride | string | `""` | |
| nodeSelector | object | `{}` | |
| podAnnotations | object | `{}` | |
| podLabels | object | `{}` | |
| podSecurityContext.fsGroup | int | `1000` | |
| podSecurityContext.fsGroupChangePolicy | string | `"OnRootMismatch"` | |
| probes.livenessProbe | object | `{}` | Configure liveness probe |
| probes.readinessProbe | object | `{}` | Configure readiness probe |
| probes.startupProbe | string | `nil` | Configure startup probe |
| resources | object | `{}` | |
| securityContext.allowPrivilegeEscalation | bool | `false` | |
| securityContext.capabilities.drop[0] | string | `"ALL"` | |
| securityContext.privileged | bool | `false` | |
| securityContext.readOnlyRootFilesystem | bool | `false` | |
| securityContext.runAsGroup | int | `1000` | |
| securityContext.runAsNonRoot | bool | `true` | |
| securityContext.runAsUser | int | `1000` | |
| securityContext.seccompProfile.type | string | `"RuntimeDefault"` | |
| service.port | int | `80` | |
| service.type | string | `"ClusterIP"` | |
| serviceAccount.annotations | object | `{}` | Annotations to add to the service account |
| serviceAccount.automount | bool | `true` | Automatically mount a ServiceAccount's API credentials? |
| serviceAccount.create | bool | `true` | Specifies whether a service account should be created |
| serviceAccount.name | string | `""` | If not set and create is true, a name is generated using the fullname template |
| tolerations | list | `[]` | |
| volumeMounts | list | `[]` | Additional volumeMounts on the output StatefulSet definition. |
| volumes | list | `[]` | Additional volumes on the output StatefulSet definition. |

View File

@@ -1,36 +0,0 @@
{{ template "chart.header" . }}
{{ template "chart.deprecationWarning" . }}
{{ template "chart.badgesSection" . }}
{{ template "chart.description" . }}
{{ template "chart.homepageLine" . }}
{{ template "chart.maintainersSection" . }}
{{ template "chart.sourcesSection" . }}
{{ template "chart.requirementsSection" . }}
## Installation
Refer to [Seerr kubernetes documentation](https://docs.seerr.dev/getting-started/kubernetes)
## Update Notes
### Updating to 3.0.0
Nothing has changed; we just rebranded the `jellyseerr` Helm chart to `seerr` 🥳 refer to our [Migration guide](https://docs.seerr.dev/migration-guide).
### Updating to 2.7.0
Seerr is a stateful application and it is not designed to have multiple replicas. In version 2.7.0 we address this by:
- replacing `Deployment` with `StatefulSet`
- removing `replicaCount` value
If `replicaCount` value was used - remove it. Helm update should work fine after that.
{{ template "chart.valuesSection" . }}

View File

@@ -1 +0,0 @@
repositoryID: 249547ec-2a30-48de-a5bc-07bfd5aa2e8f

View File

@@ -1,5 +0,0 @@
***********************************************************************
Welcome to {{ .Chart.Name }}
Chart version: {{ .Chart.Version }}
App version: {{ .Chart.AppVersion }}
***********************************************************************

View File

@@ -1,70 +0,0 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "seerr.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "seerr.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "seerr.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "seerr.labels" -}}
helm.sh/chart: {{ include "seerr.chart" . }}
{{ include "seerr.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/part-of: {{ .Chart.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "seerr.selectorLabels" -}}
app.kubernetes.io/name: {{ include "seerr.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "seerr.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "seerr.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Create the name of the pvc config to use
*/}}
{{- define "seerr.configPersistenceName" -}}
{{- default (printf "%s-config" (include "seerr.fullname" .)) .Values.config.persistence.name }}
{{- end }}

View File

@@ -1,41 +0,0 @@
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "seerr.fullname" . }}
labels:
{{- include "seerr.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.ingressClassName }}
ingressClassName: {{ .Values.ingress.ingressClassName }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ include "seerr.fullname" $ }}
port:
number: {{ $.Values.service.port }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -1,24 +0,0 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "seerr.configPersistenceName" . }}
labels:
{{- include "seerr.labels" . | nindent 4 }}
{{- with .Values.config.persistence.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with .Values.config.persistence.accessModes }}
accessModes:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- if .Values.config.persistence.volumeName }}
volumeName: {{ .Values.config.persistence.volumeName }}
{{- end }}
{{- with .Values.config.persistence.storageClass }}
storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }}
{{- end }}
resources:
requests:
storage: "{{ .Values.config.persistence.size }}"

View File

@@ -1,16 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "seerr.fullname" . }}
labels:
{{- include "seerr.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "seerr.selectorLabels" . | nindent 4 }}
ipFamilyPolicy: PreferDualStack

View File

@@ -1,13 +0,0 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "seerr.serviceAccountName" . }}
labels:
{{- include "seerr.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
{{- end }}

View File

@@ -1,121 +0,0 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ include "seerr.fullname" . }}
labels:
{{- include "seerr.labels" . | nindent 4 }}
spec:
serviceName: {{ include "seerr.fullname" . }}
selector:
matchLabels:
{{- include "seerr.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "seerr.labels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "seerr.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
{{- if .Values.image.sha }}
image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}@sha256:{{ .Values.image.sha }}"
{{- else }}
image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
{{- end }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: 5055
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
{{- if .Values.probes.livenessProbe.initialDelaySeconds }}
initialDelaySeconds: {{ .Values.probes.livenessProbe.initialDelaySeconds }}
{{- end }}
{{- if .Values.probes.livenessProbe.periodSeconds }}
periodSeconds: {{ .Values.probes.livenessProbe.periodSeconds }}
{{- end }}
{{- if .Values.probes.livenessProbe.timeoutSeconds }}
timeoutSeconds: {{ .Values.probes.livenessProbe.timeoutSeconds }}
{{- end }}
{{- if .Values.probes.livenessProbe.successThreshold }}
successThreshold: {{ .Values.probes.livenessProbe.successThreshold }}
{{- end }}
{{- if .Values.probes.livenessProbe.failureThreshold }}
failureThreshold: {{ .Values.probes.livenessProbe.failureThreshold }}
{{- end }}
readinessProbe:
httpGet:
path: /
port: http
{{- if .Values.probes.readinessProbe.initialDelaySeconds }}
initialDelaySeconds: {{ .Values.probes.readinessProbe.initialDelaySeconds }}
{{- end }}
{{- if .Values.probes.readinessProbe.periodSeconds }}
periodSeconds: {{ .Values.probes.readinessProbe.periodSeconds }}
{{- end }}
{{- if .Values.probes.readinessProbe.timeoutSeconds }}
timeoutSeconds: {{ .Values.probes.readinessProbe.timeoutSeconds }}
{{- end }}
{{- if .Values.probes.readinessProbe.successThreshold }}
successThreshold: {{ .Values.probes.readinessProbe.successThreshold }}
{{- end }}
{{- if .Values.probes.readinessProbe.failureThreshold }}
failureThreshold: {{ .Values.probes.readinessProbe.failureThreshold }}
{{- end }}
{{- if .Values.probes.startupProbe }}
startupProbe:
{{- toYaml .Values.probes.startupProbe | nindent 12 }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.extraEnv }}
env:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.extraEnvFrom }}
envFrom:
{{- toYaml . | nindent 12 }}
{{- end }}
volumeMounts:
- name: config
mountPath: /app/config
{{- with .Values.volumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}
volumes:
- name: config
persistentVolumeClaim:
claimName: {{ include "seerr.configPersistenceName" . }}
{{- with .Values.volumes }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@@ -1,15 +0,0 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "seerr.fullname" . }}-test-connection"
labels:
{{- include "seerr.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "seerr.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never

View File

@@ -1,135 +0,0 @@
image:
registry: ghcr.io
repository: seerr-team/seerr
pullPolicy: IfNotPresent
# -- Overrides the image tag whose default is the chart appVersion.
tag: ''
sha: ''
imagePullSecrets: []
nameOverride: ''
fullnameOverride: ''
# Liveness / Readiness / Startup Probes
probes:
# -- Configure liveness probe
livenessProbe: {}
# initialDelaySeconds: 60
# periodSeconds: 30
# timeoutSeconds: 5
# successThreshold: 1
# failureThreshold: 5
# -- Configure readiness probe
readinessProbe: {}
# initialDelaySeconds: 60
# periodSeconds: 30
# timeoutSeconds: 5
# successThreshold: 1
# failureThreshold: 5
# -- Configure startup probe
startupProbe: null
# tcpSocket:
# port: http
# -- Environment variables to add to the seerr pods
extraEnv: []
# -- Environment variables from secrets or configmaps to add to the seerr pods
extraEnvFrom: []
serviceAccount:
# -- Specifies whether a service account should be created
create: true
# -- Automatically mount a ServiceAccount's API credentials?
automount: true
# -- Annotations to add to the service account
annotations: {}
# -- The name of the service account to use.
# -- If not set and create is true, a name is generated using the fullname template
name: ''
podAnnotations: {}
podLabels: {}
podSecurityContext:
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: false
runAsNonRoot: true
privileged: false
runAsUser: 1000
runAsGroup: 1000
seccompProfile:
type: RuntimeDefault
service:
type: ClusterIP
port: 80
# -- Creating PVC to store configuration
config:
persistence:
# -- Size of persistent disk
size: 5Gi
# -- Annotations for PVCs
annotations: {}
# -- Access modes of persistent disk
accessModes:
- ReadWriteOnce
# -- Config name
name: ''
# -- Name of the permanent volume to reference in the claim.
# Can be used to bind to existing volumes.
volumeName: ''
ingress:
enabled: false
ingressClassName: ''
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
# -- Additional volumes on the output StatefulSet definition.
volumes: []
# - name: foo
# secret:
# secretName: mysecret
# optional: false
# -- Additional volumeMounts on the output StatefulSet definition.
volumeMounts: []
# - name: foo
# mountPath: "/etc/foo"
# readOnly: true
nodeSelector: {}
tolerations: []
affinity: {}

View File

@@ -1,36 +0,0 @@
services:
seerr:
build:
context: .
dockerfile: Dockerfile.local
ports:
- '5055:5055'
environment:
DB_TYPE: 'postgres' # Which DB engine to use. The default is "sqlite". To use postgres, this needs to be set to "postgres"
DB_HOST: 'postgres' # The host (url) of the database
DB_PORT: '5432' # The port to connect to
DB_USER: 'seerr' # Username used to connect to the database
DB_PASS: 'seerr' # Password of the user used to connect to the database
DB_NAME: 'seerr' # The name of the database to connect to
DB_LOG_QUERIES: 'false' # Whether to log the DB queries for debugging
DB_USE_SSL: 'false' # Whether to enable ssl for database connection
volumes:
- .:/app:rw,cached
- /app/node_modules
- /app/.next
depends_on:
- postgres
links:
- postgres
postgres:
image: postgres:18
environment:
POSTGRES_USER: seerr
POSTGRES_PASSWORD: seerr
POSTGRES_DB: seerr
ports:
- '5432:5432'
volumes:
- postgres:/var/lib/postgresql
volumes:
postgres:

View File

@@ -1,10 +1,10 @@
import { defineConfig } from 'cypress';
export default defineConfig({
projectId: 'onnqy3',
projectId: 'xkm1b4',
e2e: {
baseUrl: 'http://localhost:5055',
video: true,
experimentalSessionAndOrigin: true,
},
env: {
ADMIN_EMAIL: 'admin@seerr.dev',

View File

@@ -4,8 +4,9 @@
"vapidPublic": "BK_EpP8NDm9waor2zn6_S28o3ZYv4kCkJOfYpO3pt3W6jnPmxrgTLANUBNbbyaNatPnSQ12De9CeqSYQrqWzHTs",
"main": {
"apiKey": "testkey",
"applicationTitle": "Seerr",
"applicationTitle": "Overseerr",
"applicationUrl": "",
"csrfProtection": false,
"cacheImages": false,
"defaultPermissions": 32,
"defaultQuotas": {
@@ -15,15 +16,11 @@
"hideAvailable": false,
"localLogin": true,
"newPlexLogin": true,
"discoverRegion": "",
"streamingRegion": "",
"region": "",
"originalLanguage": "",
"blacklistedTags": "",
"blacklistedTagsLimit": 50,
"trustProxy": false,
"mediaServerType": 1,
"partialRequestsEnabled": true,
"enableSpecialEpisodes": false,
"locale": "en"
},
"plex": {
@@ -70,7 +67,7 @@
"ignoreTls": false,
"requireTls": false,
"allowSelfSigned": false,
"senderName": "Seerr"
"senderName": "Overseerr"
}
},
"discord": {
@@ -78,10 +75,16 @@
"types": 0,
"options": {
"webhookUrl": "",
"webhookRoleId": "",
"enableMentions": true
}
},
"lunasea": {
"enabled": false,
"types": 0,
"options": {
"webhookUrl": ""
}
},
"slack": {
"enabled": false,
"types": 0,
@@ -95,7 +98,6 @@
"options": {
"botAPI": "",
"chatId": "",
"messageThreadId": "",
"sendSilently": false
}
},
@@ -131,16 +133,7 @@
"types": 0,
"options": {
"url": "",
"token": "",
"priority": 0
}
},
"ntfy": {
"enabled": false,
"types": 0,
"options": {
"url": "",
"topic": ""
"token": ""
}
}
}
@@ -179,26 +172,5 @@
"image-cache-cleanup": {
"schedule": "0 0 5 * * *"
}
},
"network": {
"csrfProtection": false,
"trustProxy": false,
"forceIpv4First": false,
"dnsServers": "",
"proxy": {
"enabled": false,
"hostname": "",
"port": 8080,
"useSsl": false,
"user": "",
"password": "",
"bypassFilter": "",
"bypassLocalAddresses": true
},
"dnsCache": {
"enabled": false,
"forceMinTtl": 0,
"forceMaxTtl": -1
}
}
}

View File

@@ -1,148 +0,0 @@
describe('TVDB Integration', () => {
// Constants for routes and selectors
const ROUTES = {
home: '/',
metadataSettings: '/settings/metadata',
tomorrowIsOursTvShow: '/tv/72879',
monsterTvShow: '/tv/225634',
dragonnBallZKaiAnime: '/tv/61709',
};
const SELECTORS = {
sidebarToggle: '[data-testid=sidebar-toggle]',
sidebarSettingsMobile: '[data-testid=sidebar-menu-settings-mobile]',
settingsNavDesktop: 'nav[data-testid="settings-nav-desktop"]',
metadataTestButton: 'button[type="button"]:contains("Test")',
metadataSaveButton: '[data-testid="metadata-save-button"]',
tmdbStatus: '[data-testid="tmdb-status"]',
tvdbStatus: '[data-testid="tvdb-status"]',
tvMetadataProviderSelector: '[data-testid="tv-metadata-provider-selector"]',
animeMetadataProviderSelector:
'[data-testid="anime-metadata-provider-selector"]',
seasonSelector: '[data-testid="season-selector"]',
season1: 'Season 1',
season2: 'Season 2',
season3: 'Season 3',
episodeList: '[data-testid="episode-list"]',
episode9: '9 - Hang Men',
};
// Reusable commands
const navigateToMetadataSettings = () => {
cy.visit(ROUTES.home);
cy.get(SELECTORS.sidebarToggle).click();
cy.get(SELECTORS.sidebarSettingsMobile).click();
cy.get(
`${SELECTORS.settingsNavDesktop} a[href="${ROUTES.metadataSettings}"]`
).click();
};
const testAndVerifyMetadataConnection = () => {
cy.intercept('POST', '/api/v1/settings/metadatas/test').as(
'testConnection'
);
cy.get(SELECTORS.metadataTestButton).click();
return cy.wait('@testConnection');
};
const saveMetadataSettings = (customBody = null) => {
if (customBody) {
cy.intercept('PUT', '/api/v1/settings/metadatas', (req) => {
req.body = customBody;
}).as('saveMetadata');
} else {
// Else just intercept without modifying body
cy.intercept('PUT', '/api/v1/settings/metadatas').as('saveMetadata');
}
cy.get(SELECTORS.metadataSaveButton).click();
return cy.wait('@saveMetadata');
};
beforeEach(() => {
// Perform login
cy.login(Cypress.env('ADMIN_EMAIL'), Cypress.env('ADMIN_PASSWORD'));
// Navigate to Metadata settings
navigateToMetadataSettings();
// Verify we're on the correct settings page
cy.contains('h3', 'Metadata Providers').should('be.visible');
// Configure TVDB as TV provider and test connection
cy.get(SELECTORS.tvMetadataProviderSelector).click();
// get id react-select-4-option-1
cy.get('[class*="react-select__option"]').contains('TheTVDB').click();
// Test the connection
testAndVerifyMetadataConnection().then(({ response }) => {
expect(response.statusCode).to.equal(200);
// Check TVDB connection status
cy.get(SELECTORS.tvdbStatus).should('contain', 'Operational');
});
// Save settings
saveMetadataSettings({
anime: 'tvdb',
tv: 'tvdb',
}).then(({ response }) => {
expect(response.statusCode).to.equal(200);
expect(response.body.tv).to.equal('tvdb');
});
});
it('should display "Tomorrow is Ours" show information with multiple seasons from TVDB', () => {
// Navigate to the TV show
cy.visit(ROUTES.tomorrowIsOursTvShow);
// Verify that multiple seasons are displayed (TMDB has only 1 season, TVDB has multiple)
// cy.get(SELECTORS.seasonSelector).should('exist');
cy.intercept('/api/v1/tv/225634/season/1').as('season1');
// Select Season 2 and verify it loads
cy.contains(SELECTORS.season2)
.should('be.visible')
.scrollIntoView()
.click();
// Verify that episodes are displayed for Season 2
cy.contains('260 - Episode 506').should('be.visible');
});
it('Should display "Monster" show information correctly when not existing on TVDB', () => {
// Navigate to the TV show
cy.visit(ROUTES.monsterTvShow);
// Intercept season 1 request
cy.intercept('/api/v1/tv/225634/season/1').as('season1');
// Select Season 1
cy.contains(SELECTORS.season1)
.should('be.visible')
.scrollIntoView()
.click();
// Wait for the season data to load
cy.wait('@season1');
// Verify specific episode exists
cy.contains(SELECTORS.episode9).should('be.visible');
});
it('should display "Dragon Ball Z Kai" show information with multiple only 2 seasons from TVDB', () => {
// Navigate to the TV show
cy.visit(ROUTES.dragonnBallZKaiAnime);
// Intercept season 1 request
cy.intercept('/api/v1/tv/61709/season/1').as('season1');
// Select Season 2 and verify it visible
cy.contains(SELECTORS.season2)
.should('be.visible')
.scrollIntoView()
.click();
// select season 3 and verify it not visible
cy.contains(SELECTORS.season3).should('not.exist');
});
});

View File

@@ -13,10 +13,10 @@ describe('General Settings', () => {
});
it('modifies setting that requires restart', () => {
cy.visit('/settings/network');
cy.visit('/settings');
cy.get('#trustProxy').click();
cy.get('[data-testid=settings-network-form]').submit();
cy.get('[data-testid=settings-main-form]').submit();
cy.get('[data-testid=modal-title]').should(
'contain',
'Server Restart Required'
@@ -26,7 +26,7 @@ describe('General Settings', () => {
cy.get('[data-testid=modal-title]').should('not.exist');
cy.get('[type=checkbox]#trustProxy').click();
cy.get('[data-testid=settings-network-form]').submit();
cy.get('[data-testid=settings-main-form]').submit();
cy.get('[data-testid=modal-title]').should('not.exist');
});
});

View File

@@ -6,6 +6,7 @@ Cypress.Commands.add('login', (email, password) => {
[email, password],
() => {
cy.visit('/login');
cy.contains('Use your Overseerr account').click();
cy.get('[data-testid=email]').type(email);
cy.get('[data-testid=password]').type(password);

View File

@@ -1,5 +1,6 @@
version: '3'
services:
seerr:
jellyseerr:
build:
context: .
dockerfile: Dockerfile.local

View File

@@ -5,31 +5,33 @@ sidebar_position: 1
# Introduction
Welcome to the Seerr Documentation.
**Seerr** is a free and open source software application for managing requests for your media library. It integrates with the media server of your choice: [Jellyfin](https://jellyfin.org), [Plex](https://plex.tv), and [Emby](https://emby.media/). In addition, it integrates with your existing services, such as **[Sonarr](https://sonarr.tv/)**, **[Radarr](https://radarr.video/)**.
Welcome to the Jellyseerr Documentation.
## Features
- **Full Jellyfin/Emby/Plex integration**. Login and manage user access with Jellyfin/Emby/Plex.
- **Syncs to your Jellyfin/Emby/Plex library** to show what titles you already have.
- Supports Movies, Shows and Mixed Libraries.
- **Integrates with Sonarr and Radarr**. With more services to come in the future.
- Optionally set **Override rules** for requests to match with your defined conditions.
- **Easy to use request system** allowing users to request individual seasons or movies in a friendly, clean UI.
- **Simple request management UI**. Don't dig through the app to approve recent requests.
- **Mobile-friendly design**, for when you need to approve requests on the go.
- Granular permission system.
- Localization into other languages.
- Support for **PostgreSQL** and **SQLite** databases.
- Support for various notification agents.
- Easily **Watchlist** or **Blacklist** media.
- More features to come!
## Motivation
The primary motivation for starting this project was to add support for Jellyfin and Emby to Overseerr. As Overseerr is an incredibly performant and easy-to-use application, we wanted to bring that same experience to Jellyfin and Emby users. Thus, **Jellyseerr** was born.
This application is designed to be a **one-stop-shop** for all your media requests. It is designed to be a **simple, easy-to-use** application that allows users to request media to be added to your Jellyfin/Emby/Plex server.
## We need your help!
[Seerr](https://github.com/seerr-team/seerr) is an ambitious project developers/contributors poured a lot of work into, and we still have a lot more to do. Seerr is the result of a collaborative effort between the original Overseerr project and the Jellyseerr fork, created to deliver an excellent request management solution for Plex, Jellyfin and Emby users.
[Jellyseerr](https://github.com/Fallenbagel/jellyseerr) is a fork of Overseerr, with a heavy focus on Jellyfin and Emby integration.
[Overseerr](https://github.com/sct/overseerr) is an ambitious project where the original developers/contributors have already poured a lot of work into, and we wanted to build on top of that.
We value your feedback and support in identifying and fixing bugs to make Seerr even better. As an open-source project, we welcome contributions from everyone. Contribution includes building new features, patching bugs, translating the application, or even just writing documentation.
We also have poured a lot of work into this project, and we have a lot more to do as well. We need your valuable feedback and help to find and fix bugs. Also, with Jellyseerr being an open-source project, anyone is welcome to contribute. We also encourage you to contribute to Overseerr as well.
If you would like to contribute, please be sure to review our [contribution guidelines](https://github.com/seerr-team/seerr/blob/develop/CONTRIBUTING.md).
Contribution includes building new features, patching bugs, translating the application, or even just writing documentation.
If you would like to contribute, please be sure to review our [contribution guidelines](https://github.com/fallenbagel/jellyseerr/blob/develop/CONTRIBUTING.md).

View File

@@ -0,0 +1,9 @@
{
"label": "Extending Jellyseerr",
"position": 3,
"link": {
"type": "generated-index",
"title": "Extending Jellyseerr",
"description": "Extend Jellyseerr to your liking"
}
}

View File

@@ -0,0 +1,207 @@
---
title: Reverse Proxy
description: Configure a reverse proxy for Jellyseerr.
sidebar_position: 1
---
# Reverse Proxy
:::warning
Base URLs cannot be configured in Jellyseerr. With this limitation, only subdomain configurations are supported.
A Nginx subfolder workaround configuration is provided below, but it is not officially supported.
:::
## Nginx
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs groupId="nginx-reverse-proxy" queryString>
<TabItem value="subdomain" label="Subdomain">
Add the following configuration to a new file `/etc/nginx/sites-available/jellyseerr.example.com.conf`:
```nginx
server {
listen 80;
server_name jellyseerr.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name jellyseerr.example.com;
ssl_certificate /etc/letsencrypt/live/jellyseerr.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/jellyseerr.example.com/privkey.pem;
proxy_set_header Referer $http_referer;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-Port $remote_port;
proxy_set_header X-Forwarded-Host $host:$remote_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Port $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on;
location / {
proxy_pass http://127.0.0.1:5055;
}
}
```
Then, create a symlink to `/etc/nginx/sites-enabled`:
```bash
sudo ln -s /etc/nginx/sites-available/jellyseerr.example.com.conf /etc/nginx/sites-enabled/jellyseerr.example.com.conf
```
</TabItem>
<TabItem value="subfolder" label="Subfolder">
:::warning
This Nginx subfolder reverse proxy is an unsupported workaround, and only provided as an example. The filters may stop working when Jellyseerr is updated.
If you encounter any issues with Jellyseerr while using this workaround, we may ask you to try to reproduce the problem without the Nginx proxy.
:::
Add the following location block to your existing `nginx.conf` file.
```nginx
location ^~ /jellyseerr {
set $app 'jellyseerr';
# Remove /jellyseerr path to pass to the app
rewrite ^/jellyseerr/?(.*)$ /$1 break;
proxy_pass http://127.0.0.1:5055; # NO TRAILING SLASH
# Redirect location headers
proxy_redirect ^ /$app;
proxy_redirect /setup /$app/setup;
proxy_redirect /login /$app/login;
# Sub filters to replace hardcoded paths
proxy_set_header Accept-Encoding "";
sub_filter_once off;
sub_filter_types *;
sub_filter 'href="/"' 'href="/$app"';
sub_filter 'href="/login"' 'href="/$app/login"';
sub_filter 'href:"/"' 'href:"/$app"';
sub_filter '\/_next' '\/$app\/_next';
sub_filter '/_next' '/$app/_next';
sub_filter '/api/v1' '/$app/api/v1';
sub_filter '/login/plex/loading' '/$app/login/plex/loading';
sub_filter '/images/' '/$app/images/';
sub_filter '/android-' '/$app/android-';
sub_filter '/apple-' '/$app/apple-';
sub_filter '/favicon' '/$app/favicon';
sub_filter '/logo_' '/$app/logo_';
sub_filter '/site.webmanifest' '/$app/site.webmanifest';
}
```
</TabItem>
<TabItem value="swag" label="SWAG">
A sample proxy configuration is included in [SWAG (Secure Web Application Gateway)](https://github.com/linuxserver/docker-swag).
However, this page is still the only source of truth, so the SWAG sample configuration is not guaranteed to be up-to-date. If you find an inconsistency, please [report it to the LinuxServer team](https://github.com/linuxserver/reverse-proxy-confs/issues/new) or [submit a pull request to update it](https://github.com/linuxserver/reverse-proxy-confs/pulls).
To use the bundled configuration file, simply rename `jellyseerr.subdomain.conf.sample` in the `proxy-confs` folder to `jellyseerr.subdomain.conf`.
Alternatively, you can create a new file `jellyseerr.subdomain.conf` in `proxy-confs` with the following configuration:
```nginx
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name jellyseerr.*;
include /config/nginx/ssl.conf;
client_max_body_size 0;
location / {
include /config/nginx/proxy.conf;
resolver 127.0.0.11 valid=30s;
set $upstream_app jellyseerr;
set $upstream_port 5055;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
}
```
</TabItem>
<TabItem value="nginx-proxy-manager" label="Nginx Proxy Manager">
Add a new proxy host with the following settings:
### Details
- **Domain Names:** Your desired external Jellyseerr hostname; e.g., `jellyseerr.example.com`
- **Scheme:** `http`
- **Forward Hostname / IP:** Internal Jellyseerr hostname or IP
- **Forward Port:** `5055`
- **Cache Assets:** yes
- **Block Common Exploits:** yes
### SSL
- **SSL Certificate:** Select one of the options; if you are not sure, pick “Request a new SSL Certificate”
- **Force SSL:** yes
- **HTTP/2 Support:** yes
Then, click “Save” and “Apply Changes”.
</TabItem>
</Tabs>
## Caddy (v2)
Create a Caddyfile with the following content:
```caddyfile
jellyseerr.example.com {
reverse_proxy http://127.0.0.1:5055
}
```
Deploy the Caddyfile by running:
```bash
sudo caddy run --config /path/to/Caddyfile
```
Verify by visiting https://jellyseerr.example.com in your browser.
:::note
Caddy will automatically obtain and renew SSL certificates for your domain.
:::
## Traefik (v2)
Add the following labels to the Jellyseerr service in your `docker-compose.yml` file:
```yaml
labels:
- 'traefik.enable=true'
## HTTP Routers
- 'traefik.http.routers.jellyseerr-rtr.entrypoints=https'
- 'traefik.http.routers.jellyseerr-rtr.rule=Host(`jellyseerr.domain.com`)'
- 'traefik.http.routers.jellyseerr-rtr.tls=true'
## HTTP Services
- 'traefik.http.routers.jellyseerr-rtr.service=jellyseerr-svc'
- 'traefik.http.services.jellyseerr-svc.loadbalancer.server.port=5055'
```
For more information, please refer to the [Traefik documentation](https://doc.traefik.io/traefik/user-guides/docker-compose/basic-example/).

View File

@@ -1,9 +0,0 @@
{
"label": "Extending Seerr",
"position": 3,
"link": {
"type": "generated-index",
"title": "Extending Seerr",
"description": "Extend Seerr to your liking"
}
}

View File

@@ -1,170 +0,0 @@
---
title: Configuring the Database (Advanced)
description: Configure the database for Seerr
sidebar_position: 2
---
# Configuring the Database
Seerr supports SQLite and PostgreSQL. The database connection can be configured using the following environment variables:
## SQLite Options
If you want to use SQLite, you can simply set the `DB_TYPE` environment variable to `sqlite`. This is the default configuration so even if you don't set any other options, SQLite will be used.
```dotenv
DB_TYPE=sqlite # Which DB engine to use, either sqlite or postgres. The default is sqlite.
CONFIG_DIRECTORY="config" # (optional) The path to the config directory where the db file is stored. The default is "config".
DB_LOG_QUERIES="false" # (optional) Whether to log the DB queries for debugging. The default is "false".
```
## PostgreSQL Options
:::caution
When migrating Postgres from version 17 to 18 in Docker, note that the data mount point has changed. Instead of using `/var/lib/postgresql/data`, the correct mount path is now `/var/lib/postgresql`.
Refer to the [PostgreSQL Docker documentation](https://hub.docker.com/_/postgres/#pgdata) to learn how to migrate or opt out of this change.
:::
### TCP Connection
If your PostgreSQL server is configured to accept TCP connections, you can specify the host and port using the `DB_HOST` and `DB_PORT` environment variables. This is useful for remote connections where the server uses a network host and port.
```dotenv
DB_TYPE=postgres # Which DB engine to use, either sqlite or postgres. The default is sqlite.
DB_HOST="localhost" # (optional) The host (URL) of the database. The default is "localhost".
DB_PORT="5432" # (optional) The port to connect to. The default is "5432".
DB_USER= # (required) Username used to connect to the database.
DB_PASS= # (required) Password of the user used to connect to the database.
DB_NAME="seerr" # (optional) The name of the database to connect to. The default is "seerr".
DB_LOG_QUERIES="false" # (optional) Whether to log the DB queries for debugging. The default is "false".
```
### Unix Socket Connection
If your PostgreSQL server is configured to accept Unix socket connections, you can specify the path to the socket directory using the `DB_SOCKET_PATH` environment variable. This is useful for local connections where the server uses a Unix socket.
```dotenv
DB_TYPE=postgres # Which DB engine to use, either sqlite or postgres. The default is sqlite.
DB_SOCKET_PATH="/var/run/postgresql" # (required) The path to the PostgreSQL Unix socket directory.
DB_USER= # (required) Username used to connect to the database.
DB_PASS= # (optional) Password of the user used to connect to the database, depending on the server's authentication configuration.
DB_NAME="seerr" # (optional) The name of the database to connect to. The default is "seerr".
DB_LOG_QUERIES="false" # (optional) Whether to log the DB queries for debugging. The default is "false".
```
:::info
**Finding Your PostgreSQL Socket Path**
The PostgreSQL socket path varies by operating system and installation method:
- **Ubuntu/Debian**: `/var/run/postgresql`
- **CentOS/RHEL/Fedora**: `/var/run/postgresql`
- **macOS (Homebrew)**: `/tmp` or `/opt/homebrew/var/postgresql`
- **macOS (Postgres.app)**: `/tmp`
- **Windows**: Not applicable (uses TCP connections)
You can find your socket path by running:
```bash
# Find PostgreSQL socket directory
find /tmp /var/run /run -name ".s.PGSQL.*" 2>/dev/null | head -1 | xargs dirname
# Or check PostgreSQL configuration
sudo -u postgres psql -c "SHOW unix_socket_directories;"
```
:::
### SSL configuration
The following options can be used to further configure ssl. Certificates can be provided as a string or a file path, with the string version taking precedence.
```dotenv
DB_USE_SSL="false" # (optional) Whether to enable ssl for database connection. This must be "true" to use the other ssl options. The default is "false".
DB_SSL_REJECT_UNAUTHORIZED="true" # (optional) Whether to reject ssl connections with unverifiable certificates i.e. self-signed certificates without providing the below settings. The default is "true".
DB_SSL_CA= # (optional) The CA certificate to verify the connection, provided as a string. The default is "".
DB_SSL_CA_FILE= # (optional) The path to a CA certificate to verify the connection. The default is "".
DB_SSL_KEY= # (optional) The private key for the connection in PEM format, provided as a string. The default is "".
DB_SSL_KEY_FILE= # (optional) Path to the private key for the connection in PEM format. The default is "".
DB_SSL_CERT= # (optional) Certificate chain in pem format for the private key, provided as a string. The default is "".
DB_SSL_CERT_FILE= # (optional) Path to certificate chain in pem format for the private key. The default is "".
```
---
### Migrating from SQLite to PostgreSQL
1. Set up your PostgreSQL database and configure Seerr to use it
2. Run Seerr to create the tables in the PostgreSQL database
3. Stop Seerr
4. Run the following command to export the data from the SQLite database and import it into the PostgreSQL database:
:::info
Edit the postgres connection string (without the \{\{ and \}\} brackets) to match your setup.
If you don't have or don't want to use docker, you can build the working pgloader version [in this PR](https://github.com/dimitri/pgloader/pull/1531) from source and use the same options as below.
:::
:::caution
The most recent release of pgloader has an issue quoting the table columns. Use the version in the docker container to avoid this issue.
:::
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs>
<TabItem value="docker" label="Using pgloader Container (Recommended)" default>
**Recommended method**: Use the pgloader container even for standalone Seerr installations. This avoids building from source and ensures compatibility.
```bash
# For standalone installations (no Docker network needed)
docker run --rm \
-v /path/to/your/config/db.sqlite3:/db.sqlite3:ro \
ghcr.io/ralgar/pgloader:pr-1531 \
pgloader --with "quote identifiers" --with "data only" \
/db.sqlite3 postgresql://{{DB_USER}}:{{DB_PASS}}@{{DB_HOST}}:{{DB_PORT}}/{{DB_NAME}}
```
**For Docker Compose setups**: Add the network parameter if your PostgreSQL is also in a container:
```bash
docker run --rm \
--network your-seerr-network \
-v /path/to/your/config/db.sqlite3:/db.sqlite3:ro \
ghcr.io/ralgar/pgloader:pr-1531 \
pgloader --with "quote identifiers" --with "data only" \
/db.sqlite3 postgresql://{{DB_USER}}:{{DB_PASS}}@{{DB_HOST}}:{{DB_PORT}}/{{DB_NAME}}
```
</TabItem>
<TabItem value="standalone" label="Building pgloader from Source">
For users who prefer not to use Docker or need a custom build:
```bash
# Clone the repository and checkout the working version
git clone https://github.com/dimitri/pgloader.git
cd pgloader
git fetch origin pull/1531/head:pr-1531
git checkout pr-1531
# Follow the official installation instructions
# See: https://github.com/dimitri/pgloader/blob/master/INSTALL.md
```
:::info
**Building pgloader from source requires following the complete installation process outlined in the [official pgloader INSTALL.md](https://github.com/dimitri/pgloader/blob/master/INSTALL.md).**
Please refer to the official documentation for detailed, up-to-date installation instructions.
:::
Once pgloader is built, run the migration:
```bash
# Run migration (adjust path to your config directory)
./pgloader --with "quote identifiers" --with "data only" \
/path/to/your/config/db.sqlite3 \
postgresql://{{DB_USER}}:{{DB_PASS}}@{{DB_HOST}}:{{DB_PORT}}/{{DB_NAME}}
```
</TabItem>
</Tabs>
5. Start Seerr

View File

@@ -1,301 +0,0 @@
---
title: Reverse Proxy
description: Configure a reverse proxy for Seerr.
sidebar_position: 1
---
# Reverse Proxy
:::warning
Base URLs cannot be configured in Seerr. With this limitation, only subdomain configurations are supported.
A Nginx subfolder workaround configuration is provided below, but it is not officially supported.
:::
## Nginx
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs groupId="nginx-reverse-proxy" queryString>
<TabItem value="subdomain" label="Subdomain">
Add the following configuration to a new file `/etc/nginx/sites-available/seerr.example.com.conf`:
```nginx
server {
listen 80;
server_name seerr.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name seerr.example.com;
ssl_certificate /etc/letsencrypt/live/seerr.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/seerr.example.com/privkey.pem;
proxy_set_header Referer $http_referer;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-Port $remote_port;
proxy_set_header X-Forwarded-Host $host:$remote_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Port $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on;
location / {
proxy_pass http://127.0.0.1:5055;
}
}
```
Then, create a symlink to `/etc/nginx/sites-enabled`:
```bash
sudo ln -s /etc/nginx/sites-available/seerr.example.com.conf /etc/nginx/sites-enabled/seerr.example.com.conf
```
</TabItem>
<TabItem value="subfolder" label="Subfolder">
:::warning
This Nginx subfolder reverse proxy is an unsupported workaround, and only provided as an example. The filters may stop working when Seerr is updated.
If you encounter any issues with Seerr while using this workaround, we may ask you to try to reproduce the problem without the Nginx proxy.
:::
Add the following location block to your existing `nginx.conf` file.
```nginx
location ^~ /seerr {
set $app 'seerr';
# Remove /seerr path to pass to the app
rewrite ^/seerr/?(.*)$ /$1 break;
proxy_pass http://127.0.0.1:5055; # NO TRAILING SLASH
# Redirect location headers
proxy_redirect ^ /$app;
proxy_redirect /setup /$app/setup;
proxy_redirect /login /$app/login;
# Sub filters to replace hardcoded paths
proxy_set_header Accept-Encoding "";
sub_filter_once off;
sub_filter_types *;
sub_filter 'href="/"' 'href="/$app"';
sub_filter 'href="/login"' 'href="/$app/login"';
sub_filter 'href:"/"' 'href:"/$app"';
sub_filter '\/_next' '\/$app\/_next';
sub_filter '/_next' '/$app/_next';
sub_filter '/api/v1' '/$app/api/v1';
sub_filter '/login/plex/loading' '/$app/login/plex/loading';
sub_filter '/images/' '/$app/images/';
sub_filter '/imageproxy/' '/$app/imageproxy/';
sub_filter '/avatarproxy/' '/$app/avatarproxy/';
sub_filter '/android-' '/$app/android-';
sub_filter '/apple-' '/$app/apple-';
sub_filter '/favicon' '/$app/favicon';
sub_filter '/logo_' '/$app/logo_';
sub_filter '/site.webmanifest' '/$app/site.webmanifest';
}
```
</TabItem>
<TabItem value="swag" label="SWAG">
A sample proxy configuration is included in [SWAG (Secure Web Application Gateway)](https://github.com/linuxserver/docker-swag).
However, this page is still the only source of truth, so the SWAG sample configuration is not guaranteed to be up-to-date. If you find an inconsistency, please [report it to the LinuxServer team](https://github.com/linuxserver/reverse-proxy-confs/issues/new) or [submit a pull request to update it](https://github.com/linuxserver/reverse-proxy-confs/pulls).
To use the bundled configuration file, simply rename `seerr.subdomain.conf.sample` in the `proxy-confs` folder to `seerr.subdomain.conf`.
Alternatively, you can create a new file `seerr.subdomain.conf` in `proxy-confs` with the following configuration:
```nginx
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name seerr.*;
include /config/nginx/ssl.conf;
client_max_body_size 0;
location / {
include /config/nginx/proxy.conf;
resolver 127.0.0.11 valid=30s;
set $upstream_app seerr;
set $upstream_port 5055;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
}
```
</TabItem>
<TabItem value="nginx-proxy-manager" label="Nginx Proxy Manager">
Add a new proxy host with the following settings:
### Details
- **Domain Names:** Your desired external Seerr hostname; e.g., `seerr.example.com`
- **Scheme:** `http`
- **Forward Hostname / IP:** Internal Seerr hostname or IP
- **Forward Port:** `5055`
- **Cache Assets:** yes
- **Block Common Exploits:** yes
### SSL
- **SSL Certificate:** Select one of the options; if you are not sure, pick “Request a new SSL Certificate”
- **Force SSL:** yes
- **HTTP/2 Support:** yes
Then, click “Save” and “Apply Changes”.
</TabItem>
</Tabs>
## Caddy (v2)
Create a Caddyfile with the following content:
```caddyfile
seerr.example.com {
reverse_proxy http://127.0.0.1:5055
}
```
Deploy the Caddyfile by running:
```bash
sudo caddy run --config /path/to/Caddyfile
```
Verify by visiting https://seerr.example.com in your browser.
:::note
Caddy will automatically obtain and renew SSL certificates for your domain.
:::
## Traefik (v2)
Add the following labels to the Seerr service in your `compose.yaml` file:
```yaml
labels:
- 'traefik.enable=true'
## HTTP Routers
- 'traefik.http.routers.seerr-rtr.entrypoints=https'
- 'traefik.http.routers.seerr-rtr.rule=Host(`seerr.domain.com`)'
- 'traefik.http.routers.seerr-rtr.tls=true'
## HTTP Services
- 'traefik.http.routers.seerr-rtr.service=seerr-svc'
- 'traefik.http.services.seerr-svc.loadbalancer.server.port=5055'
```
For more information, please refer to the [Traefik documentation](https://doc.traefik.io/traefik/user-guides/docker-compose/basic-example/).
## Apache2 HTTP Server
<Tabs groupId="apache2-reverse-proxy" queryString>
<TabItem value="subdomain" label="Subdomain">
Add the following Location block to your existing Server configuration.
```apache
# Seerr
ProxyPreserveHost On
ProxyPass / http://localhost:5055 retry=0 connectiontimeout=5 timeout=30 keepalive=on
ProxyPassReverse http://localhost:5055 /
RequestHeader set Connection ""
```
</TabItem>
<TabItem value="subfolder" label="Subfolder">
:::warning
This Apache2 subfolder reverse proxy is an unsupported workaround, and only provided as an example. The filters may stop working when Seerr is updated.
If you encounter any issues with Seerr while using this workaround, we may ask you to try to reproduce the problem without the Apache2 proxy.
:::
Add the following Location block to your existing Server configuration.
```apache
# Seerr
# We will use "/seerr" as subfolder
# You can replace it with any that you like
<Location /seerr>
ProxyPreserveHost On
ProxyPass http://localhost:5055 retry=0 connectiontimeout=5 timeout=30 keepalive=on
ProxyPassReverse http://localhost:5055
RequestHeader set Connection ""
# Header update, to support subfolder
# Please Replace "FQDN" with your domain
Header edit location ^/login https://FQDN/seerr/login
Header edit location ^/setup https://FQDN/seerr/setup
AddOutputFilterByType INFLATE;SUBSTITUTE text/html application/javascript application/json
SubstituteMaxLineLength 2000K
# This is HTML and JS update
# Please update "/seerr" if needed
Substitute "s|href=\"|href=\"/seerr|inq"
Substitute "s|src=\"|src=\"/seerr|inq"
Substitute "s|/api/|/seerr/api/|inq"
Substitute "s|\"/_next/|\"/seerr/_next/|inq"
# This is JSON update
Substitute "s|\"/avatarproxy/|\"/seerr/avatarproxy/|inq"
</Location>
```
</TabItem>
</Tabs>
## HAProxy (v3)
:::warning
This is a third-party documentation maintained by the community. We can't provide support for this setup and are unable to test it.
:::
Add the following frontend and backend configurations for your seerr instance:
```haproxy
frontend seerr-frontend
bind 0.0.0.0:80
bind 0.0.0.0:443 ssl crt /etc/ssl/private/seerr.example.com.pem
mode http
log global
option httplog
option http-keep-alive
http-request set-header X-Real-IP %[src]
option forwardfor
acl seerr hdr(host) -i seerr.example.com
redirect scheme https code 301 if !{ ssl_fc }
use_backend seerr-backend if seerr
backend seerr-backend
mode http
log global
option httplog
http-response set-header Strict-Transport-Security max-age=15552000
option httpchk GET /api/v1/status
timeout connect 30000
timeout server 30000
retries 3
server seerr 127.0.0.1:5055 check inter 1000
```

View File

@@ -0,0 +1,39 @@
---
title: AUR (Arch User Repository)
description: Install Jellyseerr using the Arch User Repository
sidebar_position: 4
---
# AUR (Arch User Repository)
:::info
This method is not recommended for most users. It is intended for advanced users who are using Arch Linux or an Arch-based distribution.
:::
## Installation
To install Jellyseerr from the AUR, you can use an AUR helper like `yay` or `paru`:
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs groupId="aur-methods" queryString>
<TabItem value="yay" label="yay">
```bash
yay -S jellyseerr
```
</TabItem>
<TabItem value="paru" label="paru">
```bash
paru -S jellyseerr
```
</TabItem>
</Tabs>
:::info
After installing Jellyseerr, configure it by visiting the web UI at `http://[address]:5055` and completing the setup steps.
:::
:::tip
You can find the environment file at `/etc/conf.d/jellyseerr` and the service file at `/etc/systemd/system/jellyseerr.service`.
:::

View File

@@ -1,64 +1,105 @@
---
title: Build From Source (Advanced)
description: Install Seerr by building from source
description: Install Jellyseerr by building from source
sidebar_position: 2
---
# Build from Source (Advanced)
:::warning
This method is not recommended for most users. It is intended for advanced users who are familiar with managing their own server infrastructure.
Refer to [Configuring Databases](/extending-seerr/database-config#postgresql-options) for details on how to configure your database.
:::
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
### Prerequisites
- [Node.js 22.x](https://nodejs.org/en/download/)
- [Pnpm 10.x](https://pnpm.io/installation)
<Tabs groupId="versions" queryString>
<TabItem value="latest" label="Latest">
- [Node.js 18.x](https://nodejs.org/en/download/)
- [Yarn 1.x](https://classic.yarnpkg.com/lang/en/docs/install)
- [Git](https://git-scm.com/downloads)
</TabItem>
<TabItem value="develop" label="Develop">
- [Node.js 20.x](https://nodejs.org/en/download/)
- [Pnpm 9.x](https://pnpm.io/installation)
- [Git](https://git-scm.com/downloads)
</TabItem>
</Tabs>
## Unix (Linux, macOS)
### Installation
1. Assuming you want the working directory to be `/opt/seerr`, create the directory and navigate to it:
<Tabs groupId="versions" queryString>
<TabItem value="latest" label="latest">
1. Assuming you want the working directory to be `/opt/jellyseerr`, create the directory and navigate to it:
```bash
sudo mkdir -p /opt/seerr && cd /opt/seerr
sudo mkdir -p /opt/jellyseerr && cd /opt/jellyseerr
```
2. Clone the Seerr repository and checkout the main branch:
2. Clone the Jellyseerr repository and checkout the latest release:
```bash
git clone https://github.com/seerr-team/seerr.git .
git clone https://github.com/Fallenbagel/jellyseerr.git
cd jellyseerr
git checkout main
```
3. Install the dependencies:
```bash
CYPRESS_INSTALL_BINARY=0 yarn install --frozen-lockfile --network-timeout 1000000
```
4. Build the project:
```bash
yarn build
```
5. Start Jellyseerr:
```bash
yarn start
```
</TabItem>
<TabItem value="develop" label="develop">
1. Assuming you want the working directory to be `/opt/jellyseerr`, create the directory and navigate to it:
```bash
sudo mkdir -p /opt/jellyseerr && cd /opt/jellyseerr
```
2. Clone the Jellyseerr repository and checkout the develop branch:
```bash
git clone https://github.com/Fallenbagel/jellyseerr.git
cd jellyseerr
git checkout develop # by default, you are on the develop branch so this step is not necessary
```
3. Install the dependencies:
```bash
CYPRESS_INSTALL_BINARY=0 pnpm install --frozen-lockfile
```
4. Build the project:
```bash
pnpm build
```
5. Start Seerr:
5. Start Jellyseerr:
```bash
pnpm start
```
</TabItem>
</Tabs>
:::info
You can now access Seerr by visiting `http://localhost:5055` in your web browser.
You can now access Jellyseerr by visiting `http://localhost:5055` in your web browser.
:::
#### Extending the installation
<Tabs groupId="unix-extensions" queryString>
<TabItem value="linux" label="Linux">
To run seerr as a systemd service:
1. create the environment file at `/etc/seerr/seerr.conf`:
To run jellyseerr as a systemd service:
1. create the environment file at `/etc/jellyseerr/jellyseerr.conf`:
```bash
## Seerr's default port is 5055, if you want to use both, change this.
## Jellyseerr's default port is 5055, if you want to use both, change this.
## specify on which port to listen
PORT=5055
## specify on which interface to listen, by default seerr listens on all interfaces
## specify on which interface to listen, by default jellyseerr listens on all interfaces
#HOST=127.0.0.1
## Uncomment if your media server is emby instead of jellyfin.
# JELLYFIN_TYPE=emby
## Uncomment if you want to force Node.js to resolve IPv4 before IPv6 (advanced users only)
# FORCE_IPV4_FIRST=true
```
@@ -68,19 +109,19 @@ which node
```
Copy the path to node, it should be something like `/usr/bin/node`.
3. Create the systemd service file at `/etc/systemd/system/seerr.service`, using either `sudo systemctl edit seerr` or `sudo nano /etc/systemd/system/seerr.service`:
3. Create the systemd service file at `/etc/systemd/system/jellyseerr.service`, using either `sudo systemctl edit jellyseerr` or `sudo nano /etc/systemd/system/jellyseerr.service`:
```bash
[Unit]
Description=Seerr Service
Description=Jellyseerr Service
Wants=network-online.target
After=network-online.target
[Service]
EnvironmentFile=/etc/seerr/seerr.conf
EnvironmentFile=/etc/jellyseerr/jellyseerr.conf
Environment=NODE_ENV=production
Type=exec
Restart=on-failure
WorkingDirectory=/opt/seerr
WorkingDirectory=/opt/jellyseerr
ExecStart=/usr/bin/node dist/index.js
[Install]
@@ -92,33 +133,33 @@ If you are using a different path to node, replace `/usr/bin/node` with the path
4. Enable and start the service:
```bash
sudo systemctl enable seerr
sudo systemctl start seerr
sudo systemctl enable jellyseerr
sudo systemctl start jellyseerr
```
</TabItem>
<TabItem value="macos" label="macOS">
To run seerr as a launchd service:
To run jellyseerr as a launchd service:
1. Find the path to node:
```bash
which node
```
Copy the path to node, it should be something like `/usr/local/bin/node`.
2. Create a launchd plist file at `~/Library/LaunchAgents/com.seerr.plist`:
2. Create a launchd plist file at `~/Library/LaunchAgents/com.jellyseerr.plist`:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.seerr</string>
<string>com.jellyseerr</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/node</string>
<string>/opt/seerr/dist/index.js</string>
<string>/opt/jellyseerr/dist/index.js</string>
</array>
<key>WorkingDirectory</key>
<string>/opt/seerr</string>
<string>/opt/jellyseerr</string>
<key>EnvironmentVariables</key>
<dict>
<key>NODE_ENV</key>
@@ -138,11 +179,11 @@ If you are using a different path to node, replace `/usr/local/bin/node` with th
:::
3. Load the service:
```bash
sudo launchctl load ~/Library/LaunchAgents/com.seerr.plist
sudo launchctl load ~/Library/LaunchAgents/com.jellyseerr.plist
```
3. Start the service:
```bash
sudo launchctl start com.seerr
sudo launchctl start com.jellyseerr
```
4. To ensure the service starts on boot, run the following command:
```bash
@@ -150,14 +191,14 @@ sudo lauchctl load
```
</TabItem>
<TabItem value="pm2" label="PM2">
To run seerr as a PM2 service:
To run jellyseerr as a PM2 service:
1. Install PM2:
```bash
npm install -g pm2
```
2. Start seerr with PM2:
2. Start jellyseerr with PM2:
```bash
pm2 start dist/index.js --name seerr --node-args="--NODE_ENV=production"
pm2 start dist/index.js --name jellyseerr --node-args="--NODE_ENV=production"
```
3. Save the process list:
```bash
@@ -170,66 +211,95 @@ pm2 startup
**Managing the service**
- To start the service:
```powershell
pm2 start seerr
pm2 start jellyseerr
```
- To stop the service:
```powershell
pm2 stop seerr
pm2 stop jellyseerr
```
- To restart the service:
```powershell
pm2 restart seerr
pm2 restart jellyseerr
```
- To view the logs:
```powershell
pm2 logs seerr
pm2 logs jellyseerr
```
- To view the status:
```powershell
pm2 status seerr
pm2 status jellyseerr
```
</TabItem>
</Tabs>
## Windows
### Installation
1. Assuming you want the working directory to be `C:\seerr`, create the directory and navigate to it:
<Tabs groupId="versions" queryString>
<TabItem value="latest" label="latest">
1. Assuming you want the working directory to be `C:\jellyseerr`, create the directory and navigate to it:
```powershell
mkdir C:\seerr
cd C:\seerr
mkdir C:\jellyseerr
cd C:\jellyseerr
```
2. Clone the Seerr repository and checkout the main branch:
2. Clone the Jellyseerr repository and checkout the latest release:
```powershell
git clone https://github.com/seerr-team/seerr.git .
git clone https://github.com/Fallenbagel/jellyseerr.git .
git checkout main
```
3. Install the dependencies:
```powershell
npm install -g win-node-env
set CYPRESS_INSTALL_BINARY=0 && yarn install --frozen-lockfile --network-timeout 1000000
```
4. Build the project:
```powershell
yarn build
```
5. Start Jellyseerr:
```powershell
yarn start
```
</TabItem>
<TabItem value="develop" label="develop">
1. Assuming you want the working directory to be `C:\jellyseerr`, create the directory and navigate to it:
```powershell
mkdir C:\jellyseerr
cd C:\jellyseerr
```
2. Clone the Jellyseerr repository and checkout the develop branch:
```powershell
git clone https://github.com/Fallenbagel/jellyseerr.git .
git checkout develop # by default, you are on the develop branch so this step is not necessary
```
3. Install the dependencies:
```powershell
npm install -g win-node-env
set CYPRESS_INSTALL_BINARY=0 && pnpm install --frozen-lockfile
```
4. Build the project:
```powershell
pnpm build
```
5. Start Seerr:
5. Start Jellyseerr:
```powershell
pnpm start
```
</TabItem>
</Tabs>
:::tip
You can add the environment variables to a `.env` file in the Seerr directory.
You can add the environment variables to a `.env` file in the Jellyseerr directory.
:::
:::info
You can now access Seerr by visiting `http://localhost:5055` in your web browser.
You can now access Jellyseerr by visiting `http://localhost:5055` in your web browser.
:::
#### Extending the installation
<Tabs groupId="windows-extensions" queryString>
<TabItem value="task-scheduler" label="Task Scheduler">
To run seerr as a bat script:
1. Create a file named `start-seerr.bat` in the seerr directory:
To run jellyseerr as a bat script:
1. Create a file named `start-jellyseerr.bat` in the jellyseerr directory:
```bat
@echo off
set PORT=5055
@@ -239,43 +309,41 @@ node dist/index.js
2. Create a task in Task Scheduler:
- Open Task Scheduler
- Click on "Create Basic Task"
- Name the task "Seerr"
- Name the task "Jellyseerr"
- Set the trigger to "When the computer starts"
- Set the action to "Start a program"
- Set the program/script to the path of the `start-seerr.bat` file
- Set the "Start in" to the seerr directory.
- Set the program/script to the path of the `start-jellyseerr.bat` file
- Click "Finish"
Now, Seerr will start when the computer boots up in the background.
Now, Jellyseerr will start when the computer boots up in the background.
</TabItem>
<TabItem value="nssm" label="NSSM">
To run seerr as a service:
To run jellyseerr as a service:
1. Download the [Non-Sucking Service Manager](https://nssm.cc/download)
2. Install NSSM:
```powershell
nssm install Seerr "C:\Program Files\nodejs\node.exe" "C:\seerr\dist\index.js"
nssm set Seerr AppDirectory "C:\seerr"
nssm set Seerr AppEnvironmentExtra NODE_ENV=production
nssm install Jellyseerr "C:\Program Files\nodejs\node.exe" ["C:\jellyseerr\dist\index.js"]
nssm set Jellyseerr AppEnvironmentExtra NODE_ENV=production
```
3. Start the service:
```powershell
nssm start Seerr
nssm start Jellyseerr
```
4. To ensure the service starts on boot, run the following command:
```powershell
nssm set Seerr Start SERVICE_AUTO_START
nssm set Jellyseerr Start SERVICE_AUTO_START
```
</TabItem>
<TabItem value="pm2" label="PM2">
To run seerr as a PM2 service:
To run jellyseerr as a PM2 service:
1. Install PM2:
```powershell
npm install -g pm2
```
2. Start seerr with PM2:
2. Start jellyseerr with PM2:
```powershell
pm2 start dist/index.js --name seerr --node-args="--NODE_ENV=production"
pm2 start dist/index.js --name jellyseerr --node-args="--NODE_ENV=production"
```
3. Save the process list:
```powershell
@@ -288,31 +356,31 @@ pm2 startup
##### Managing the service
- To start the service:
```powershell
pm2 start seerr
pm2 start jellyseerr
```
- To stop the service:
```powershell
pm2 stop seerr
pm2 stop jellyseerr
```
- To restart the service:
```powershell
pm2 restart seerr
pm2 restart jellyseerr
```
- To view the logs:
```powershell
pm2 logs seerr
pm2 logs jellyseerr
```
- To view the status:
```powershell
pm2 status seerr
pm2 status jellyseerr
```
</TabItem>
</Tabs>
### Updating
To update Seerr, navigate to the Seerr directory and run the following commands:
To update Jellyseerr, navigate to the Jellyseerr directory and run the following commands:
```bash
git pull
```
Then, follow the steps in the installation section to rebuild and restart Seerr.
Then, follow the steps in the installation section to rebuild and restart Jellyseerr.

View File

@@ -1,29 +1,17 @@
---
title: Docker (Recommended)
description: Install Seerr using Docker
description: Install Jellyseerr using Docker
sidebar_position: 1
---
# Docker
:::info
This is the recommended method for most users.
Details on how to install Docker can be found on the [official Docker website](https://docs.docker.com/get-docker/).
Refer to [Configuring Databases](/extending-seerr/database-config#postgresql-options) for details on how to configure your database.
:::
:::info
An alternative Docker image is available on Docker Hub for this project. You can find it at [Docker Hub Repository Link](https://hub.docker.com/r/seerr/seerr)
:::
:::info
All official Seerr images are cryptographically signed and include a verified [Software Bill of Materials (SBOM)](https://cyclonedx.org/).
To confirm that the container image you are using is authentic and unmodified, please refer to the [Verifying Signed Artifacts](/using-seerr/advanced/verifying-signed-artifacts#verifying-signed-images) guide.
:::
## Unix (Linux, macOS)
:::warning
Be sure to replace `/path/to/appdata/config` in the below examples with a valid host directory path. If this volume mount is not configured correctly, your Seerr settings/data will not be persisted when the container is recreated (e.g., when updating the image or rebooting your machine).
Be sure to replace `/path/to/appdata/config` in the below examples with a valid host directory path. If this volume mount is not configured correctly, your Jellyseerr settings/data will not be persisted when the container is recreated (e.g., when updating the image or rebooting your machine).
The `TZ` environment variable value should also be set to the [TZ database name](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) of your time zone!
@@ -40,27 +28,20 @@ For details on the Docker CLI, please [review the official `docker run` document
```bash
docker run -d \
--name seerr \
--init \
--name jellyseerr \
-e LOG_LEVEL=debug \
-e TZ=Asia/Tashkent \
-e PORT=5055 \
-e PORT=5055 `#optional` \
-p 5055:5055 \
-v /path/to/appdata/config:/app/config \
--restart unless-stopped \
ghcr.io/seerr-team/seerr:latest
fallenbagel/jellyseerr
```
:::tip
If you are using emby, make sure to set the `JELLYFIN_TYPE` environment variable to `emby`.
The argument `-e PORT=5055` is optional.
If you want to add a healthcheck to the above command, you can add the following flags :
```
--health-cmd "wget --no-verbose --tries=1 --spider http://localhost:5055/api/v1/status || exit 1" \
--health-start-period 20s \
--health-timeout 3s \
--health-interval 15s \
--health-retries 3 \
```
`-e JELLYFIN_TYPE=emby`
:::
To run the container as a specific user/group, you may optionally add `--user=[ user | user:group | uid | uid:gid | user:gid | uid:group ]` to the above command.
@@ -68,11 +49,11 @@ To run the container as a specific user/group, you may optionally add `--user=[
Stop and remove the existing container:
```bash
docker stop seerr && docker rm seerr
docker stop jellyseerr && docker rm Jellyseerr
```
Pull the latest image:
```bash
docker pull ghcr.io/seerr-team/seerr:latest
docker pull fallenbagel/jellyseerr
```
Finally, run the container with the same parameters originally used to create the container:
```bash
@@ -80,7 +61,7 @@ docker run -d ...
```
:::tip
You may alternatively use a third-party updating mechanism, such as [Watchtower](https://github.com/containrrr/watchtower) or [Ouroboros](https://github.com/pyouroboros/ouroboros), to keep Seerr up-to-date automatically.
You may alternatively use a third-party updating mechanism, such as [Watchtower](https://github.com/containrrr/watchtower) or [Ouroboros](https://github.com/pyouroboros/ouroboros), to keep Jellyseerr up-to-date automatically.
You could also use [diun](https://github.com/crazy-max/diun) to receive notifications when a new image is available.
:::
@@ -90,14 +71,13 @@ You could also use [diun](https://github.com/crazy-max/diun) to receive notifica
For details on how to use Docker Compose, please [review the official Compose documentation](https://docs.docker.com/compose/reference/).
#### Installation:
Define the `seerr` service in your `compose.yaml` as follows:
Define the `jellyseerr` service in your `docker-compose.yml` as follows:
```yaml
---
services:
seerr:
image: ghcr.io/seerr-team/seerr:latest
init: true
container_name: seerr
jellyseerr:
image: fallenbagel/jellyseerr:latest
container_name: jellyseerr
environment:
- LOG_LEVEL=debug
- TZ=Asia/Tashkent
@@ -106,28 +86,25 @@ services:
- 5055:5055
volumes:
- /path/to/appdata/config:/app/config
healthcheck:
test: wget --no-verbose --tries=1 --spider http://localhost:5055/api/v1/status || exit 1
start_period: 20s
timeout: 3s
interval: 15s
retries: 3
restart: unless-stopped
```
:::tip
If you are using emby, make sure to set the `JELLYFIN_TYPE` environment variable to `emby`.
:::
Then, start all services defined in the Compose file:
```bash
docker compose up -d
docker-compose up -d
```
#### Updating:
Pull the latest image:
```bash
docker compose pull seerr
docker-compose pull jellyseerr
```
Then, restart all services defined in the Compose file:
```bash
docker compose up -d
docker-compose up -d
```
:::tip
You may alternatively use a third-party mechanism like [dockge](https://github.com/louislam/dockge) to manage your docker compose files.
@@ -135,6 +112,16 @@ You may alternatively use a third-party mechanism like [dockge](https://github.c
</TabItem>
</Tabs>
## Unraid
1. Ensure you have the **Community Applications** plugin installed.
2. Inside the **Community Applications** app store, search for **Jellyseerr**.
3. Click the **Install Button**.
4. On the following **Add Container** screen, make changes to the **Host Port** and **Host Path 1** \(Appdata\) as needed.
5. If you want to use emby, make sure to set the `JELLYFIN_TYPE` environment variable to `emby`. Otherwise, remove the variable.
6. Click apply and access "Jellyseerr" at your `<ServerIP:HostPort>` in a web browser.
## Windows
Please refer to the [Docker Desktop for Windows user manual](https://docs.docker.com/docker-for-windows/) for details on how to install Docker on Windows. There is no need to install a Linux distro if using named volumes like in the example below.
@@ -142,52 +129,22 @@ Please refer to the [Docker Desktop for Windows user manual](https://docs.docker
**WSL2 will need to be installed to prevent DB corruption!** Please see the [Docker Desktop WSL 2 backend documentation](https://docs.docker.com/docker-for-windows/wsl/) for instructions on how to enable WSL2. The commands below will only work with WSL2 installed!
:::
First, create a volume to store the configuration data for Seerr using using either the Docker CLI:
First, create a volume to store the configuration data for Jellyseerr using using either the Docker CLI:
```bash
docker volume create seerr-data
docker volume create jellyseerr-data
```
or the Docker Desktop app:
1. Open the Docker Desktop app
2. Head to the Volumes tab
3. Click on the "New Volume" button near the top right
4. Enter a name for the volume (example: `seerr-data`) and hit "Create"
4. Enter a name for the volume (example: `jellyseerr-data`) and hit "Create"
Then, create and start the Seerr container:
Then, create and start the Jellyseerr container:
<Tabs groupId="docker-methods" queryString>
<TabItem value="docker-cli" label="Docker CLI">
```bash
docker run -d \
--name seerr \
--init \
-e LOG_LEVEL=debug \
-e TZ=Asia/Tashkent \
-e PORT=5055 \
-p 5055:5055 \
-v seerr-data:/app/config \
--restart unless-stopped \
ghcr.io/seerr-team/seerr:latest
```
The argument `-e PORT=5055` is optional.
If you want to add a healthcheck to the above command, you can add the following flags :
```
--health-cmd "wget --no-verbose --tries=1 --spider http://localhost:5055/api/v1/status || exit 1" \
--health-start-period 20s \
--health-timeout 3s \
--health-interval 15s \
--health-retries 3 \
```
#### Updating:
Pull the latest image:
```bash
docker compose pull seerr
```
Then, restart all services defined in the Compose file:
```bash
docker compose up -d
docker run -d --name jellyseerr -e LOG_LEVEL=debug -e TZ=Asia/Tashkent -p 5055:5055 -v "jellyseerr-data:/app/config" --restart unless-stopped fallenbagel/jellyseerr:latest
```
</TabItem>
@@ -195,43 +152,32 @@ docker compose up -d
```yaml
---
services:
seerr:
image: ghcr.io/seerr-team/seerr:latest
init: true
container_name: seerr
jellyseerr:
image: fallenbagel/jellyseerr:latest
container_name: jellyseerr
environment:
- LOG_LEVEL=debug
- TZ=Asia/Tashkent
ports:
- 5055:5055
volumes:
- seerr-data:/app/config
healthcheck:
test: wget --no-verbose --tries=1 --spider http://localhost:5055/api/v1/status || exit 1
start_period: 20s
timeout: 3s
interval: 15s
retries: 3
- jellyseerr-data:/app/config
restart: unless-stopped
volumes:
seerr-data:
jellyseerr-data:
external: true
```
#### Updating:
Pull the latest image:
```bash
docker compose pull seerr
```
Then, restart all services defined in the Compose file:
```bash
docker compose up -d
```
</TabItem>
</Tabs>
To access the files inside the volume created above, navigate to `\\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes\seerr-data\_data` using File Explorer.
:::tip
If you are using a named volume, then you can safely **ignore** the warning about the `/app/config` folder being incorrectly mounted.
If you are using emby, make sure to set the `JELLYFIN_TYPE` environment variable to `emby`.
:::
To access the files inside the volume created above, navigate to `\\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes\jellyseerr-data\_data` using File Explorer.
:::info
Docker on Windows works differently than it does on Linux; it runs Docker inside of a stripped-down Linux VM. Volume mounts are exposed to Docker inside this VM via SMB mounts. While this is fine for media, it is unacceptable for the `/app/config` directory because SMB does not support file locking. This will eventually corrupt your database, which can lead to slow behavior and crashes.
@@ -239,6 +185,3 @@ Docker on Windows works differently than it does on Linux; it runs Docker inside
**If you must run Docker on Windows, you should put the `/app/config` directory mount inside the VM and not on the Windows host.** (This also applies to other containers with SQLite databases.)
Named volumes, like in the example commands above, are automatically mounted inside the VM. Therefore the warning on the setup about the `/app/config` folder being incorrectly mounted page should be ignored.
:::

View File

@@ -4,7 +4,7 @@ title: Getting Started
import DocCardList from '@theme/DocCardList';
:::info
After running Seerr for the first time, configure it by visiting the web UI at `http://[address]:5055` and completing the setup steps.
After running Jellyseerr for the first time, configure it by visiting the web UI at `http://[address]:5055` and completing the setup steps.
:::
<DocCardList />
<DocCardList />

View File

@@ -1,26 +0,0 @@
---
title: Kubernetes (Advanced)
description: Install Seerr in Kubernetes
sidebar_position: 3
---
# Kubernetes
:::warning
This method is not recommended for most users. It is intended for advanced users who are using Kubernetes.
:::
:::info
All official Seerr charts are cryptographically signed and include a verified [Software Bill of Materials (SBOM)](https://cyclonedx.org/).
To confirm that the chart you are using is authentic and unmodified, please refer to the [Verifying Signed Artifacts](/using-seerr/advanced/verifying-signed-artifacts#verifying-signed-helm-charts) guide.
:::
## Installation
```console
helm install seerr oci://ghcr.io/seerr-team/seerr/seerr-chart
```
Helm values can be found in the Seerr repository under [charts/seerr-chart/README.md](https://github.com/seerr-team/seerr/tree/develop/charts/seerr-chart).
Verify the signature with [cosign](https://docs.sigstore.dev/cosign/system_config/installation/) (replace [tag], with the TAG you want to verify) :
```console
cosign verify ghcr.io/seerr-team/seerr/seerr-chart:[tag] --certificate-identity=https://github.com/seerr-team/seerr/.github/workflows/helm.yml@refs/heads/main --certificate-oidc-issuer=https://token.actions.githubusercontent.com
```

View File

@@ -0,0 +1,225 @@
---
title: Nix Package Manager (Advanced)
description: Install Jellyseerr using Nix
sidebar_position: 3
---
import { JellyseerrVersion, NixpkgVersion } from '@site/src/components/JellyseerrVersion';
import Admonition from '@theme/Admonition';
# Nix Package Manager (Advanced)
:::info
This method is not recommended for most users. It is intended for advanced users who are using Nix as their package manager.
:::
export const VersionMismatchWarning = () => {
const jellyseerrVersion = JellyseerrVersion();
const nixpkgVersion = NixpkgVersion();
const isUpToDate = jellyseerrVersion === nixpkgVersion;
return (
<>
{!isUpToDate ? (
<Admonition type="warning">
The <a href="https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/servers/jellyseerr/default.nix#L14">upstream Jellyseerr Nix Package (v{nixpkgVersion})</a> is not <b>up-to-date</b>. If you want to use <b>Jellyseerr v{jellyseerrVersion}</b>, you will need to <a href="#overriding-the-package-derivation">override the package derivation</a>.
</Admonition>
) : (
<Admonition type="success">
The <a href="https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/servers/jellyseerr/default.nix#L14">upstream Jellyseerr Nix Package (v{nixpkgVersion})</a> is <b>up-to-date</b> with <b>Jellyseerr v{jellyseerrVersion}</b>.
</Admonition>
)}
</>
);
};
<VersionMismatchWarning />
## Installation
To get up and running with jellyseerr using Nix, you can add the following to your `configuration.nix`:
```nix
{ config, pkgs, ... }:
{
services.jellyseerr.enable = true;
}
```
If you want more advanced configuration options, you can use the following:
```nix
{ config, pkgs, ... }:
{
services.jellyseerr = {
enable = true;
port = 5055;
openFirewall = true;
};
}
```
After adding the configuration to your `configuration.nix`, you can run the following command to install jellyseerr:
```bash
nixos-rebuild switch
```
After rebuild is complete jellyseerr should be running, verify that it is with the following command.
```bash
systemctl status jellyseerr
```
:::info
You can now access Jellyseerr by visiting `http://localhost:5055` in your web browser.
:::
import CodeBlock from '@theme/CodeBlock';
## Overriding the package derivation
export const VersionMatch = () => {
const jellyseerrVersion = JellyseerrVersion();
const nixpkgVersion = NixpkgVersion();
const code = `{ config, pkgs, ... }:
{
nixpkgs.config.packageOverrides = pkgs: {
jellyseerr = pkgs.jellyseerr.overrideAttrs (oldAttrs: rec {
version = "${jellyseerrVersion}";
src = pkgs.fetchFromGitHub {
rev = "v\${version}";
sha256 = pkgs.lib.fakeSha256;
};
offlineCache = pkgs.fetchYarnDeps {
sha256 = pkgs.lib.fakeSha256;
};
});
};
}`;
const module = `{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.jellyseerr;
in
{
meta.maintainers = [ maintainers.camillemndn ];
disabledModules = [ "services/misc/jellyseerr.nix" ];
options.services.jellyseerr = {
enable = mkEnableOption (mdDoc ''Jellyseerr, a requests manager for Jellyfin'');
openFirewall = mkOption {
type = types.bool;
default = false;
description = mdDoc ''Open port in the firewall for the Jellyseerr web interface.'';
};
port = mkOption {
type = types.port;
default = 5055;
description = mdDoc ''The port which the Jellyseerr web UI should listen to.'';
};
package = mkOption {
type = types.package;
default = pkgs.jellyseerr;
defaultText = literalExpression "pkgs.jellyseerr";
description = lib.mdDoc ''
Jellyseerr package to use.
'';
};
};
config = mkIf cfg.enable {
systemd.services.jellyseerr = {
description = "Jellyseerr, a requests manager for Jellyfin";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
environment.PORT = toString cfg.port;
serviceConfig = {
Type = "exec";
StateDirectory = "jellyseerr";
WorkingDirectory = "\${cfg.package}/libexec/jellyseerr/deps/jellyseerr";
DynamicUser = true;
ExecStart = "\${cfg.package}/bin/jellyseerr";
BindPaths = [ "/var/lib/jellyseerr/:\${cfg.package}/libexec/jellyseerr/deps/jellyseerr/config/" ];
Restart = "on-failure";
ProtectHome = true;
ProtectSystem = "strict";
PrivateTmp = true;
PrivateDevices = true;
ProtectHostname = true;
ProtectClock = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
NoNewPrivileges = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
RemoveIPC = true;
PrivateMounts = true;
};
};
networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [ cfg.port ];
};
};
}`;
const configuration = `{ config, pkgs, ... }:
{
imports = [ ./jellyseerr-module.nix ]
services.jellyseerr = {
enable = true;
port = 5055;
openFirewall = true;
package = (pkgs.callPackage (import ../../../pkgs/jellyseerr) { });
};
}`;
const isUpToDate = jellyseerrVersion === nixpkgVersion;
return (
<>
{isUpToDate ? (
<>
<p>The latest version of Jellyseerr <strong>({jellyseerrVersion})</strong> and the Jellyseerr nixpkg package version <strong>({nixpkgVersion})</strong> is <strong>up-to-date</strong>.</p>
<p>There is no need to override the package derivation.</p>
</>
) : (
<>
<p>The latest version of Jellyseerr <strong>({jellyseerrVersion})</strong> and the Jellyseerr nixpkg version <strong>(v{nixpkgVersion})</strong> is <strong>out-of-date</strong>.
If you want to use <b>Jellyseerr v{jellyseerrVersion}</b>, you will need to override the package derivation.</p>
<p>In order to override the package derivation:</p>
<ol>
<li style={{ marginBottom: '1rem' }}>Grab the <a href="https://raw.githubusercontent.com/NixOS/nixpkgs/nixos-unstable/pkgs/servers/jellyseerr/default.nix">latest nixpkg derivation for Jellyseerr</a></li>
<li style={{ marginBottom: '1rem' }}>Grab the latest <a href="https://raw.githubusercontent.com/Fallenbagel/jellyseerr/main/package.json">package.json</a> for Jellyseerr</li>
<li style={{ marginBottom: '1rem' }}>Add it to the same directory as the nixpkg derivation</li>
<li style={{ marginBottom: '1rem' }}>Update the `src` and `offlineCache` attributes in the nixpkg derivation:</li>
<CodeBlock className="language-nix" style={{ marginBottom: '1rem' }}>{code}</CodeBlock>
<Admonition type="tip" style={{ marginBottom: '1rem' }}>You can replace the <b>sha256</b> with the actual hash that <b>nixos-rebuild</b> outputs when you run the command.</Admonition>
<li style={{ marginBottom: '1rem' }}>Grab this module and import it in your `configuration.nix`</li>
<CodeBlock className="language-nix" style={{ marginBottom: '1rem' }}>{module}</CodeBlock>
<Admonition type="tip" style={{ marginBottom: '1rem' }}>We are using a custom module because the upstream module does not have a package option.</Admonition>
<li style={{ marginBottom: '1rem' }}>Call the new package in your `configuration.nix`</li>
<CodeBlock className="language-nix" style={{ marginBottom: '1rem' }}>{configuration}</CodeBlock>
</ol>
</>
)}
</>
);
};
<VersionMatch />

View File

@@ -1,42 +0,0 @@
---
title: AUR (Advanced)
description: Install Seerr using the Arch User Repository
sidebar_position: 2
---
# AUR
:::warning
Third-party installation methods are maintained by the community. The Seerr team is not responsible for these packages.
:::
:::warning
This method is not recommended for most users. It is intended for advanced users who are using Arch Linux or an Arch-based distribution.
:::
## Installation
To install Seerr from the AUR, you can use an AUR helper like `yay` or `paru`:
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs groupId="aur-methods" queryString>
<TabItem value="yay" label="yay">
```bash
yay -S seerr
```
</TabItem>
<TabItem value="paru" label="paru">
```bash
paru -S seerr
```
</TabItem>
</Tabs>
:::info
After installing Seerr, configure it by visiting the web UI at `http://[address]:5055` and completing the setup steps.
:::
:::tip
You can find the environment file at `/etc/conf.d/seerr` and the service file at `/etc/systemd/system/seerr.service`.
:::

View File

@@ -1,11 +0,0 @@
---
title: Third-party Installation Methods
---
import DocCardList from '@theme/DocCardList';
:::warning
Third-party installation methods are maintained by the community. The Seerr team is not responsible for these packages.
:::
<DocCardList />

View File

@@ -1,17 +0,0 @@
---
title: Nix Package Manager (Advanced)
description: Install Seerr using Nixpkgs
sidebar_position: 1
---
import { SeerrVersion, NixpkgVersion } from '@site/src/components/SeerrVersion';
import Admonition from '@theme/Admonition';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# Nix Package Manager
:::warning
Third-party installation methods are maintained by the community. The Seerr team is not responsible for these packages.
:::
Refer to [NixOS documentation](https://search.nixos.org/options?channel=25.05&query=seerr)

View File

@@ -1,20 +0,0 @@
---
title: Unraid (Advanced)
description: Install Seerr using Unraid
sidebar_position: 3
---
# Unraid
:::warning
Third-party installation methods are maintained by the community. The Seerr team is not responsible for these packages.
:::
:::warning
This method is not recommended for most users. It is intended for advanced users who are using Unraid.
:::
1. Ensure you have the **Community Applications** plugin installed.
2. Inside the **Community Applications** app store, search for **Seerr**.
3. Click the **Install Button**.
4. On the following **Add Container** screen, make changes to the **Host Port** and **Host Path 1** \(Appdata\) as needed.
5. Click apply and access "Seerr" at your `<ServerIP:HostPort>` in a web browser.

View File

@@ -1,168 +0,0 @@
---
title: Migration guide
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Whether you come from Overseerr or Jellyseerr, you don't need to perform any manual migration steps, your instance will automatically be migrated to Seerr.
This migration will run automatically the first time you start your instance using the Seerr codebase (Docker image or source build or Kubernetes, etc.).
An additional migration will happen for Overseerr users, to migrate their configuration to the new codebase.
:::warning
Before doing anything you should backup your existing instance so that you can rollback in case something goes wrong.
See [Backups](/using-seerr/backups) for details on how to properly backup your instance.
:::
## Docker
Refer to [Seerr Docker Documentation](/getting-started/docker), all of our examples have been updated to reflect the below change.
Changes :
- Renamed all references from `overseerr` or `jellyseerr` to `seerr`.
- The container image reference has been updated.
- The container can now be run as a non-root user (`node` user); remove the `user` directive if you have configured it.
- The container no longer provides an init process, so you must configure it by adding `init: true` for Docker Compose or `--init` for the Docker CLI.
:::info
**Config folder permissions**: Since the container now runs as the `node` user (UID 1000), you must ensure your config folder has the correct permissions. The `node` user must have read and write access to the `/app/config` directory.
If you're migrating from a previous installation, you may need to update the ownership of your config folder:
```bash
docker run --rm -v /path/to/appdata/config:/data alpine chown -R 1000:1000 /data
```
This ensures the `node` user (UID 1000) owns the config directory and can read and write to it.
:::
### Unix
Summary of changes :
<Tabs groupId="docker-methods" queryString>
<TabItem value="docker-compose" label="Docker compose">
```yaml {3-6}
---
services:
seerr:
image: ghcr.io/seerr-team/seerr:latest
init: true
container_name: seerr
environment:
- LOG_LEVEL=debug
- TZ=Asia/Tashkent
- PORT=5055 #optional
ports:
- 5055:5055
volumes:
- /path/to/appdata/config:/app/config
healthcheck:
test: wget --no-verbose --tries=1 --spider http://localhost:5055/api/v1/status || exit 1
start_period: 20s
timeout: 3s
interval: 15s
retries: 3
restart: unless-stopped
```
</TabItem>
<TabItem value="docker-cli" label="Docker CLI">
```bash {2-3,10}
docker run -d \
--name seerr \
--init \
-e LOG_LEVEL=debug \
-e TZ=Asia/Tashkent \
-e PORT=5055 \
-p 5055:5055 \
-v /path/to/appdata/config:/app/config \
--restart unless-stopped \
ghcr.io/seerr-team/seerr:latest
```
</TabItem>
</Tabs>
### Windows
Summary of changes :
<Tabs groupId="docker-methods" queryString>
<TabItem value="docker-compose" label="Docker compose">
```yaml {3-6,13,23}
---
services:
seerr:
image: ghcr.io/seerr-team/seerr:latest
init: true
container_name: seerr
environment:
- LOG_LEVEL=debug
- TZ=Asia/Tashkent
ports:
- 5055:5055
volumes:
- seerr-data:/app/config
healthcheck:
test: wget --no-verbose --tries=1 --spider http://localhost:5055/api/v1/status || exit 1
start_period: 20s
timeout: 3s
interval: 15s
retries: 3
restart: unless-stopped
volumes:
seerr-data:
external: true
```
</TabItem>
<TabItem value="docker-cli" label="Docker CLI">
```bash {2-3,8,10}
docker run -d \
--name seerr \
--init \
-e LOG_LEVEL=debug \
-e TZ=Asia/Tashkent \
-e PORT=5055 \
-p 5055:5055 \
-v seerr-data:/app/config \
--restart unless-stopped \
ghcr.io/seerr-team/seerr:latest
```
</TabItem>
</Tabs>
## Kubernetes
Refer to [Seerr Kubernetes Documentation](/getting-started/kubernetes), all of our examples have been updated to reflect the below change.
Changes :
- All references to `jellyseerr` have been renamed to `seerr` in the manifests.
- The container image reference has been updated.
- The default `securityContext` and `podSecurityContext` have been updated to support running the container without root permissions.
Summary of changes :
<Tabs groupId="kubernetes-values" queryString>
<TabItem value="old" label="Old values">
```yaml
image:
repository: fallenbagel/jellyseerr
podSecurityContext: {}
securityContext: {}
```
</TabItem>
<TabItem value="new" label="New values">
```yaml
image:
repository: seerr-team/seerr
podSecurityContext:
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: false
runAsNonRoot: true
privileged: false
runAsUser: 1000
runAsGroup: 1000
seccompProfile:
type: RuntimeDefault
```
</TabItem>
</Tabs>

View File

@@ -1,209 +0,0 @@
---
title: Troubleshooting
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
## [TMDB] failed to retrieve/fetch XXX
### Option 1: Change your DNS servers
This error often comes from your Internet Service Provider (ISP) blocking TMDB API. The ISP may block the DNS resolution to the TMDB API hostname.
To fix this, you can change your DNS servers to a public DNS service like Google's DNS or Cloudflare's DNS:
<Tabs groupId="methods" queryString>
<TabItem value="docker-cli" label="Docker CLI">
Add the following to your `docker run` command to use Google's DNS:
```bash
--dns=8.8.8.8
```
or for Cloudflare's DNS:
```bash
--dns=1.1.1.1
```
or for Quad9 DNS:
```bash
--dns=9.9.9.9
```
You can try them all and see which one works for your network.
</TabItem>
<TabItem value="docker-compose" label="Docker Compose">
Add the following to your `compose.yaml` to use Google's DNS:
```yaml
---
services:
seerr:
dns:
- 8.8.8.8
```
or for Cloudflare's DNS:
```yaml
---
services:
seerr:
dns:
- 1.1.1.1
```
or for Quad9's DNS:
```yaml
---
services:
seerr:
dns:
- 9.9.9.9
```
You can try them all and see which one works for your network.
</TabItem>
<TabItem value="windows" label="Windows">
1. Open the Control Panel.
2. Click on Network and Internet.
3. Click on Network and Sharing Center.
4. Click on Change adapter settings.
5. Right-click the network interface connected to the internet and select Properties.
6. Select Internet Protocol Version 4 (TCP/IPv4) and click Properties.
7. Select Use the following DNS server addresses and enter `8.8.8.8` for Google's DNS or `1.1.1.1` for Cloudflare's DNS or `9.9.9.9` for Quad9's DNS.
</TabItem>
<TabItem value="linux" label="Linux">
1. Open a terminal.
2. Edit the `/etc/resolv.conf` file with your favorite text editor.
3. Add the following line to use Google's DNS:
```bash
nameserver 8.8.8.8
```
or for Cloudflare's DNS:
```bash
nameserver 1.1.1.1
```
or for Quad9's DNS:
```bash
nameserver 9.9.9.9
```
</TabItem>
</Tabs>
### Option 2: Use Seerr through a proxy
If you can't change your DNS servers or force IPV4 resolution, you can use Seerr through a proxy.
In some places (like China), the ISP blocks not only the DNS resolution but also the connection to the TMDB API.
You can configure Seerr to use a proxy with the [HTTP(S) Proxy](/using-seerr/settings/general#enable-proxy-support) setting.
### Option 3: Force IPV4 resolution first
Sometimes there are configuration issues with IPV6 that prevent the hostname resolution from working correctly.
You can try to force the resolution to use IPV4 first by going to `Settings > Networking > Advanced Networking` and enabling `Force IPv4 Resolution First` setting and restarting Seerr.
### Option 4: Check that your server can reach TMDB API
Make sure that your server can reach the TMDB API by running the following command:
<Tabs groupId="methods" queryString>
<TabItem value="docker-cli" label="Docker CLI">
```bash
docker exec -it seerr sh -c "apk update && apk add curl && curl -L https://api.themoviedb.org"
```
</TabItem>
<TabItem value="docker-compose" label="Docker Compose">
```bash
docker compose exec seerr sh -c "apk update && apk add curl && curl -L https://api.themoviedb.org"
```
</TabItem>
<TabItem value="linux" label="Linux">
In a terminal:
```bash
curl -L https://api.themoviedb.org
```
</TabItem>
<TabItem value="windows" label="Windows">
In a PowerShell window:
```powershell
(Invoke-WebRequest -Uri "https://api.themoviedb.org" -Method Get).Content
```
</TabItem>
</Tabs>
If you can't get a response, then your server can't reach the TMDB API.
This is usually due to a network configuration issue or a firewall blocking the connection.
## Account does not have admin privileges
If your admin account no longer has admin privileges, this is typically because your Jellyfin/Emby user ID has changed on the server side.
This can happen if you have a new installation of Jellyfin/Emby or if you have changed the user ID of your admin account.
### Solution: Reset admin access
1. Back up your `settings.json` file (located in your Seerr data directory)
2. Stop the Seerr container/service
3. Delete the `settings.json` file
4. Start Seerr again
5. This will force the setup page to appear
6. Go through the setup process with the same login details
7. You can skip the services setup
8. Once you reach the discover page, stop Seerr
9. Restore your backed-up `settings.json` file
10. Start Seerr again
This process should restore your admin privileges while preserving your settings.
## Failed to enable web push notifications
### Option 1: You are using Pi-hole
When using Pi-hole, you need to whitelist the proper domains in order for the queries to not be intercepted and blocked by Pi-hole.
If you are using a chromium based browser (eg: Chrome, Brave, Edge...), the domain you need to whitelist is `fcm.googleapis.com`
If you are using Firefox, the domain you need to whitelist is `push.services.mozilla.com`
1. Log into your Pi-hole through the admin interface, then click on Domains situated under GROUP MANAGEMENT.
2. Add the domain corresponding to your browser in the `Domain to be added` field and then click on Add to allowed domains.
3. Now in order for those changes to be used you need to flush your current dns cache.
4. You can do so by using this command line in your Pi-hole terminal:
```bash
pihole restartdns
```
If this command fails (which is unlikely), use this equivalent:
```bash
pihole -f && pihole restartdns
```
5. Then restart your Seerr instance and try to enable the web push notifications again.
### Option 2: You are using Brave browser
Brave is a "De-Googled" browser. So by default or if you refused a prompt in the past, it cuts the access to the FCM (Firebase Cloud Messaging) service, which is mandatory for the web push notifications on Chromium based browsers.
1. Open Brave and paste this address in the url bar: `brave://settings/privacy`
2. Look for the option: "Use Google services for push messaging"
3. Activate this option
4. Relaunch Brave completely
5. You should now see the notifications prompt appearing instead of an error message.
If you still encounter issues, please reach out on our support channels.

View File

@@ -0,0 +1,9 @@
{
"label": "Using Jellyseerr",
"position": 2,
"link": {
"type": "generated-index",
"title": "Using Jellyseerr",
"description": "Learn how to use Jellyseerr"
}
}

View File

@@ -18,10 +18,6 @@ Users can optionally opt-in to being mentioned in Discord notifications by confi
You can find the webhook URL in the Discord application, at **Server Settings &rarr; Integrations &rarr; Webhooks**.
### Notification Role ID (optional)
If a role ID is specified, it will be included in the webhook message. See [Discord role ID](https://support.discord.com/hc/en-us/articles/206346498-Where-can-I-find-my-User-Server-Message-ID).
### Bot Username (optional)
If you would like to override the name you configured for your bot in Discord, you may set this value to whatever you like!

View File

@@ -9,12 +9,12 @@ sidebar_position: 1
## Configuration
:::info
If the [Application URL](/using-seerr/settings/general#application-title) setting is configured in **Settings → General**, Seerr will explicitly set the origin server hostname when connecting to the SMTP host.
If the [Application URL](/using-jellyseerr/settings/general#application-title) setting is configured in **Settings → General**, Jellyseerr will explicitly set the origin server hostname when connecting to the SMTP host.
:::
### Sender Name (optional)
Configure a friendly name for the email sender (e.g., "Seerr").
Configure a friendly name for the email sender (e.g., "Jellyseerr").
### Sender Address

View File

@@ -8,7 +8,7 @@ sidebar_position: 3
## Supported Notification Agents
Seerr currently supports the following notification agents:
Jellyseerr currently supports the following notification agents:
import DocCardList from '@theme/DocCardList';
@@ -16,10 +16,10 @@ import DocCardList from '@theme/DocCardList';
## Setting Up Notifications
Simply configure your desired notification agents in **Settings -> Notifications** in the Seerr web UI.
Simply configure your desired notification agents in **Settings -> Notifications** in the Jellyseerr web UI.
Users can customize their notification preferences in their own user notification settings.
## Requesting New Notification Agents
If we do not currently support your preferred notification agent, feel free to [submit a feature request on GitHub](https://github.com/seerr-team/seerr/issues). However, please be sure to search first and confirm that there is not already an existing request for the agent!
If we do not currently support your preferred notification agent, feel free to [submit a feature request on GitHub](https://github.com/Fallenbagel/jellyseerr/issues). However, please be sure to search first and confirm that there is not already an existing request for the agent!

View File

@@ -6,12 +6,12 @@ sidebar_position: 2
# Web Push
The web push notification agent enables you and your users to receive Seerr notifications in a supported browser.
The web push notification agent enables you and your users to receive Jellyseerr notifications in a supported browser.
This notification agent does not require any configuration, but is not enabled in Seerr
This notification agent does not require any configuration, but is not enabled in Jellyseerr by default.
:::warning
Web push notifications require a secure connection to your Seerr instance. Refer to the [Reverse Proxy](/extending-seerr/reverse-proxy) documentation for more information.
Web push notifications require a secure connection to your Jellyseerr instance. Refer to the [Reverse Proxy](/extending-jellyseerr/reverse-proxy) documentation for more information.
:::
To set up web push notifications, simply enable the agent in **Settings → Notifications → Web Push**. You and your users will then be prompted to allow notifications in your web browser.

View File

@@ -4,6 +4,6 @@
"link": {
"type": "generated-index",
"title": "Settings",
"description": "Configure Seerr to your liking"
"description": "Configure Jellyseerr to your liking"
}
}

View File

@@ -0,0 +1,77 @@
---
title: General
description: Configure global and default settings for Jellyseerr.
sidebar_position: 1
---
# General
## API Key
This is your Jellyseerr API key, which can be used to integrate Jellyseerr with third-party applications. Do **not** share this key publicly, as it can be used to gain administrator access!
If you need to generate a new API key for any reason, simply click the button to the right of the text box.
If you want to set the API key, rather than letting it be randomly generated, you can use the API_KEY environment variable. Whatever that variable is set to will be your API key.
## Application Title
If you aren't a huge fan of the name "Jellyseerr" and would like to display something different to your users, you can customize the application title!
## Application URL
Set this to the externally-accessible URL of your Jellyseerr instance.
You must configure this setting in order to enable password reset and generation emails.
## Enable Proxy Support
If you have Jellyseerr behind a reverse proxy, enable this setting to allow Jellyseerr to correctly register client IP addresses. For details, please see the [Express Documentation](https://expressjs.com/en/guide/behind-proxies.html).
This setting is **disabled** by default.
## Enable CSRF Protection
:::warning
**This is an advanced setting.** Please only enable this setting if you are familiar with CSRF protection and how it works.
:::
CSRF stands for [cross-site request forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery). When this setting is enabled, all external API access that alters Jellyseerr application data is blocked.
If you do not use Jellyseerr integrations with third-party applications to add/modify/delete requests or users, you can consider enabling this setting to protect against malicious attacks.
One caveat, however, is that HTTPS is required, meaning that once this setting is enabled, you will no longer be able to access your Jellyseerr instance over _HTTP_ (including using an IP address and port number).
If you enable this setting and find yourself unable to access Jellyseerr, you can disable the setting by modifying `settings.json` in `/app/config`.
This setting is **disabled** by default.
## Enable Image Caching
When enabled, Jellseerr will proxy and cache images from pre-configured sources (such as TMDB). This can use a significant amount of disk space.
Images are saved in the `config/cache/images` and stale images are cleared out every 24 hours.
You should enable this if you are having issues with loading images directly from TMDB in your browser.
## Display Language
Set the default display language for Jellyseerr. Users can override this setting in their user settings.
## Discover Region & Discover Language
These settings filter content shown on the "Discover" home page based on regional availability and original language, respectively. Users can override these global settings by configuring these same options in their user settings.
## Hide Available Media
When enabled, media which is already available will not appear on the "Discover" home page, or in the "Recommended" or "Similar" categories or other links on media detail pages.
Available media will still appear in search results, however, so it is possible to locate and view hidden items by searching for them by title.
This setting is **disabled** by default.
## Allow Partial Series Requests
When enabled, users will be able to submit requests for specific seasons of TV series. If disabled, users will only be able to submit requests for all unavailable seasons.
This setting is **enabled** by default.

View File

@@ -0,0 +1,12 @@
---
title: Jobs & Cache
description: Configure jobs and cache settings.
---
# Jobs & Cache
Jellyseerr performs certain maintenance tasks as regularly-scheduled jobs, but they can also be manually triggered on this page.
Jellyseerr also caches requests to external API endpoints to optimize performance and avoid making unnecessary API calls. If necessary, the cache for any particular endpoint can be cleared by clicking the "Flush Cache" button.
You can also view the current image cache size as well as the total number of cached images.

View File

@@ -20,13 +20,13 @@ It is **not** tied to your Jellyfin account.
### Jellyfin Libraries
In this section, simply select the libraries you would like Seerr to scan. Seerr will periodically check the selected libraries for available content to update the media status that is displayed to users.
In this section, simply select the libraries you would like Jellyseerr to scan. Jellyseerr will periodically check the selected libraries for available content to update the media status that is displayed to users.
If you do not see your Jellyfin library listed, verify your Jellyfin settings are correct and click the Sync Libraries button.
### Manual Library Scan
Seerr will perform a full scan of your Jellyfin libraries once every 24 hours (recently added items are fetched more frequently). If this is your first time configuring Jellyfin, a one-time full manual library scan is recommended!
Jellyseerr will perform a full scan of your Jellyfin libraries once every 24 hours (recently added items are fetched more frequently). If this is your first time configuring Jellyfin, a one-time full manual library scan is recommended!
### Jellyfin Settings
@@ -37,15 +37,15 @@ This section is where you configure the connection to your Jellyfin server.
#### Internal URL
The internal URL is the URL that Seerr will use to communicate with your Jellyfin server. This URL should be accessible from the machine running Seerr.
The internal URL is the URL that Jellyseerr will use to communicate with your Jellyfin server. This URL should be accessible from the machine running Jellyseerr.
In most cases, this will be the hostname or IP address of the machine running Jellyfin, followed by the port number Jellyfin is running on (usually 8096).
:::note
When running Seerr in a docker container with a bridged network (default), the container's network will be separate from the host network. Therefore, you cannot use `localhost` or `127.0.0.1` as the internal URL as it will resolve to the container itself.
When running Jellyseerr in a docker container with a bridged network (default), the container's network will be separate from the host network. Therefore, you cannot use `localhost` or `127.0.0.1` as the internal URL as it will resolve to the container itself.
:::
:::tip
If you are running Jellyfin in a docker container, you can put both Seerr and Jellyfin on the same docker network by using a custom [docker network](https://docs.docker.com/reference/cli/docker/network/). This will allow you to use the container name as the internal URL.
If you are running Jellyfin in a docker container, you can put both Jellyseerr and Jellyfin on the same docker network by using a custom [docker network](https://docs.docker.com/reference/cli/docker/network/). This will allow you to use the container name as the internal URL.
:::
#### External URL
@@ -56,7 +56,7 @@ In most cases, the external URL will be different from the internal URL. This is
#### Forgot Password URL
The forgot password URL is the URL that users will be directed to when they click the "Forgot Password" button on the login page. This URL should be accessible from the machine running Seerr.
The forgot password URL is the URL that users will be directed to when they click the "Forgot Password" button on the login page. This URL should be accessible from the machine running Jellyseerr.
By default, this field is empty and the "Forgot Password" button on the login page will redirect to the Jellyfin internal URL with the path `/web/index.html#!/forgotpassword`.
@@ -67,15 +67,15 @@ You can customize this URL to point to a custom password reset page if you have
#### Hostname or IP Address
If you have Seerr installed on the same network as Jellyfin, you can set this to the local IP address of your Jellyfin server. Otherwise, this should be set to a valid hostname (e.g., jellyfin.myawesomeserver.com).
If you have Jellyseerr installed on the same network as Jellyfin, you can set this to the local IP address of your Jellyfin server. Otherwise, this should be set to a valid hostname (e.g., jellyfin.myawesomeserver.com).
In most cases, this will be the hostname or IP address of the machine running Jellyfin.
:::note
When running Seerr in a docker container with a bridged network (default), the container's network will be separate from the host network. Therefore, you cannot use `localhost` or `127.0.0.1` as the internal URL as it will resolve to the container itself.
When running Jellyseerr in a docker container with a bridged network (default), the container's network will be separate from the host network. Therefore, you cannot use `localhost` or `127.0.0.1` as the internal URL as it will resolve to the container itself.
:::
:::tip
If you are running Jellyfin in a docker container, you can put both Seerr and Jellyfin on the same docker network by using a custom [docker network](https://docs.docker.com/reference/cli/docker/network/). This will allow you to use the container name as the internal URL.
If you are running Jellyfin in a docker container, you can put both Jellyseerr and Jellyfin on the same docker network by using a custom [docker network](https://docs.docker.com/reference/cli/docker/network/). This will allow you to use the container name as the internal URL.
:::
#### Port
@@ -94,7 +94,7 @@ In most cases, the external URL will be different from the internal URL. This is
#### Forgot Password URL
The forgot password URL is the URL that users will be directed to when they click the "Forgot Password" button on the login page. This URL should be accessible from the machine running Seerr.
The forgot password URL is the URL that users will be directed to when they click the "Forgot Password" button on the login page. This URL should be accessible from the machine running Jellyseerr.
By default, this field is empty and the "Forgot Password" button on the login page will redirect to the Jellyfin internal URL with the path `/web/index.html#!/forgotpassword`.
@@ -114,13 +114,13 @@ It is **not** tied to your Emby account.
### Emby Libraries
In this section, simply select the libraries you would like Seerr to scan. Seerr will periodically check the selected libraries for available content to update the media status that is displayed to users.
In this section, simply select the libraries you would like Jellyseerr to scan. Jellyseerr will periodically check the selected libraries for available content to update the media status that is displayed to users.
If you do not see your Emby library listed, verify your Emby settings are correct and click the Sync Libraries button.
### Manual Library Scan
Seerr will perform a full scan of your Emby libraries once every 24 hours (recently added items are fetched more frequently). If this is your first time configuring Emby, a one-time full manual library scan is recommended!
Jellyseerr will perform a full scan of your Emby libraries once every 24 hours (recently added items are fetched more frequently). If this is your first time configuring Emby, a one-time full manual library scan is recommended!
### Emby Settings
@@ -131,15 +131,15 @@ This section is where you configure the connection to your Emby server.
#### Internal URL
The internal URL is the URL that Seerr will use to communicate with your Emby server. This URL should be accessible from the machine running Seerr.
The internal URL is the URL that Jellyseerr will use to communicate with your Emby server. This URL should be accessible from the machine running Jellyseerr.
In most cases, this will be the hostname or IP address of the machine running Emby, followed by the port number Emby is running on (usually 8096).
:::note
When running Seerr in a docker container with a bridged network (default), the container's network will be separate from the host network. Therefore, you cannot use `localhost` or `127.0.0.1` as the internal URL as it will resolve to the container itself.
When running Jellyseerr in a docker container with a bridged network (default), the container's network will be separate from the host network. Therefore, you cannot use `localhost` or `127.0.0.1` as the internal URL as it will resolve to the container itself.
:::
:::tip
If you are running Emby in a docker container, you can put both Seerr and Emby on the same docker network by using a custom [docker network](https://docs.docker.com/reference/cli/docker/network/). This will allow you to use the container name as the internal URL.
If you are running Emby in a docker container, you can put both Jellyseerr and Emby on the same docker network by using a custom [docker network](https://docs.docker.com/reference/cli/docker/network/). This will allow you to use the container name as the internal URL.
:::
#### External URL
@@ -150,7 +150,7 @@ In most cases, the external URL will be different from the internal URL. This is
#### Forgot Password URL
The forgot password URL is the URL that users will be directed to when they click the "Forgot Password" button on the login page. This URL should be accessible from the machine running Seerr.
The forgot password URL is the URL that users will be directed to when they click the "Forgot Password" button on the login page. This URL should be accessible from the machine running Jellyseerr.
By default, this field is empty and the "Forgot Password" button on the login page will redirect to the Emby internal URL with the path `/web/index.html#!/forgotpassword.html`.
@@ -161,15 +161,15 @@ You can customize this URL to point to a custom password reset page if you have
#### Hostname or IP Address
If you have Seerr installed on the same network as Emby, you can set this to the local IP address of your Emby server. Otherwise, this should be set to a valid hostname (e.g., jellyfin.myawesomeserver.com).
If you have Jellyseerr installed on the same network as Emby, you can set this to the local IP address of your Emby server. Otherwise, this should be set to a valid hostname (e.g., jellyfin.myawesomeserver.com).
In most cases, this will be the hostname or IP address of the machine running Emby.
:::note
When running Seerr in a docker container with a bridged network (default), the container's network will be separate from the host network. Therefore, you cannot use `localhost` or `127.0.0.1` as the internal URL as it will resolve to the container itself.
When running Jellyseerr in a docker container with a bridged network (default), the container's network will be separate from the host network. Therefore, you cannot use `localhost` or `127.0.0.1` as the internal URL as it will resolve to the container itself.
:::
:::tip
If you are running Emby in a docker container, you can put both Seerr and Emby on the same docker network by using a custom [docker network](https://docs.docker.com/reference/cli/docker/network/). This will allow you to use the container name as the internal URL.
If you are running Emby in a docker container, you can put both Jellyseerr and Emby on the same docker network by using a custom [docker network](https://docs.docker.com/reference/cli/docker/network/). This will allow you to use the container name as the internal URL.
:::
#### Port
@@ -188,7 +188,7 @@ In most cases, the external URL will be different from the internal URL. This is
#### Forgot Password URL
The forgot password URL is the URL that users will be directed to when they click the "Forgot Password" button on the login page. This URL should be accessible from the machine running Seerr.
The forgot password URL is the URL that users will be directed to when they click the "Forgot Password" button on the login page. This URL should be accessible from the machine running Jellyseerr.
By default, this field is empty and the "Forgot Password" button on the login page will redirect to the Emby internal URL with the path `/web/index.html#!/startup/forgotpassword.html`.
@@ -205,12 +205,12 @@ You can customize this URL to point to a custom password reset page if you have
:::info
To set up Plex, you can either enter your details manually or select a server retrieved from [plex.tv](https://plex.tv/). Press the button to the right of the "Server" dropdown to retrieve available servers.
Depending on your setup/configuration, you may need to enter your Plex server details manually in order to establish a connection from Seerr.
Depending on your setup/configuration, you may need to enter your Plex server details manually in order to establish a connection from Jellyseerr.
:::
#### Hostname or IP Address
If you have Seerr installed on the same network as Plex, you can set this to the local IP address of your Plex server. Otherwise, this should be set to a valid hostname (e.g., `plex.myawesomeserver.com`).
If you have Jellyseerr installed on the same network as Plex, you can set this to the local IP address of your Plex server. Otherwise, this should be set to a valid hostname (e.g., `plex.myawesomeserver.com`).
#### Port
@@ -228,13 +228,13 @@ Note that you will need to enter the full path to the web app (e.g., `https://pl
### Plex Libraries
In this section, simply select the libraries you would like Seerr to scan. Seerr will periodically check the selected libraries for available content to update the media status that is displayed to users.
In this section, simply select the libraries you would like Jellyseerr to scan. Jellyseerr will periodically check the selected libraries for available content to update the media status that is displayed to users.
If you do not see your Plex libraries listed, verify your Plex settings are correct and click the **Sync Libraries** button.
### Manual Library Scan
Seerr will perform a full scan of your Plex libraries once every 24 hours (recently added items are fetched more frequently). If this is your first time configuring Plex, a one-time full manual library scan is recommended!
Jellyseerr will perform a full scan of your Plex libraries once every 24 hours (recently added items are fetched more frequently). If this is your first time configuring Plex, a one-time full manual library scan is recommended!
</TabItem>

View File

@@ -6,4 +6,4 @@ sidebar_position: 5
# Notifications
Please see the [Notifications](/using-seerr/notifications) page for more information.
Please see the [Notifications](/using-jellyseerr/notifications) page for more information.

Some files were not shown because too many files have changed in this diff Show More