diff --git a/docs/extending-jellyseerr/database-config.mdx b/docs/extending-jellyseerr/database-config.mdx index 01c250c44..d6c4442a2 100644 --- a/docs/extending-jellyseerr/database-config.mdx +++ b/docs/extending-jellyseerr/database-config.mdx @@ -9,6 +9,8 @@ Jellyseerr supports SQLite and PostgreSQL. The database connection can be config ## 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". @@ -17,17 +19,35 @@ DB_LOG_QUERIES="false" # (optional) Whether to log the DB queries for debugging. ## PostgreSQL Options +### 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". To use postgres, this needs to be set to "postgres" -DB_HOST="localhost" # (optional) The host (url) of the database. The default is "localhost". +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_USER= # (required) Username used to connect to the database. +DB_PASS= # (required) Password of the user used to connect to the database. +DB_NAME="jellyseerr" # (optional) The name of the database to connect to. The default is "jellyseerr". +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="jellyseerr" # (optional) The name of the database to connect to. The default is "jellyseerr". DB_LOG_QUERIES="false" # (optional) Whether to log the DB queries for debugging. The default is "false". ``` ### 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 @@ -40,6 +60,7 @@ DB_SSL_KEY_FILE= # (optinal) Path to the private key for the connection in PEM f 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 @@ -48,7 +69,7 @@ DB_SSL_CERT_FILE= # (optional) Path to certificate chain in pem format for the p 3. Stop Jellyseerr 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 to match your setup +Edit the postgres connection string 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. ::: diff --git a/docs/getting-started/buildfromsource.mdx b/docs/getting-started/buildfromsource.mdx index b6ad72fe5..9e139dcdb 100644 --- a/docs/getting-started/buildfromsource.mdx +++ b/docs/getting-started/buildfromsource.mdx @@ -6,6 +6,8 @@ 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-jellyseerr/database-config#postgresql-options) for details on how to configure your database. ::: import Tabs from '@theme/Tabs'; diff --git a/docs/getting-started/docker.mdx b/docs/getting-started/docker.mdx index 303ed9a37..3d411e021 100644 --- a/docs/getting-started/docker.mdx +++ b/docs/getting-started/docker.mdx @@ -7,6 +7,8 @@ sidebar_position: 1 :::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-jellyseerr/database-config#postgresql-options) for details on how to configure your database. ::: ## Unix (Linux, macOS) diff --git a/docs/getting-started/nixpkg.mdx b/docs/getting-started/nixpkg.mdx index 9afb27577..e35fd184c 100644 --- a/docs/getting-started/nixpkg.mdx +++ b/docs/getting-started/nixpkg.mdx @@ -6,6 +6,8 @@ sidebar_position: 3 import { JellyseerrVersion, NixpkgVersion } from '@site/src/components/JellyseerrVersion'; import Admonition from '@theme/Admonition'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; # Nix Package Manager (Advanced) :::info @@ -13,22 +15,55 @@ This method is not recommended for most users. It is intended for advanced users ::: export const VersionMismatchWarning = () => { - const jellyseerrVersion = JellyseerrVersion(); - const nixpkgVersion = NixpkgVersion(); + let jellyseerrVersion = null; + let nixpkgVersions = null; + try { + jellyseerrVersion = JellyseerrVersion(); + nixpkgVersions = NixpkgVersion(); + } catch (err) { + return ( + + Failed to load version information. Error: {err.message || JSON.stringify(err)} + + ); + } - const isUpToDate = jellyseerrVersion === nixpkgVersion; + if (!nixpkgVersions || nixpkgVersions.error) { + return ( + + Failed to fetch Nixpkg versions: {nixpkgVersions?.error || 'Unknown error'} + + ); + } + + const isUnstableUpToDate = jellyseerrVersion === nixpkgVersions.unstable; + const isStableUpToDate = jellyseerrVersion === nixpkgVersions.stable; return ( - <> - {!isUpToDate ? ( - - The upstream Jellyseerr Nix Package (v{nixpkgVersion}) is not up-to-date. If you want to use Jellyseerr v{jellyseerrVersion}, you will need to override the package derivation. - - ) : ( - - The upstream Jellyseerr Nix Package (v{nixpkgVersion}) is up-to-date with Jellyseerr v{jellyseerrVersion}. - - )} + <> + {!isStableUpToDate ? ( + + The{' '} + + upstream Jellyseerr Nix Package (v{nixpkgVersions.stable}) + {' '} + is not up-to-date. If you want to use Jellyseerr v{jellyseerrVersion},{' '} + {isUnstableUpToDate ? ( + <> + consider using the{' '} + + unstable package + {' '} + instead. + + ) : ( + <> + you will need to{' '} + override the package derivation. + + )} + +) : null} ); }; @@ -48,6 +83,8 @@ To get up and running with jellyseerr using Nix, you can add the following to yo If you want more advanced configuration options, you can use the following: + + ```nix { config, pkgs, ... }: @@ -56,53 +93,20 @@ If you want more advanced configuration options, you can use the following: enable = true; port = 5055; openFirewall = true; + package = pkgs.jellyseerr; # Use the unstable package if stable is not up-to-date }; } ``` - -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, ... }: + + +In order to use postgres, you will need to add override the default module of jellyseerr with the following as the current default module is not compatible with postgres: +```nix { - 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, ... }: - + config, + pkgs, + lib, + ... +}: with lib; let cfg = config.services.jellyseerr; @@ -113,28 +117,65 @@ in disabledModules = [ "services/misc/jellyseerr.nix" ]; options.services.jellyseerr = { - enable = mkEnableOption (mdDoc ''Jellyseerr, a requests manager for Jellyfin''); + enable = mkEnableOption ''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.''; + description = ''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.''; + description = ''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. - ''; + type = types.package; + default = pkgs.jellyseerr; + defaultText = literalExpression "pkgs.jellyseerr"; + description = '' + Jellyseerr package to use. + ''; + }; + + databaseConfig = mkOption { + type = types.attrsOf types.str; + default = { + type = "sqlite"; + configDirectory = "config"; + logQueries = "false"; }; + description = '' + Database configuration. For "sqlite", only "type", "configDirectory", and "logQueries" are relevant. + For "postgres", include host, port, user, pass, name, and optionally socket. + Example: + { + type = "postgres"; + socket = "/run/postgresql"; + user = "jellyseerr"; + name = "jellyseerr"; + logQueries = "false"; + } + or + { + type = "postgres"; + host = "localhost"; + port = "5432"; + user = "dbuser"; + pass = "password"; + name = "jellyseerr"; + logQueries = "false"; + } + or + { + type = "sqlite"; + configDirectory = "config"; + logQueries = "false"; + } + ''; + }; }; config = mkIf cfg.enable { @@ -142,14 +183,29 @@ in description = "Jellyseerr, a requests manager for Jellyfin"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - environment.PORT = toString cfg.port; + environment = + let + dbConfig = cfg.databaseConfig; + in + { + PORT = toString cfg.port; + DB_TYPE = toString dbConfig.type; + CONFIG_DIRECTORY = toString dbConfig.configDirectory or ""; + DB_LOG_QUERIES = toString dbConfig.logQueries; + DB_HOST = if dbConfig.type == "postgres" && !(hasAttr "socket" dbConfig) then toString dbConfig.host or "" else ""; + DB_PORT = if dbConfig.type == "postgres" && !(hasAttr "socket" dbConfig) then toString dbConfig.port or "" else ""; + DB_SOCKET_PATH = if dbConfig.type == "postgres" && hasAttr "socket" dbConfig then toString dbConfig.socket or "" else ""; + DB_USER = if dbConfig.type == "postgres" then toString dbConfig.user or "" else ""; + DB_PASS = if dbConfig.type == "postgres" then toString dbConfig.pass or "" else ""; + DB_NAME = if dbConfig.type == "postgres" then toString dbConfig.name or "" else ""; + }; serviceConfig = { Type = "exec"; StateDirectory = "jellyseerr"; - WorkingDirectory = "\${cfg.package}/libexec/jellyseerr/deps/jellyseerr"; + WorkingDirectory = "${cfg.package}/libexec/jellyseerr"; DynamicUser = true; - ExecStart = "\${cfg.package}/bin/jellyseerr"; - BindPaths = [ "/var/lib/jellyseerr/:\${cfg.package}/libexec/jellyseerr/deps/jellyseerr/config/" ]; + ExecStart = "${cfg.package}/bin/jellyseerr"; + BindPaths = [ "/var/lib/jellyseerr/:${cfg.package}/libexec/jellyseerr/config/" ]; Restart = "on-failure"; ProtectHome = true; ProtectSystem = "strict"; @@ -169,57 +225,47 @@ in }; }; - networking.firewall = mkIf cfg.openFirewall { - allowedTCPPorts = [ cfg.port ]; - }; + networking.firewall = mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; }; -}`; - - const configuration = `{ config, pkgs, ... }: +} +``` +Then, import the module into your `configuration.nix`: +```nix +{ config, pkgs, ... }: { - imports = [ ./jellyseerr-module.nix ] + imports = [ ./modules/jellyseerr.nix ]; - services.jellyseerr = { - enable = true; - port = 5055; - openFirewall = true; - package = (pkgs.callPackage (import ../../../pkgs/jellyseerr) { }); + services.jellyseerr = { + enable = true; + port = 5055; + openFirewall = true; + package = pkgs.unstable.jellyseerr; # use the unstable package if stable is not up-to-date + databaseConfig = { + type = "postgres"; + host = "localhost"; # or socket: "/run/postgresql" + port = "5432"; # if using socket, this is not needed + user = "jellyseerr"; + pass = "jellyseerr"; + name = "jellyseerr"; + logQueries = "false"; }; -}`; + } +} +``` + + - const isUpToDate = jellyseerrVersion === nixpkgVersion; +After adding the configuration to your `configuration.nix`, you can run the following command to install jellyseerr: - return ( - <> - {isUpToDate ? ( - <> -

The latest version of Jellyseerr ({jellyseerrVersion}) and the Jellyseerr nixpkg package version ({nixpkgVersion}) is up-to-date.

-

There is no need to override the package derivation.

- - ) : ( - <> -

The latest version of Jellyseerr ({jellyseerrVersion}) and the Jellyseerr nixpkg version (v{nixpkgVersion}) is out-of-date. - If you want to use Jellyseerr v{jellyseerrVersion}, you will need to override the package derivation.

-

In order to override the package derivation:

-
    -
  1. Grab the latest nixpkg derivation for Jellyseerr
  2. -
  3. Grab the latest package.json for Jellyseerr
  4. -
  5. Add it to the same directory as the nixpkg derivation
  6. -
  7. Update the `src` and `offlineCache` attributes in the nixpkg derivation:
  8. - {code} - You can replace the sha256 with the actual hash that nixos-rebuild outputs when you run the command. -
  9. Grab this module and import it in your `configuration.nix`
  10. - {module} - We are using a custom module because the upstream module does not have a package option. -
  11. Call the new package in your `configuration.nix`
  12. - {configuration} -
- - )} - - ); +```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. +::: diff --git a/gen-docs/src/components/JellyseerrVersion/index.tsx b/gen-docs/src/components/JellyseerrVersion/index.tsx index 0c4857e5e..355f74443 100644 --- a/gen-docs/src/components/JellyseerrVersion/index.tsx +++ b/gen-docs/src/components/JellyseerrVersion/index.tsx @@ -26,25 +26,37 @@ export const JellyseerrVersion = () => { }; export const NixpkgVersion = () => { - const [version, setVersion] = useState(null); + const [versions, setVersions] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchVersion = async () => { try { - const url = - 'https://raw.githubusercontent.com/NixOS/nixpkgs/nixos-unstable/pkgs/servers/jellyseerr/default.nix'; - const response = await fetch(url); - const data = await response.text(); + const unstableUrl = + 'https://raw.githubusercontent.com/NixOS/nixpkgs/refs/heads/nixos-unstable/pkgs/by-name/je/jellyseerr/package.nix'; + const stableUrl = + 'https://raw.githubusercontent.com/NixOS/nixpkgs/refs/heads/nixos-24.11/pkgs/servers/jellyseerr/default.nix'; + + const [unstableResponse, stableResponse] = await Promise.all([ + fetch(unstableUrl), + fetch(stableUrl), + ]); + + const unstableData = await unstableResponse.text(); + const stableData = await stableResponse.text(); const versionRegex = /version\s*=\s*"([^"]+)"/; - const match = data.match(versionRegex); - if (match && match[1]) { - setVersion(match[1]); - } else { - setError('0.0.0'); - } + + const unstableMatch = unstableData.match(versionRegex); + const stableMatch = stableData.match(versionRegex); + + const unstableVersion = + unstableMatch && unstableMatch[1] ? unstableMatch[1] : '0.0.0'; + const stableVersion = + stableMatch && stableMatch[1] ? stableMatch[1] : '0.0.0'; + + setVersions({ unstable: unstableVersion, stable: stableVersion }); setLoading(false); } catch (err) { setError(err.message); @@ -63,5 +75,5 @@ export const NixpkgVersion = () => { return { error }; } - return version; + return versions; }; diff --git a/server/datasource.ts b/server/datasource.ts index 8a03c4aea..0c5b9ad3e 100644 --- a/server/datasource.ts +++ b/server/datasource.ts @@ -68,8 +68,10 @@ const prodConfig: DataSourceOptions = { const postgresDevConfig: DataSourceOptions = { type: 'postgres', - host: process.env.DB_HOST, - port: parseInt(process.env.DB_PORT ?? '5432'), + host: process.env.DB_SOCKET_PATH || process.env.DB_HOST, + port: process.env.DB_SOCKET_PATH + ? undefined + : parseInt(process.env.DB_PORT ?? '5432'), username: process.env.DB_USER, password: process.env.DB_PASS, database: process.env.DB_NAME ?? 'jellyseerr', @@ -84,8 +86,10 @@ const postgresDevConfig: DataSourceOptions = { const postgresProdConfig: DataSourceOptions = { type: 'postgres', - host: process.env.DB_HOST, - port: parseInt(process.env.DB_PORT ?? '5432'), + host: process.env.DB_SOCKET_PATH || process.env.DB_HOST, + port: process.env.DB_SOCKET_PATH + ? undefined + : parseInt(process.env.DB_PORT ?? '5432'), username: process.env.DB_USER, password: process.env.DB_PASS, database: process.env.DB_NAME ?? 'jellyseerr',