aboutsummaryrefslogtreecommitdiffstats
path: root/roles/invidious
diff options
context:
space:
mode:
authorStonewall Jackson <stonewall@sacredheartsc.com>2023-02-04 01:23:43 -0500
committerStonewall Jackson <stonewall@sacredheartsc.com>2023-02-04 01:52:13 -0500
commit0261e875679f1bf63c8d689da7fc7e014597885d (patch)
tree3f19cd74a0c1070944f75437f30b098d6ef2ffcb /roles/invidious
downloadselfhosted-0261e875679f1bf63c8d689da7fc7e014597885d.tar.gz
selfhosted-0261e875679f1bf63c8d689da7fc7e014597885d.zip
initial commit
Diffstat (limited to 'roles/invidious')
-rw-r--r--roles/invidious/defaults/main.yml38
-rw-r--r--roles/invidious/handlers/main.yml4
-rw-r--r--roles/invidious/meta/main.yml4
-rw-r--r--roles/invidious/tasks/database.yml69
-rw-r--r--roles/invidious/tasks/main.yml116
-rw-r--r--roles/invidious/templates/etc/systemd/system/invidious.service.j232
-rw-r--r--roles/invidious/templates/opt/invidious/invidious-db-cleanup.sh.j211
-rw-r--r--roles/invidious/templates/opt/invidious/invidious-update.sh.j242
-rw-r--r--roles/invidious/templates/opt/invidious/invidious/config/config.yml.j234
-rw-r--r--roles/invidious/vars/main.yml42
10 files changed, 392 insertions, 0 deletions
diff --git a/roles/invidious/defaults/main.yml b/roles/invidious/defaults/main.yml
new file mode 100644
index 0000000..01ad9b1
--- /dev/null
+++ b/roles/invidious/defaults/main.yml
@@ -0,0 +1,38 @@
+invidious_version: master
+invidious_crystal_version: 1.5.0-1
+
+invidious_server_name: '{{ ansible_fqdn }}'
+invidious_port: 8080
+invidious_user: invidious
+invidious_db_user: s-invidious
+invidious_db_name: invidious
+invidious_db_host: '{{ postgresql_host }}'
+
+invidious_db_cleanup_on_calendar: weekly
+invidious_update_on_calendar: weekly
+
+invidious_channel_threads: 1
+invidious_feed_threads: 1
+invidious_admin_email: 'root@{{ email_domain }}'
+invidious_registration_enabled: yes
+invidious_popular_enabled: no
+invidious_full_refresh: no
+invidious_hmac_key: secretKey
+invidious_use_pubsub_feeds: no
+
+invidious_default_locale: en-US
+invidious_default_region: US
+invidious_default_dark_mode: auto
+invidious_default_autoplay: no
+invidious_default_continue: yes
+invidious_default_continue_autoplay: no
+invidious_default_local: yes
+invidious_default_quality: dash
+invidious_default_quality_dash: 1080p
+invidious_default_related_videos: yes
+invidious_default_video_loop: no
+invidious_default_player_style: invidious
+invidious_default_home: Subscriptions
+invidious_feed_menu:
+ - Subscriptions
+ - Playlists
diff --git a/roles/invidious/handlers/main.yml b/roles/invidious/handlers/main.yml
new file mode 100644
index 0000000..150e02c
--- /dev/null
+++ b/roles/invidious/handlers/main.yml
@@ -0,0 +1,4 @@
+- name: restart invidious
+ systemd:
+ name: invidious
+ state: restarted
diff --git a/roles/invidious/meta/main.yml b/roles/invidious/meta/main.yml
new file mode 100644
index 0000000..29230f9
--- /dev/null
+++ b/roles/invidious/meta/main.yml
@@ -0,0 +1,4 @@
+dependencies:
+ - role: yum
+ yum_repositories: epel
+ tags: yum
diff --git a/roles/invidious/tasks/database.yml b/roles/invidious/tasks/database.yml
new file mode 100644
index 0000000..d8a44e1
--- /dev/null
+++ b/roles/invidious/tasks/database.yml
@@ -0,0 +1,69 @@
+- name: create postgresql database
+ postgresql_db:
+ name: '{{ invidious_db_name }}'
+ state: present
+ delegate_to: "{{ postgresql_host.split('.')[0] }}"
+ become: True
+ become_user: postgres
+
+- name: create postgresql user
+ postgresql_user:
+ name: '{{ invidious_db_user }}'
+ db: '{{ invidious_db_name }}'
+ password: '{{ invidious_db_password }}'
+ priv: ALL
+ state: present
+ environment:
+ PGOPTIONS: "-c password_encryption=scram-sha-256"
+ delegate_to: "{{ postgresql_host.split('.')[0] }}"
+ become: True
+ become_user: postgres
+
+- name: check if database schema is initialized
+ postgresql_query:
+ login_user: '{{ invidious_db_user }}'
+ login_password: '{{ invidious_db_password }}'
+ login_host: '{{ invidious_db_host }}'
+ db: '{{ invidious_db_name }}'
+ query: SELECT 1 FROM channels LIMIT 1
+ register: invidious_check_db
+ failed_when: false
+
+- name: initialize database schema
+ postgresql_query:
+ login_user: '{{ invidious_db_user }}'
+ login_password: '{{ invidious_db_password }}'
+ login_host: '{{ invidious_db_host }}'
+ db: '{{ invidious_db_name }}'
+ path_to_script: '{{ invidious_install_dir }}/config/sql/{{ item }}.sql'
+ as_single_query: yes
+ loop: '{{ invidious_schema_files }}'
+ when:
+ - invidious_check_db.msg is defined
+ - invidious_check_db.msg is search('relation "channels" does not exist')
+
+- name: create pgpass file
+ copy:
+ content: |
+ {{ invidious_db_host }}:*:{{ invidious_db_name }}:{{ invidious_db_user }}:{{ invidious_db_password }}
+ dest: '{{ invidious_home }}/.pgpass'
+ mode: 0600
+ owner: '{{ invidious_user }}'
+ group: '{{ invidious_user }}'
+
+- name: generate database cleanup script
+ template:
+ src: '{{ invidious_home[1:] }}/invidious-db-cleanup.sh.j2'
+ dest: '{{ invidious_home }}/invidious-db-cleanup.sh'
+ mode: 0555
+
+- name: set up invidious-db-cleanup timer
+ include_role:
+ name: systemd_timer
+ vars:
+ timer_name: invidious-db-cleanup
+ timer_description: Prune invidious database
+ timer_after: network.target
+ timer_user: '{{ invidious_user }}'
+ timer_on_calendar: '{{ invidious_db_cleanup_on_calendar }}'
+ timer_exec: '{{ invidious_home }}/invidious-db-cleanup.sh'
diff --git a/roles/invidious/tasks/main.yml b/roles/invidious/tasks/main.yml
new file mode 100644
index 0000000..4a2cf0c
--- /dev/null
+++ b/roles/invidious/tasks/main.yml
@@ -0,0 +1,116 @@
+- name: install dependencies
+ dnf:
+ name: '{{ invidious_packages }}'
+ state: present
+
+- name: create crystal directory
+ file:
+ path: '{{ invidious_crystal_install_dir }}'
+ state: directory
+
+- name: download crystal-lang
+ unarchive:
+ src: '{{ invidious_crystal_url }}'
+ dest: '{{ invidious_crystal_install_dir }}'
+ remote_src: yes
+ extra_opts: --strip-components=1
+
+- name: create local user
+ user:
+ name: '{{ invidious_user }}'
+ system: yes
+ home: '{{ invidious_home }}'
+ shell: /sbin/nologin
+ create_home: no
+
+- name: create home home directory
+ file:
+ path: '{{ invidious_home }}'
+ owner: '{{ invidious_user }}'
+ group: '{{ invidious_user }}'
+ mode: 0755
+ state: directory
+
+- name: clone repo
+ git:
+ repo: '{{ invidious_git_repo }}'
+ dest: '{{ invidious_install_dir }}'
+ version: '{{ invidious_version }}'
+ update: yes
+ force: yes
+ become: yes
+ become_user: '{{ invidious_user }}'
+ register: invidious_git
+
+- name: build invidious
+ command:
+ cmd: '{{ item }}'
+ chdir: '{{ invidious_install_dir }}'
+ environment:
+ PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:{{ invidious_crystal_install_dir }}/bin
+ loop:
+ - shards install --production
+ - crystal build src/invidious.cr -Ddisable_quic --release
+ when: invidious_git.changed
+ become: yes
+ become_user: '{{ invidious_user }}'
+
+- name: create systemd unit
+ template:
+ src: etc/systemd/system/invidious.service.j2
+ dest: /etc/systemd/system/invidious.service
+ register: invidious_unit
+ notify: restart invidious
+
+- name: reload systemd daemons
+ systemd:
+ daemon_reload: yes
+ when: invidious_unit.changed
+
+- name: generate config file
+ template:
+ src: '{{ invidious_install_dir[1:] }}/config/config.yml.j2'
+ dest: '{{ invidious_install_dir }}/config/config.yml'
+ owner: '{{ invidious_user }}'
+ group: '{{ invidious_user }}'
+ mode: 0600
+ notify: restart invidious
+
+- import_tasks: database.yml
+
+- name: allow apache to connect to invidious port
+ seport:
+ ports: '{{ invidious_port }}'
+ proto: tcp
+ setype: http_port_t
+ state: present
+ tags: selinux
+
+- name: start invidious
+ systemd:
+ name: invidious
+ enabled: yes
+ state: started
+
+- name: generate update script
+ template:
+ src: '{{ invidious_home[1:] }}/invidious-update.sh.j2'
+ dest: '{{ invidious_home }}/invidious-update.sh'
+ mode: 0555
+
+- name: create invidious-update timer
+ include_role:
+ name: systemd_timer
+ vars:
+ timer_name: invidious-update
+ timer_description: Update invidious
+ timer_after: network.target
+ timer_on_calendar: '{{ invidious_update_on_calendar }}'
+ timer_exec: '{{ invidious_home }}/invidious-update.sh'
+
+- name: restart invidious daily at 3:30am
+ cron:
+ name: restart invidious
+ minute: 30
+ hour: 3
+ job: systemctl restart invidious
diff --git a/roles/invidious/templates/etc/systemd/system/invidious.service.j2 b/roles/invidious/templates/etc/systemd/system/invidious.service.j2
new file mode 100644
index 0000000..c711185
--- /dev/null
+++ b/roles/invidious/templates/etc/systemd/system/invidious.service.j2
@@ -0,0 +1,32 @@
+[Unit]
+Description=Invidious youtube client
+After=network.target
+AssertPathExists={{ invidious_install_dir }}
+
+[Service]
+Type=simple
+ExecStart={{ invidious_install_dir }}/invidious
+User={{ invidious_user }}
+Group={{ invidious_user }}
+WorkingDirectory={{ invidious_install_dir }}
+Restart=always
+
+# See https://www.freedesktop.org/software/systemd/man/systemd.exec.html
+# for details
+DevicePolicy=closed
+NoNewPrivileges=yes
+PrivateDevices=yes
+PrivateTmp=yes
+ProtectControlGroups=yes
+ProtectKernelModules=yes
+ProtectKernelTunables=yes
+RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
+RestrictNamespaces=yes
+RestrictRealtime=yes
+SystemCallFilter=~@clock @debug @module @mount @obsolete @privileged @reboot @setuid @swap
+
+ProtectSystem=full
+ProtectHome=true
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/invidious/templates/opt/invidious/invidious-db-cleanup.sh.j2 b/roles/invidious/templates/opt/invidious/invidious-db-cleanup.sh.j2
new file mode 100644
index 0000000..1c9ffe1
--- /dev/null
+++ b/roles/invidious/templates/opt/invidious/invidious-db-cleanup.sh.j2
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+set -eu
+
+PG_HOST={{ invidious_db_host | quote }}
+PG_USER={{ invidious_db_user | quote }}
+PG_NAME={{ invidious_db_name | quote }}
+
+export PGPASSFILE={{ invidious_home | quote }}/.pgpass
+
+psql -qtA -h "$PG_HOST" "$PG_NAME" "$PG_USER" -c {{ invidious_db_cleanup_sql | join('; ') | quote }}
diff --git a/roles/invidious/templates/opt/invidious/invidious-update.sh.j2 b/roles/invidious/templates/opt/invidious/invidious-update.sh.j2
new file mode 100644
index 0000000..561e45e
--- /dev/null
+++ b/roles/invidious/templates/opt/invidious/invidious-update.sh.j2
@@ -0,0 +1,42 @@
+#!/usr/bin/env bash
+
+set -eu
+
+SRCDIR={{ invidious_install_dir | quote }}
+INVIDIOUS_USER={{ invidious_user | quote }}
+CRYSTAL_HOME={{ invidious_crystal_install_dir | quote }}
+
+export PATH="${PATH}:${CRYSTAL_HOME}/bin"
+
+as-invidious() {
+ runuser -u "$INVIDIOUS_USER" -- "$@"
+}
+
+if (( $EUID != 0 )); then
+ echo 'must be superuser' 1>&2
+ exit 1
+fi
+
+cd "$SRCDIR"
+
+old_rev=$(git rev-list --max-count=1 --abbrev-commit HEAD)
+
+as-invidious git fetch
+
+local_rev=$(git rev-parse HEAD)
+upstream_rev=$(git rev-parse '@{u}')
+
+echo "local: $local_rev"
+echo "upstream: $upstream_rev"
+
+if [ "$local_rev" != "$upstream_rev" ]; then
+ as-invidious git pull --ff-only
+
+ echo "building invidious..."
+ as-invidious shards install --production
+ as-invidious crystal build src/invidious.cr -Ddisable_quic --release
+
+ systemctl restart invidious
+else
+ echo "invidious is already up to date"
+fi
diff --git a/roles/invidious/templates/opt/invidious/invidious/config/config.yml.j2 b/roles/invidious/templates/opt/invidious/invidious/config/config.yml.j2
new file mode 100644
index 0000000..e74caee
--- /dev/null
+++ b/roles/invidious/templates/opt/invidious/invidious/config/config.yml.j2
@@ -0,0 +1,34 @@
+log_level: warn
+domain: {{ invidious_server_name }}
+external_port: 443
+channel_threads: {{ invidious_channel_threads }}
+feed_threads: {{ invidious_channel_threads }}
+database_url: postgres://{{ invidious_db_user }}:{{ invidious_db_password}}@{{ invidious_db_host }}/{{ invidious_db_name }}?sslmode=verify-full
+use_pubsub_feeds: {{ invidious_use_pubsub_feeds }}
+hmac_key: {{ invidious_hmac_key }}
+https_only: true
+registration_enabled: {{ invidious_registration_enabled }}
+admin_email: {{ invidious_admin_email }}
+port: {{ invidious_port }}
+host_binding: 127.0.0.1
+popular_enabled: {{ invidious_popular_enabled }}
+full_refresh: {{ invidious_full_refresh }}
+captcha_enabled: false
+check_tables: true
+cache_annotations: true
+
+default_user_preferences:
+ dark_mode: {{ invidious_default_dark_mode }}
+ autoplay: {{ invidious_default_autoplay }}
+ continue: {{ invidious_default_continue }}
+ continue_autoplay: {{ invidious_default_continue_autoplay }}
+ local: {{ invidious_default_local }}
+ quality: {{ invidious_default_quality }}
+ quality_dash: {{ invidious_default_quality_dash }}
+ locale: {{ invidious_default_locale }}
+ region: {{ invidious_default_region }}
+ related_videos: {{ invidious_default_related_videos }}
+ video_loop: {{ invidious_default_video_loop }}
+ player_style: {{ invidious_default_player_style }}
+ default_home: {{ invidious_default_home }}
+ feed_menu: {{ invidious_feed_menu | to_yaml }}
diff --git a/roles/invidious/vars/main.yml b/roles/invidious/vars/main.yml
new file mode 100644
index 0000000..36ca643
--- /dev/null
+++ b/roles/invidious/vars/main.yml
@@ -0,0 +1,42 @@
+invidious_packages:
+ - openssl-devel
+ - libevent-devel
+ - libxml2-devel
+ - libyaml-devel
+ - gmp-devel
+ - readline-devel
+ - postgresql
+ - librsvg2-devel
+ - sqlite-devel
+ - zlib-devel
+ - gcc
+ - git
+ - python3-psycopg2
+
+invidious_git_repo: https://github.com/iv-org/invidious
+invidious_home: /opt/invidious
+invidious_install_dir: '{{ invidious_home }}/invidious'
+
+invidious_crystal_url: https://github.com/crystal-lang/crystal/releases/download/{{ invidious_crystal_version | regex_replace('-.*$', '') }}/crystal-{{ invidious_crystal_version }}-linux-x86_64.tar.gz
+invidious_crystal_install_dir: /opt/crystal
+
+invidious_schema_files:
+ - channels
+ - videos
+ - channel_videos
+ - users
+ - session_ids
+ - nonces
+ - annotations
+ - playlists
+ - playlist_videos
+
+invidious_db_cleanup_sql:
+ - DELETE FROM nonces * WHERE expire < current_timestamp
+ - TRUNCATE TABLE videos
+
+invidious_apache_config: |
+ AllowEncodedSlashes NoDecode
+ {{ apache_proxy_config }}
+ ProxyPass / http://127.0.0.1:{{ invidious_port }}/ nocanon
+ ProxyPassReverse / http://127.0.0.1:{{ invidious_port }}/