saulutions.ca

// blog post

Part 1: Building Jellyseerr from Source with OIDC

5 min read
#jellyseerr #oidc #proxmox #systemd

The stable Jellyseerr release doesn’t have OIDC support. To get it, we need to build from the preview-OIDC branch. Don’t worry, it’s just cloning a repo and running a few commands.

Note: The preview-OIDC branch is not the stable main branch. It works, but it’s a preview so expect the occasional rough edge. If you just want regular Jellyseerr without OIDC, use main instead (or just use the community install script which does everything automatically).

Already have Jellyseerr installed?

If you have an existing Jellyseerr instance (e.g., from the community script), you don’t need to start from scratch. Your config and data in /opt/jellyseerr/config/ will carry over, you just need to switch branches and rebuild.

systemctl stop jellyseerr
cd /opt/jellyseerr
git checkout preview-OIDC
rm -rf dist .next node_modules

Then install and build (as root is fine if that’s how your existing setup runs):

export CYPRESS_INSTALL_BINARY=0
pnpm install --frozen-lockfile

export NODE_OPTIONS="--max-old-space-size=3072"
pnpm build

Update the systemd service to use pnpm start:

sed -i 's|ExecStart=.*|ExecStart=/usr/bin/pnpm start|' /etc/systemd/system/jellyseerr.service
systemctl daemon-reload
systemctl start jellyseerr

That’s it. Skip ahead to Part 2 if you already have a domain set up, or straight to Part 3 for the OIDC config.


The rest of this guide is for a fresh install.

Set up the LXC container

You need a Linux box to run this on. Any Debian or Ubuntu machine works. If you’re on Proxmox, spin up an LXC container with the community scripts:

bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/debian.sh)"

If you’re creating the container manually, here are the recommended specs. The build process is memory-hungry, so don’t skimp:

  • Template: Debian 12 or Ubuntu 24.04
  • RAM: 4GB (the build needs headroom, you can scale down to 2GB after)
  • Storage: 8GB minimum
  • CPU: 4 cores (speeds up the build significantly)

SSH in and update everything:

apt update && apt upgrade -y

Install dependencies

We need Git and build-essential (for compiling native Node modules):

apt install -y git build-essential

Install Node.js 22

Jellyseerr requires Node.js 22:

curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt install -y nodejs
node --version   # should show v22.x

Clone the repo

Clone Jellyseerr to /opt/jellyseerr and check out the OIDC preview branch:

git clone https://github.com/fallenbagel/jellyseerr.git /opt/jellyseerr
cd /opt/jellyseerr
git checkout preview-OIDC

Install pnpm

The pnpm version needs to match what the project expects. We read it straight from package.json and install globally (this needs root):

pnpm_version=$(grep -Po '"pnpm":\s*"\K[^"]+' /opt/jellyseerr/package.json)
npm install -g "pnpm@$pnpm_version"
pnpm --version   # should match what package.json expects

Create a dedicated user

Don’t run Jellyseerr as root. Create a service account with its home directory pointing to the repo we just cloned:

useradd -r -d /opt/jellyseerr -s /bin/bash jellyseerr
chown -R jellyseerr:jellyseerr /opt/jellyseerr

Build

Switch to the jellyseerr user:

su - jellyseerr

You’ll land directly in /opt/jellyseerr, which is the repo. No need to cd anywhere.

Now the actual build. We set CYPRESS_INSTALL_BINARY=0 to skip downloading the Cypress browser testing binary (we don’t need it), and bump Node’s memory limit so the build doesn’t run out of memory:

export CYPRESS_INSTALL_BINARY=0
pnpm install --frozen-lockfile

export NODE_OPTIONS="--max-old-space-size=3072"
pnpm build

The build takes a few minutes depending on your hardware. Go make coffee.

Once it’s done, test that it starts:

pnpm start

You should see Jellyseerr start up on port 5055. Hit Ctrl+C to stop it, we’ll run it properly with systemd next.

Exit back to root:

exit

Set up systemd

Create a config file for environment variables:

mkdir -p /etc/jellyseerr
cat > /etc/jellyseerr/jellyseerr.conf << 'EOF'
PORT=5055
# HOST=0.0.0.0
# JELLYFIN_TYPE=emby
EOF

Now create the systemd service:

cat > /etc/systemd/system/jellyseerr.service << 'EOF'
[Unit]
Description=Jellyseerr Service
After=network.target

[Service]
EnvironmentFile=/etc/jellyseerr/jellyseerr.conf
Environment=NODE_ENV=production
User=jellyseerr
Group=jellyseerr
Type=exec
WorkingDirectory=/opt/jellyseerr
ExecStart=/usr/bin/pnpm start
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

Enable and start it:

systemctl daemon-reload
systemctl enable jellyseerr
systemctl start jellyseerr

Check that it’s running:

systemctl status jellyseerr

You should see it active and running on port 5055. Try accessing it from your browser at http://<container-ip>:5055.

Since this is a system-level systemd service, it starts on boot automatically, keeps running after you log out (it’s not tied to your SSH session), and restarts on crash with a 5-second cooldown.

Updating later

When you need to update, pull the latest changes, rebuild, and restart:

systemctl stop jellyseerr
su - jellyseerr

Then in the jellyseerr shell:

git pull
rm -rf dist .next node_modules

export CYPRESS_INSTALL_BINARY=0
pnpm install --frozen-lockfile

export NODE_OPTIONS="--max-old-space-size=3072"
pnpm build
exit

Back as root, start the service:

systemctl start jellyseerr

That’s Part 1 done. Jellyseerr is built, running, and managed by systemd. Next up: giving it a proper domain.

Comments