diff --git a/invidious/Chart.yaml b/invidious/Chart.yaml index 697e1d3..b892171 100644 --- a/invidious/Chart.yaml +++ b/invidious/Chart.yaml @@ -4,7 +4,7 @@ description: Invidious is an alternative front-end to YouTube type: application -version: 2.0.2 +version: 2.0.3 appVersion: v2.20240427 dependencies: @@ -31,4 +31,4 @@ maintainers: - name: Leon Klingele email: mail@leonklingele.de - name: JuniorJPDJ - url: https://github.com/JuniorJPDJ \ No newline at end of file + url: https://github.com/JuniorJPDJ diff --git a/invidious/README.md b/invidious/README.md index ec8cc17..b989d1e 100644 --- a/invidious/README.md +++ b/invidious/README.md @@ -1,42 +1,49 @@ # Invidious Helm chart -Easily deploy Invidious to Kubernetes. +This guide explains how to deploy Invidious to Kubernetes using the Invidious Helm chart. -## Installing Helm chart +## Installing -```sh -# Add repo of Invidious helm charts -$ helm repo add invidious https://charts-helm.invidious.io -$ helm repo update - -# Add PostgreSQL init scripts -$ kubectl create configmap invidious-postgresql-init \ - --from-file=../config/sql/channels.sql \ - --from-file=../config/sql/videos.sql \ - --from-file=../config/sql/channel_videos.sql \ - --from-file=../config/sql/users.sql \ - --from-file=../config/sql/session_ids.sql \ - --from-file=../config/sql/nonces.sql \ - --from-file=../config/sql/annotations.sql \ - --from-file=../config/sql/playlists.sql \ - --from-file=../config/sql/playlist_videos.sql - -# Install Helm app to your Kubernetes cluster -$ helm install invidious invidious/invidious -``` +Follow these steps to install the Helm chart: + +1. Add the Invidious Helm chart repository: + + ```sh + $ helm repo add invidious https://charts-helm.invidious.io + $ helm repo update + ``` + +2. Install the Helm chart to your Kubernetes cluster: + + ```sh + $ helm install invidious invidious/invidious + ``` ## Upgrading +To upgrade the Helm chart, run the following command: + ```sh -# Upgrading is easy, too! $ helm upgrade invidious invidious/invidious ``` -## Uninstall +## Uninstalling + +To uninstall the Helm chart and remove all associated resources (except the database), execute: ```sh -# Get rid of everything (except database) $ helm delete invidious +``` + +### Removing `invidious-postgresql` PersistentVolumeClaims + +> [!CAUTION] +> This action is irreversible. Ensure you have backed up any important data before proceeding. -# To also delete the database, remove all invidious-postgresql PVCs +If you want to delete the Invidious PostgreSQL database along with the Helm chart, you need to remove the associated [PersistentVolumeClaims (PVCs)](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims). Deleting the PVCs will permanently remove the persistent storage used by the database. + +To delete the Invidious PostgreSQL database and its associated PVCs, run the following command: + +```sh +$ kubectl delete pvc data-invidious-postgresql-0 ``` diff --git a/invidious/templates/invidious-postgresql-init-configmap.yaml b/invidious/templates/invidious-postgresql-init-configmap.yaml new file mode 100644 index 0000000..e5d1961 --- /dev/null +++ b/invidious/templates/invidious-postgresql-init-configmap.yaml @@ -0,0 +1,225 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: invidious-postgresql-init +data: + annotations.sql: | + -- Table: public.annotations + + -- DROP TABLE public.annotations; + + CREATE TABLE IF NOT EXISTS public.annotations + ( + id text NOT NULL, + annotations xml, + CONSTRAINT annotations_id_key UNIQUE (id) + ); + + GRANT ALL ON TABLE public.annotations TO current_user; + channel_videos.sql: |+ + -- Table: public.channel_videos + + -- DROP TABLE public.channel_videos; + + CREATE TABLE IF NOT EXISTS public.channel_videos + ( + id text NOT NULL, + title text, + published timestamp with time zone, + updated timestamp with time zone, + ucid text, + author text, + length_seconds integer, + live_now boolean, + premiere_timestamp timestamp with time zone, + views bigint, + CONSTRAINT channel_videos_id_key UNIQUE (id) + ); + + GRANT ALL ON TABLE public.channel_videos TO current_user; + + -- Index: public.channel_videos_ucid_idx + + -- DROP INDEX public.channel_videos_ucid_idx; + + CREATE INDEX IF NOT EXISTS channel_videos_ucid_idx + ON public.channel_videos + USING btree + (ucid COLLATE pg_catalog."default"); + + channels.sql: |+ + -- Table: public.channels + + -- DROP TABLE public.channels; + + CREATE TABLE IF NOT EXISTS public.channels + ( + id text NOT NULL, + author text, + updated timestamp with time zone, + deleted boolean, + subscribed timestamp with time zone, + CONSTRAINT channels_id_key UNIQUE (id) + ); + + GRANT ALL ON TABLE public.channels TO current_user; + + -- Index: public.channels_id_idx + + -- DROP INDEX public.channels_id_idx; + + CREATE INDEX IF NOT EXISTS channels_id_idx + ON public.channels + USING btree + (id COLLATE pg_catalog."default"); + + nonces.sql: |+ + -- Table: public.nonces + + -- DROP TABLE public.nonces; + + CREATE TABLE IF NOT EXISTS public.nonces + ( + nonce text, + expire timestamp with time zone, + CONSTRAINT nonces_id_key UNIQUE (nonce) + ); + + GRANT ALL ON TABLE public.nonces TO current_user; + + -- Index: public.nonces_nonce_idx + + -- DROP INDEX public.nonces_nonce_idx; + + CREATE INDEX IF NOT EXISTS nonces_nonce_idx + ON public.nonces + USING btree + (nonce COLLATE pg_catalog."default"); + + playlist_videos.sql: | + -- Table: public.playlist_videos + + -- DROP TABLE public.playlist_videos; + + CREATE TABLE IF NOT EXISTS public.playlist_videos + ( + title text, + id text, + author text, + ucid text, + length_seconds integer, + published timestamptz, + plid text references playlists(id), + index int8, + live_now boolean, + PRIMARY KEY (index,plid) + ); + + GRANT ALL ON TABLE public.playlist_videos TO current_user; + playlists.sql: | + -- Type: public.privacy + + -- DROP TYPE public.privacy; + + CREATE TYPE public.privacy AS ENUM + ( + 'Public', + 'Unlisted', + 'Private' + ); + + -- Table: public.playlists + + -- DROP TABLE public.playlists; + + CREATE TABLE IF NOT EXISTS public.playlists + ( + title text, + id text primary key, + author text, + description text, + video_count integer, + created timestamptz, + updated timestamptz, + privacy privacy, + index int8[] + ); + + GRANT ALL ON public.playlists TO current_user; + session_ids.sql: |+ + -- Table: public.session_ids + + -- DROP TABLE public.session_ids; + + CREATE TABLE IF NOT EXISTS public.session_ids + ( + id text NOT NULL, + email text, + issued timestamp with time zone, + CONSTRAINT session_ids_pkey PRIMARY KEY (id) + ); + + GRANT ALL ON TABLE public.session_ids TO current_user; + + -- Index: public.session_ids_id_idx + + -- DROP INDEX public.session_ids_id_idx; + + CREATE INDEX IF NOT EXISTS session_ids_id_idx + ON public.session_ids + USING btree + (id COLLATE pg_catalog."default"); + + users.sql: |+ + -- Table: public.users + + -- DROP TABLE public.users; + + CREATE TABLE IF NOT EXISTS public.users + ( + updated timestamp with time zone, + notifications text[], + subscriptions text[], + email text NOT NULL, + preferences text, + password text, + token text, + watched text[], + feed_needs_update boolean, + CONSTRAINT users_email_key UNIQUE (email) + ); + + GRANT ALL ON TABLE public.users TO current_user; + + -- Index: public.email_unique_idx + + -- DROP INDEX public.email_unique_idx; + + CREATE UNIQUE INDEX IF NOT EXISTS email_unique_idx + ON public.users + USING btree + (lower(email) COLLATE pg_catalog."default"); + + videos.sql: |+ + -- Table: public.videos + + -- DROP TABLE public.videos; + + CREATE UNLOGGED TABLE IF NOT EXISTS public.videos + ( + id text NOT NULL, + info text, + updated timestamp with time zone, + CONSTRAINT videos_pkey PRIMARY KEY (id) + ); + + GRANT ALL ON TABLE public.videos TO current_user; + + -- Index: public.id_idx + + -- DROP INDEX public.id_idx; + + CREATE UNIQUE INDEX IF NOT EXISTS id_idx + ON public.videos + USING btree + (id COLLATE pg_catalog."default"); diff --git a/invidious/values.yaml b/invidious/values.yaml index e086b39..546f3f9 100644 --- a/invidious/values.yaml +++ b/invidious/values.yaml @@ -9,6 +9,8 @@ imagePullSecrets: [] nameOverride: "" fullnameOverride: "" +# Setting replicaCount higher than 1 may cause PostgreSQL database deadlocks. +# This happens when multiple Invidious processes simultaneously attempt to refresh channel subscriptions for users. replicaCount: 1 autoscaling: @@ -64,7 +66,7 @@ tolerations: [] affinity: {} -# See https://github.com/bitnami/charts/tree/master/bitnami/postgresql +# Reference: https://github.com/bitnami/charts/tree/main/bitnami/postgresql postgresql: enabled: true image: @@ -79,7 +81,7 @@ postgresql: password: kemal scriptsConfigMap: invidious-postgresql-init -# Adapted from ../config/config.yml +# Reference: https://github.com/iv-org/invidious/blob/master/config/config.example.yml config: db: user: kemal