From 81d2ea447a5cf23995efd89bfa3c4edb5ab65205 Mon Sep 17 00:00:00 2001 From: Kris Lamoureux Date: Wed, 26 Apr 2023 02:26:50 -0400 Subject: [PATCH] Add mediaserver, rm .gitignore, FQCN, Jellyfin - Added development "mediaserver" playbook for testing - rm .gitignore in roles dir since no external ansible roles are used - Update a part of the base role to use FQCN for linting - Added "jellyfin" role to install Jellyfin with docker-compose - Updated Traefik to use the loopback for default web entry points - Simplified Traefik docker-compose vars, Ansible sets defaults --- dev/host_vars/mediaserver.yml | 37 +++++++++++++++++++ dev/mediaserver.yml | 11 ++++++ mediaserver.yml | 9 +++++ roles/.gitignore | 20 ---------- roles/base/handlers/main.yml | 12 ++++-- roles/base/tasks/ansible.yml | 6 +-- roles/base/tasks/ddclient.yml | 13 ++----- roles/jellyfin/defaults/main.yml | 5 +++ roles/jellyfin/handlers/main.yml | 5 +++ roles/jellyfin/tasks/main.yml | 37 +++++++++++++++++++ roles/jellyfin/templates/compose-env.j2 | 5 +++ .../jellyfin/templates/docker-compose.yml.j2 | 29 +++++++++++++++ roles/traefik/defaults/main.yml | 4 +- roles/traefik/templates/docker-compose.yml.j2 | 6 +-- update-hosts.sh | 1 + 15 files changed, 160 insertions(+), 40 deletions(-) create mode 100644 dev/host_vars/mediaserver.yml create mode 100644 dev/mediaserver.yml create mode 100644 mediaserver.yml delete mode 100644 roles/.gitignore create mode 100644 roles/jellyfin/defaults/main.yml create mode 100644 roles/jellyfin/handlers/main.yml create mode 100644 roles/jellyfin/tasks/main.yml create mode 100644 roles/jellyfin/templates/compose-env.j2 create mode 100644 roles/jellyfin/templates/docker-compose.yml.j2 diff --git a/dev/host_vars/mediaserver.yml b/dev/host_vars/mediaserver.yml new file mode 100644 index 0000000..39dafe1 --- /dev/null +++ b/dev/host_vars/mediaserver.yml @@ -0,0 +1,37 @@ +base_domain: vm.krislamo.org + +# base +allow_reboot: false +manage_network: false + +# proxy +proxy: + #production: true + dns_cloudflare: + opts: --test-cert + #email: realemail@example.com + #api_token: CLOUDFLARE_DNS01_API_TOKEN + wildcard_domains: + - "{{ base_domain }}" + servers: + - domain: "{{ traefik_domain }}" + proxy_pass: "http://127.0.0.1:8000" + - domain: "{{ jellyfin_domain }}" + proxy_pass: "http://127.0.0.1:8000" + +# docker +docker_users: + - vagrant + +# traefik +traefik_version: latest +traefik_dashboard: true +traefik_domain: "traefik.{{ base_domain }}" +traefik_auth: admin:$apr1$T1l.BCFz$Jyg8msXYEAUi3LLH39I9d1 # admin:admin +#traefik_acme_email: realemail@example.com # Let's Encrypt settings +#traefik_production: true +traefik_http_only: true # if behind reverse-proxy + +# jellyfin +jellyfin_domain: "jellyfin.{{ base_domain }}" +jellyfin_version: latest diff --git a/dev/mediaserver.yml b/dev/mediaserver.yml new file mode 100644 index 0000000..ce66f96 --- /dev/null +++ b/dev/mediaserver.yml @@ -0,0 +1,11 @@ +- name: Install Media Server + hosts: all + become: true + vars_files: + - host_vars/mediaserver.yml + roles: + - base + - proxy + - docker + - traefik + - jellyfin diff --git a/mediaserver.yml b/mediaserver.yml new file mode 100644 index 0000000..beb0fec --- /dev/null +++ b/mediaserver.yml @@ -0,0 +1,9 @@ +- name: Install Media Server + hosts: mediaservers + become: true + roles: + - base + - proxy + - docker + - traefik + - jellyfin diff --git a/roles/.gitignore b/roles/.gitignore deleted file mode 100644 index bb43362..0000000 --- a/roles/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -/* -!.gitignore -!requirements.yml -!base*/ -!bitwarden*/ -!docker*/ -!gitea*/ -!jenkins*/ -!libvirt*/ -!mariadb*/ -!minecraft*/ -!nextcloud*/ -!nginx*/ -!postgresql*/ -!prometheus*/ -!proxy*/ -!rsnapshot*/ -!traefik*/ -!unifi*/ -!wordpress*/ diff --git a/roles/base/handlers/main.yml b/roles/base/handlers/main.yml index 3372219..59f85df 100644 --- a/roles/base/handlers/main.yml +++ b/roles/base/handlers/main.yml @@ -1,18 +1,24 @@ - name: Reboot host - reboot: + ansible.builtin.reboot: msg: "Reboot initiated by Ansible" connect_timeout: 5 listen: reboot_host when: allow_reboot - name: Restart WireGuard - service: + ansible.builtin.service: name: wg-quick@wg0 state: restarted listen: restart_wireguard - name: Restart Fail2ban - service: + ansible.builtin.service: name: fail2ban state: restarted listen: restart_fail2ban + +- name: Restart ddclient + ansible.builtin.service: + name: ddclient + state: restarted + listen: restart_ddclient diff --git a/roles/base/tasks/ansible.yml b/roles/base/tasks/ansible.yml index c130855..7b2c06b 100644 --- a/roles/base/tasks/ansible.yml +++ b/roles/base/tasks/ansible.yml @@ -1,11 +1,11 @@ - name: 'Install Ansible dependency: python3-apt' - shell: 'apt-get update && apt-get install python3-apt -y' + ansible.builtin.shell: 'apt-get update && apt-get install python3-apt -y' args: creates: /usr/lib/python3/dist-packages/apt warn: false - name: Install additional Ansible dependencies - apt: + ansible.builtin.apt: name: "{{ item }}" state: present force_apt_get: true @@ -17,7 +17,7 @@ - python3-psycopg2 - name: Create Ansible's temporary remote directory - file: + ansible.builtin.file: path: "~/.ansible/tmp" state: directory mode: 0700 diff --git a/roles/base/tasks/ddclient.yml b/roles/base/tasks/ddclient.yml index f1e1121..7643c83 100644 --- a/roles/base/tasks/ddclient.yml +++ b/roles/base/tasks/ddclient.yml @@ -1,22 +1,17 @@ - name: Install ddclient - apt: + ansible.builtin.apt: name: ddclient state: present - name: Install ddclient settings - template: + ansible.builtin.template: src: ddclient.conf.j2 dest: /etc/ddclient.conf + mode: 0600 register: ddclient_settings - name: Start ddclient and enable on boot - service: + ansible.builtin.service: name: ddclient state: started enabled: true - -- name: Restart ddclient - service: - name: ddclient - state: restarted - when: ddclient_settings.changed diff --git a/roles/jellyfin/defaults/main.yml b/roles/jellyfin/defaults/main.yml new file mode 100644 index 0000000..a58f97e --- /dev/null +++ b/roles/jellyfin/defaults/main.yml @@ -0,0 +1,5 @@ +jellyfin_name: jellyfin +jellyfin_volume: "{{ jellyfin_name }}" +jellyfin_router: "{{ jellyfin_name }}" +jellyfin_rooturl: "https://{{ jellyfin_domain }}" +jellyfin_root: "{{ docker_compose_root }}/{{ jellyfin_name }}" \ No newline at end of file diff --git a/roles/jellyfin/handlers/main.yml b/roles/jellyfin/handlers/main.yml new file mode 100644 index 0000000..cb6ec9a --- /dev/null +++ b/roles/jellyfin/handlers/main.yml @@ -0,0 +1,5 @@ +- name: Restart Jellyfin + service: + name: "{{ docker_compose_service }}@{{ jellyfin_name }}" + state: restarted + listen: restart_jellyfin diff --git a/roles/jellyfin/tasks/main.yml b/roles/jellyfin/tasks/main.yml new file mode 100644 index 0000000..f2c97e1 --- /dev/null +++ b/roles/jellyfin/tasks/main.yml @@ -0,0 +1,37 @@ +- name: Create Jellyfin directory + ansible.builtin.file: + path: "{{ jellyfin_root }}" + state: directory + +- name: Create jellyfin user + user: + name: jellyfin + state: present + +- name: jellyfin user uid + getent: + database: passwd + key: jellyfin + +- name: jellyfin user gid + getent: + database: group + key: jellyfin + +- name: Install Jellyfin's docker-compose file + template: + src: docker-compose.yml.j2 + dest: "{{ jellyfin_root }}/docker-compose.yml" + notify: restart_jellyfin + +- name: Install Jellyfin's docker-compose variables + template: + src: compose-env.j2 + dest: "{{ jellyfin_root }}/.env" + notify: restart_jellyfin + +- name: Start and enable Jellyfin service + service: + name: "{{ docker_compose_service }}@{{ jellyfin_name }}" + state: started + enabled: true diff --git a/roles/jellyfin/templates/compose-env.j2 b/roles/jellyfin/templates/compose-env.j2 new file mode 100644 index 0000000..9edc54c --- /dev/null +++ b/roles/jellyfin/templates/compose-env.j2 @@ -0,0 +1,5 @@ +# {{ ansible_managed }} +jellyfin_version={{ jellyfin_version }} +jellyfin_name={{ jellyfin_name }} +jellyfin_domain={{ jellyfin_domain }} +jellyfin_rooturl={{ jellyfin_rooturl }} diff --git a/roles/jellyfin/templates/docker-compose.yml.j2 b/roles/jellyfin/templates/docker-compose.yml.j2 new file mode 100644 index 0000000..51e7d0d --- /dev/null +++ b/roles/jellyfin/templates/docker-compose.yml.j2 @@ -0,0 +1,29 @@ +version: '3.7' + +volumes: + {{ jellyfin_volume }}: + +networks: + traefik: + external: true + +services: + jellyfin: + image: "jellyfin/jellyfin:${jellyfin_version}" + container_name: "${jellyfin_name}" + networks: + - traefik + labels: + - "traefik.http.routers.{{ jellyfin_router }}.rule=Host(`{{ jellyfin_domain }}`)" +{% if traefik_http_only %} + - "traefik.http.routers.{{ jellyfin_router }}.entrypoints=web" +{% else %} + - "traefik.http.routers.{{ jellyfin_router }}.entrypoints=websecure" +{% endif %} + - "traefik.http.services.{{ jellyfin_router }}.loadbalancer.server.port=8096" + - "traefik.docker.network=traefik" + - "traefik.enable=true" + volumes: + - ./config:/config + - ./cache:/cache + - {{ jellyfin_volume }}:/media diff --git a/roles/traefik/defaults/main.yml b/roles/traefik/defaults/main.yml index 43f09ed..060328b 100644 --- a/roles/traefik/defaults/main.yml +++ b/roles/traefik/defaults/main.yml @@ -3,8 +3,8 @@ traefik_name: traefik traefik_standalone: true traefik_http_only: false traefik_debug: false -traefik_web_entry: "80:80" -traefik_websecure_entry: "443:443" +traefik_web_entry: "127.0.0.1:8000" +traefik_websecure_entry: "127.0.0.1:8443" traefik_localonly: "10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8" # HTTPS settings diff --git a/roles/traefik/templates/docker-compose.yml.j2 b/roles/traefik/templates/docker-compose.yml.j2 index fb7f741..b5c9224 100644 --- a/roles/traefik/templates/docker-compose.yml.j2 +++ b/roles/traefik/templates/docker-compose.yml.j2 @@ -9,9 +9,9 @@ services: image: "traefik:${traefik_version}" container_name: "${traefik_name}" ports: - - "${traefik_web_entry:-80:80}" + - "${traefik_web_entry}:80" {% if traefik_standalone and not traefik_http_only %} - - "${traefik_websecure_entry:-443:443}" + - "${traefik_websecure_entry}:443" {% endif %} networks: - traefik @@ -19,7 +19,7 @@ services: - "traefik.http.routers.traefik.rule=Host(`{{ traefik_domain }}`)" - "traefik.http.routers.traefik.service=api@internal" - "traefik.docker.network=traefik" - - "traefik.enable=${traefik_dashboard:-false}" + - "traefik.enable=${traefik_dashboard}" volumes: - /var/run/docker.sock:/var/run/docker.sock - "{{ traefik_root }}/config:/etc/traefik" diff --git a/update-hosts.sh b/update-hosts.sh index 7131117..2dc7cc8 100755 --- a/update-hosts.sh +++ b/update-hosts.sh @@ -14,6 +14,7 @@ HOST[8]="wordpress.${DOMAIN}" HOST[9]="site1.wordpress.${DOMAIN}" HOST[10]="site2.wordpress.${DOMAIN}" HOST[11]="unifi.${DOMAIN}" +HOST[12]="jellyfin.${DOMAIN}" # Get Vagrantbox guest IP VAGRANT_OUTPUT=$(vagrant ssh -c "hostname -I | cut -d' ' -f2" 2>/dev/null)