diff --git a/grail.tf b/grail.tf new file mode 100644 index 0000000..9628133 --- /dev/null +++ b/grail.tf @@ -0,0 +1,45 @@ +resource "proxmox_lxc" "LXC" { + target_node = "pve" + hostname = "grail-tf" + vmid = 218 + ostemplate = "local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst" + password = "terraform" + unprivileged = true + cores = 10 + memory = 4096 + swap = 1024 + start = true + tags = "terraform" + nameserver = "192.168.0.24" + ssh_public_keys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINFw70PrMsilcsqCrwW1I6PAt3anQbhmVg+t/HUfomug ryan@mxDesktop" + + features { + nesting = true + } + + rootfs { + storage = "junk2" + size = "32G" + } + + mountpoint{ + key = "0" + slot = 0 + storage = "Cephtest" + mp = "/data" + size = "400G" + } + + network { + name = "eth0" + bridge = "vmbr0" + ip = "192.168.0.57/24" + gw = "192.168.0.1" + + } + + provisioner "local-exec" { + command = "./.ansible.d/setup.sh" + } + +} \ No newline at end of file diff --git a/roles/ind/grail/cron.vars b/roles/ind/grail/cron.vars new file mode 100644 index 0000000..5b69bbe --- /dev/null +++ b/roles/ind/grail/cron.vars @@ -0,0 +1,18 @@ +--- +cronjob: + + - name: appdata + job_name: "Daily /data/ Backup" + job_minute: "0" + job_hour: "3" + job_day: "*" + user: "root" + job_command: "/home/docker/restic.sh --backup /data/ " + + - name: weeklydb + job_name: "Weekly /data/ verification" + job_minute: "10" + job_hour: "6" + job_day: "1" + user: "root" + job_command: "/home/docker/restic.sh --verify /data/" \ No newline at end of file diff --git a/roles/ind/grail/docker-compose.env b/roles/ind/grail/docker-compose.env new file mode 100644 index 0000000..893016a --- /dev/null +++ b/roles/ind/grail/docker-compose.env @@ -0,0 +1,121 @@ +######################################################################## +######################################################################## +######################################################################## +## +## Docker Compose Environment Variable file for Jellyfin Media Stack +## +## Update any of the environment variables below as required. +## +## It is highly recommended Linux users set up a "docker" +## user, so the applications can access the local filesystem +## with this user's access privileges. Use PUID / PGID to map +## user access between the Docker apps and local filesystem. +## +######################################################################## +######################################################################## +######################################################################## + +#Name of the project in Docker +COMPOSE_PROJECT_NAME=media-stack + +# This is the network subnet which will be used inside the docker "media_network", change as required. +# LOCAL_SUBNET is your home network and is needed so the VPN client allows access to your home computers. +DOCKER_SUBNET=172.28.10.0/24 +DOCKER_GATEWAY=172.28.10.1 +LOCAL_SUBNET=192.168.0.0/24 +LOCAL_DOCKER_IP=192.168.0.6 + +# Each of the "*ARR" applications have been configured so the theme can be changed to your needs. +# Refer to Theme Park for more info / options: https://docs.theme-park.dev/theme-options/aquamarine/ +TP_DISABLE_THEME=false +TP_THEME=nord + +# These are the folders on your local host computer / NAS running docker, they MUST exist +# and have correct permissions for PUID and PGUI prior to running the docker-compose. +# +# Use the commands in the Guide to create all the sub-folders in each of these folders. + +# Host Data Folders - Will accept Linux, Windows, NAS folders +FOLDER_FOR_CONFIGS=/home/grail/docker +FOLDER_FOR_MEDIA=/data + +# File access, date and time details for the containers / applications to use. +# Run "sudo id docker" on host computer to find PUID / PGID and update these to suit. +PUID=1000 +PGID=1000 +UMASK=0002 +TIMEZONE=America/Chicago + +# Update your own Internet VPN provide details below +VPN_TYPE=openvpn +VPN_SERVICE_PROVIDER=airvpn +VPN_USERNAME= +VPN_PASSWORD= + + +SERVER_COUNTRIES= +SERVER_REGION= +SERVER_CITIES="Chicago Illinois" +SERVER_HOSTNAMES= + +# Fill in this item ONLY if you're using a custom OpenVPN configuration +# Should be inside gluetun data folder - Example: /gluetun/custom-openvpn.conf +# You can then edit it inside the FOLDER_FOR_CONFIGS location for gluetun. +OPENVPN_CUSTOM_CONFIG=/gluetun/ipvanish.openvpn.conf +#OPENVPN_CUSTOM_CONFIG= + +# Fill in these items ONLY if you change VPN_TYPE to "wireguard" +VPN_ENDPOINT_IP= +VPN_ENDPOINT_PORT= +WIREGUARD_PUBLIC_KEY= +WIREGUARD_PRIVATE_KEY= +WIREGUARD_PRESHARED_KEY= +WIREGUARD_ADDRESSES= + +# These are the default ports used to access each of the application in your web browser. +# You can safely change these if you need, but they can't conflict with other active ports. +QBIT_PORT_TCP=44172 +QBIT_PORT_UDP=44172 + +FLARESOLVERR_PORT=8191 + +TDARR_SERVER_PORT=8266 +WEBUI_PORT_TDARR=8265 + +WEBUI_PORT_BAZARR=6767 +WEBUI_PORT_DDNS_UPDATER=6500 +WEBUI_PORT_JELLYFIN=8096 +WEBUI_PORT_JELLYSEERR=5055 +WEBUI_PORT_LIDARR=8686 +WEBUI_PORT_MYLAR3=8090 +WEBUI_PORT_PORTAINER=9443 +WEBUI_PORT_PROWLARR=9696 +WEBUI_PORT_QBITTORRENT=8200 +WEBUI_PORT_RADARR=7878 +WEBUI_PORT_READARR=8787 +WEBUI_PORT_SONARR=8989 +WEBUI_PORT_SABNZBD=8100 +WEBUI_PORT_WHISPARR=6969 + +# SWAG is configured for Reverse Proxy. Set your Internet gateway to redirect incoming ports 80 and 443 +# to the ports used below (using Docker IP Address), and they will be translated back to 80 and 443 by SWAG. +# Change these port numbers if you have conflicting services running on the Docker host computer. + +REVERSE_PROXY_PORT_HTTP=5080 +REVERSE_PROXY_PORT_HTTPS=5443 + +# SWAG REVERSE PROXY SETTINGS: +URL=your-domain-name-goes-here.com +SUBDOMAINS=wildcard +VALIDATION=dns +DNSPLUGIN=cloudflare +CERTPROVIDER= +PROPAGATION= +DUCKDNSTOKEN= +EMAIL= +ONLY_SUBDOMAINS=false +EXTRA_DOMAINS= +STAGING=false +HEALTH_VPN_DURATION_INITIAL=45s +HEALTH_VPN_DURATION_ADDITION=30s +UPDATER_PERIOD=8h \ No newline at end of file diff --git a/roles/ind/grail/docker-compose.yml b/roles/ind/grail/docker-compose.yml new file mode 100644 index 0000000..2585aa0 --- /dev/null +++ b/roles/ind/grail/docker-compose.yml @@ -0,0 +1,203 @@ +networks: + media-network: + name: media-network + driver: bridge + ipam: + driver: default + config: + - subnet: ${DOCKER_SUBNET:?err} + gateway: ${DOCKER_GATEWAY:?err} + +services: + gluetun: + image: qmcgaw/gluetun:latest + container_name: gluetun + restart: always + cap_add: + - NET_ADMIN + devices: + - /dev/net/tun:/dev/net/tun + ports: + - "8888:8888/tcp" # Gluetun Local Network HTTP proxy + - "8388:8388/tcp" # Gluetun Local Network Shadowsocks + - "8388:8388/udp" # Gluetun Local Network Shadowsocks + - "8200:8200" # WebUI Portal: qBittorrent + - "${QBIT_PORT_TCP:?err}:44172/tcp" # Transmission Torrent Port TCP + - "${QBIT_PORT_UDP:?err}:44172/udp" # Transmission Torrent Port UDP + env_file: + - ./docker-compose.env + volumes: + - ${FOLDER_FOR_CONFIGS:?err}/gluetun:/gluetun + environment: + - PUID=${PUID:?err} + - PGID=${PGID:?err} + - TZ=${TIMEZONE:?err} + - VPN_SERVICE_PROVIDER=${VPN_SERVICE_PROVIDER:?err} + - OPENVPN_USER=${VPN_USERNAME} + - OPENVPN_PASSWORD=${VPN_PASSWORD} + - SERVER_COUNTRIES=${SERVER_COUNTRIES} + - SERVER_REGION=${SERVER_REGION} + - SERVER_CITIES=${SERVER_CITIES} + - SERVER_HOSTNAMES=${SERVER_HOSTNAMES} + - FIREWALL_OUTBOUND_SUBNETS=${LOCAL_SUBNET:?err} + - OPENVPN_CUSTOM_CONFIG=${OPENVPN_CUSTOM_CONFIG} + - VPN_TYPE=${VPN_TYPE} + - VPN_ENDPOINT_IP=${VPN_ENDPOINT_IP} + - VPN_ENDPOINT_PORT=${VPN_ENDPOINT_PORT} + - WIREGUARD_PUBLIC_KEY=${WIREGUARD_PUBLIC_KEY} + - WIREGUARD_PRIVATE_KEY=${WIREGUARD_PRIVATE_KEY} + - WIREGUARD_PRESHARED_KEY=${WIREGUARD_PRESHARED_KEY} + - WIREGUARD_ADDRESSES=${WIREGUARD_ADDRESSES} + - HTTPPROXY=on + - SHADOWSOCKS=on +# NOTE: Gluetun VPN container MUST ONLY connect to the media-network + networks: + - media-network + + bazarr: + image: lscr.io/linuxserver/bazarr:latest + container_name: bazarr + restart: unless-stopped + volumes: + - ${FOLDER_FOR_CONFIGS:?err}/bazarr:/config + - ${FOLDER_FOR_MEDIA:?err}:/data + - /ceph:/downloads + ports: + - "${WEBUI_PORT_BAZARR:?err}:6767" + environment: + - PUID=${PUID:?err} + - PGID=${PGID:?err} + - TZ=${TIMEZONE:?err} + - DOCKER_MODS=ghcr.io/gilbn/theme.park:bazarr + - TP_THEME=${TP_THEME:?err} + networks: + - media-network + + jellyseerr: + image: fallenbagel/jellyseerr:latest + container_name: jellyseerr + restart: unless-stopped + volumes: + - ${FOLDER_FOR_CONFIGS:?err}/jellyseerr:/app/config + ports: + - "${WEBUI_PORT_JELLYSEERR:?err}:5055" + environment: + - PUID=${PUID:?err} + - PGID=${PGID:?err} + - UMASK=${UMASK:?err} + - TZ=${TIMEZONE:?err} + networks: + - media-network + + prowlarr: + image: lscr.io/linuxserver/prowlarr:develop + container_name: prowlarr + restart: unless-stopped + volumes: + - ${FOLDER_FOR_CONFIGS:?err}/prowlarr:/config + ports: + - "${WEBUI_PORT_PROWLARR:?err}:9696" + environment: + - PUID=${PUID:?err} + - PGID=${PGID:?err} + - TZ=${TIMEZONE:?err} + - DOCKER_MODS=ghcr.io/gilbn/theme.park:prowlarr + - TP_THEME=${TP_THEME:?err} + networks: + - media-network + + qbittorrent: + image: lscr.io/linuxserver/qbittorrent:latest + container_name: qbittorrent + restart: unless-stopped + volumes: + - ${FOLDER_FOR_CONFIGS:?err}/qbittorrent:/config + - ${FOLDER_FOR_MEDIA:?err}:/data + - /ceph:/downloads + environment: + - PUID=${PUID:?err} + - PGID=${PGID:?err} + - UMASK=${UMASK:?err} + - TZ=${TIMEZONE:?err} + - WEBUI_PORT=8200 + - DOCKER_MODS=ghcr.io/themepark-dev/theme.park:qbittorrent-develop + - TP_THEME=${TP_THEME:?err} + depends_on: + - gluetun + + network_mode: "service:gluetun" + qbit-exporter: + image: caseyscarborough/qbittorrent-exporter:latest + container_name: qbit-exporter + ports: + - "17871:17871" + environment: + - QBITTORRENT_USERNAME=admin + - QBITTORRENT_PASSWORD=hammy1 + - QBITTORRENT_BASE_URL=http://192.168.0.5:8200 + + radarr: + image: lscr.io/linuxserver/radarr:latest + container_name: radarr + restart: unless-stopped + volumes: + - /ceph:/downloads + - ${FOLDER_FOR_CONFIGS:?err}/radarr:/config + - ${FOLDER_FOR_MEDIA:?err}:/data + ports: + - "${WEBUI_PORT_RADARR:?err}:7878" + environment: + - PUID=${PUID:?err} + - PGID=${PGID:?err} + - TZ=${TIMEZONE:?err} + - DOCKER_MODS=ghcr.io/gilbn/theme.park:radarr + - TP_THEME=${TP_THEME:?err} + networks: + - media-network + + readarr: + image: lscr.io/linuxserver/readarr:develop + container_name: readarr + restart: unless-stopped + volumes: + - ${FOLDER_FOR_CONFIGS:?err}/readarr:/config + - ${FOLDER_FOR_MEDIA:?err}:/data + - /ceph:/downloads + ports: + - "${WEBUI_PORT_READARR:?err}:8787" + environment: + - PUID=${PUID:?err} + - PGID=${PGID:?err} + - TZ=${TIMEZONE:?err} + - DOCKER_MODS=ghcr.io/gilbn/theme.park:readarr + - TP_THEME=${TP_THEME:?err} + networks: + - media-network + + requestrr: + environment: + - ${FOLDER_FOR_CONFIGS:?err}/requestrr:/config + ports: + - 4545:4545 + container_name: requestwqrr + image: darkalfx/requestrr + + sonarr: + image: lscr.io/linuxserver/sonarr:latest + container_name: sonarr + restart: unless-stopped + volumes: + - /ceph:/downloads + - ${FOLDER_FOR_CONFIGS:?err}/sonarr:/config + - ${FOLDER_FOR_MEDIA:?err}:/data + ports: + - "${WEBUI_PORT_SONARR:?err}:8989" + environment: + - PUID=${PUID:?err} + - PGID=${PGID:?err} + - TZ=${TIMEZONE:?err} + - DOCKER_MODS=ghcr.io/gilbn/theme.park:sonarr + - TP_THEME=${TP_THEME:?err} + networks: + - media-network + diff --git a/roles/ind/grail/grail-install.yml b/roles/ind/grail/grail-install.yml new file mode 100644 index 0000000..b50afc6 --- /dev/null +++ b/roles/ind/grail/grail-install.yml @@ -0,0 +1,104 @@ +--- +- hosts: all + become: yes + remote_user: ansible + gather_facts: false + + vars: + + tasks: + - name: Upgrade-packages.yml - update packages + include: ../../lib/upgrade-packages.yml + + - name: Install-docker.yml - setting up docker + include: ../../lib/install-docker.yml + + - name: Install Restic and setup + include: ../../lib/setup-restic.yml + + - name: Setup Restic Cron jobs + include: ../../lib/setup-restic-cron.yml + + - name: Create grail user + user: + name: grail + uid: 1000 + group: docker + state: present + create_home: yes + home: /data + shell: /bin/bash + + - name: Install Python Packages + apt: + name: + - python3-full + - python3-pip + state: present + update_cache: yes + + - name: Setup Service + copy: + dest: /etc/systemd/system/grail.service + content: | + [Unit] + Description=Docker Compose service + Requires=docker.service + After=docker.service + + [Service] + Type=oneshot + RemainAfterExit=yes + WorkingDirectory=/home/docker/grail + ExecStart=/usr/bin/docker-compose -f docker-compose.yml up -d + ExecStop=/usr/bin/docker-compose -f docker-compose.yml down + + [Install] + WantedBy=multi-user.target + owner: root + group: root + mode: '0644' + + - name: Write docker-compose.yml + ansible.builtin.copy: + src: docker-compose.yml + dest: /home/docker/docker-compose.yml + owner: docker + group: docker + mode: u=rw,g=r,o=r + + - name: Write docker-compose.env + ansible.builtin.copy: + src: docker-compose.env + dest: /home/docker/docker-compose.env + owner: docker + group: docker + mode: u=rw,g=r,o=r + + #- name: Start services + # community.docker.docker_compose_v2: + # project_src: /home/docker/ + # register: output + + - name: Check if docker config directory exists + stat: + path: /home/docker/qbittorrent + register: wikmd_stat + + - name: Restore docker config Dir + shell: | + restic --password-file ./.resticpassword -r sftp:misamisa://home/restic/$(hostname) --target / restore latest + args: + chdir: /home/docker + creates: /home/docker/qbitorrent + when: not wikmd_stat.stat.exists or not wikmd_stat.stat.isdir + + - name: Reload systemd daemon + systemd: + daemon_reload: yes + + - name: Start grail Service + systemd: + name: grail + state: started + enabled: yes \ No newline at end of file diff --git a/bookstack.tf b/wikmd.tf similarity index 97% rename from bookstack.tf rename to wikmd.tf index 2bdcec0..856f45e 100644 --- a/bookstack.tf +++ b/wikmd.tf @@ -1,6 +1,6 @@ resource "proxmox_lxc" "LXC" { target_node = "pve" - hostname = "bookstack" + hostname = "wikmd" vmid = 217 ostemplate = "local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst" password = "terraform"