Initial commit

This commit is contained in:
Javier Feliz 2025-03-20 19:59:48 -04:00
commit 54fa8e9a03
35 changed files with 1284 additions and 0 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"ansible.python.interpreterPath": "/bin/python3"
}

2
ansible.cfg Normal file
View File

@ -0,0 +1,2 @@
[defaults]
inventory = hosts.yml

View File

@ -0,0 +1,24 @@
<Config>
<BindAddress>*</BindAddress>
<Port>9696</Port>
<SslPort>6969</SslPort>
<EnableSsl>False</EnableSsl>
<LaunchBrowser>True</LaunchBrowser>
<ApiKey>prowlarr123</ApiKey>
<AuthenticationMethod>Forms</AuthenticationMethod>
<AuthenticationRequired>Enabled</AuthenticationRequired>
<Branch>develop</Branch>
<LogLevel>debug</LogLevel>
<SslCertPath></SslCertPath>
<SslCertPassword></SslCertPassword>
<UrlBase></UrlBase>
<InstanceName>Prowlarr</InstanceName>
<UpdateMechanism>Docker</UpdateMechanism>
<PostgresUser>arrstack</PostgresUser>
<PostgresPassword>password</PostgresPassword>
<PostgresPort>5432</PostgresPort>
<PostgresHost>10.89.0.102</PostgresHost>
<PostgresMainDb>arrstack_prowlarr_main</PostgresMainDb>
<PostgresLogDb>arrstack_prowlarr_log</PostgresLogDb>
</Config>

View File

@ -0,0 +1,59 @@
[Application]
FileLogger\Age=1
FileLogger\AgeType=1
FileLogger\Backup=true
FileLogger\DeleteOld=true
FileLogger\Enabled=true
FileLogger\MaxSizeBytes=66560
FileLogger\Path=/config/qBittorrent/logs
[AutoRun]
enabled=false
program=
[BitTorrent]
Session\AddTorrentStopped=false
Session\DefaultSavePath=/data/torrents
Session\ExcludedFileNames=
Session\Port=6881
Session\QueueingSystemEnabled=true
Session\SSL\Port=47017
Session\ShareLimitAction=Stop
Session\TempPath=/data/torrents/incomplete
Session\TempPathEnabled=true
[Core]
AutoDeleteAddedTorrentFile=Never
[LegalNotice]
Accepted=true
[Meta]
MigrationVersion=8
[Network]
Cookies=@Invalid()
PortForwardingEnabled=false
Proxy\HostnameLookupEnabled=false
Proxy\Profiles\BitTorrent=true
Proxy\Profiles\Misc=true
Proxy\Profiles\RSS=true
[Preferences]
Connection\PortRangeMin=6881
Connection\UPnP=false
Downloads\SavePath=/downloads/
Downloads\TempPath=/downloads/incomplete/
General\Locale=en
MailNotification\req_auth=true
WebUI\Address=*
WebUI\AlternativeUIEnabled=true
WebUI\AuthSubnetWhitelist=@Invalid()
WebUI\Password_PBKDF2="@ByteArray(4s/z5haZUWwVroTF8nQ3sg==:gmUsUm24faCVh9K3r41OIaz5XHGRBReP0dBnu2Iu6+j77N39SG4wR/C6VDPYDr5PW+vlQzwNKTy6+XGsr8xO9A==)"
WebUI\Port=5007
WebUI\RootFolder=/themepark
WebUI\ServerDomains=*
[RSS]
AutoDownloader\DownloadRepacks=true
AutoDownloader\SmartEpisodeFilter=s(\\d+)e(\\d+), (\\d+)x(\\d+), "(\\d{4}[.\\-]\\d{1,2}[.\\-]\\d{1,2})", "(\\d{1,2}[.\\-]\\d{1,2}[.\\-]\\d{4})"

View File

@ -0,0 +1,24 @@
<Config>
<BindAddress>*</BindAddress>
<Port>7878</Port>
<SslPort>8787</SslPort>
<EnableSsl>False</EnableSsl>
<LaunchBrowser>True</LaunchBrowser>
<ApiKey>radarr123</ApiKey>
<AuthenticationMethod>External</AuthenticationMethod>
<AuthenticationRequired>Enabled</AuthenticationRequired>
<Branch>main</Branch>
<LogLevel>debug</LogLevel>
<SslCertPath></SslCertPath>
<SslCertPassword></SslCertPassword>
<UrlBase></UrlBase>
<InstanceName>Radarr</InstanceName>
<UpdateMechanism>Docker</UpdateMechanism>
<PostgresUser>arrstack</PostgresUser>
<PostgresPassword>password</PostgresPassword>
<PostgresPort>5432</PostgresPort>
<PostgresHost>10.89.0.102</PostgresHost>
<PostgresMainDb>arrstack_radarr_main</PostgresMainDb>
<PostgresLogDb>arrstack_radarr_log</PostgresLogDb>
</Config>

View File

@ -0,0 +1,25 @@
<Config>
<BindAddress>*</BindAddress>
<Port>8787</Port>
<SslPort>7854</SslPort>
<EnableSsl>False</EnableSsl>
<LaunchBrowser>True</LaunchBrowser>
<ApiKey>readarr123</ApiKey>
<AuthenticationMethod>External</AuthenticationMethod>
<AuthenticationRequired>Enabled</AuthenticationRequired>
<Branch>main</Branch>
<LogLevel>debug</LogLevel>
<SslCertPath></SslCertPath>
<SslCertPassword></SslCertPassword>
<UrlBase></UrlBase>
<InstanceName>Readarr</InstanceName>
<UpdateMechanism>Docker</UpdateMechanism>
<PostgresUser>arrstack</PostgresUser>
<PostgresPassword>password</PostgresPassword>
<PostgresPort>5432</PostgresPort>
<PostgresHost>10.89.0.102</PostgresHost>
<PostgresMainDb>arrstack_readarr_main</PostgresMainDb>
<PostgresLogDb>arrstack_readarr_log</PostgresLogDb>
<PostgresCacheDb>arrstack_readarr_cache</PostgresCacheDb>
</Config>

View File

@ -0,0 +1,24 @@
<Config>
<BindAddress>*</BindAddress>
<Port>8989</Port>
<SslPort>9898</SslPort>
<EnableSsl>False</EnableSsl>
<LaunchBrowser>True</LaunchBrowser>
<ApiKey>sonarr123</ApiKey>
<AuthenticationMethod>Forms</AuthenticationMethod>
<AuthenticationRequired>Enabled</AuthenticationRequired>
<Branch>main</Branch>
<LogLevel>debug</LogLevel>
<SslCertPath></SslCertPath>
<SslCertPassword></SslCertPassword>
<UrlBase></UrlBase>
<InstanceName>Sonarr</InstanceName>
<UpdateMechanism>Docker</UpdateMechanism>
<PostgresUser>arrstack</PostgresUser>
<PostgresPassword>password</PostgresPassword>
<PostgresPort>5432</PostgresPort>
<PostgresHost>10.89.0.102</PostgresHost>
<PostgresMainDb>arrstack_sonarr_main</PostgresMainDb>
<PostgresLogDb>arrstack_sonarr_log</PostgresLogDb>
</Config>

View File

@ -0,0 +1,17 @@
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl -y
sudo install -y -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" |
sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
sudo docker run hello-world

0
databases.yml Normal file
View File

2
deps.sh Executable file
View File

@ -0,0 +1,2 @@
sudo apt install python3-psycopg2
sudo apt install sshpass

96
docker/arrstack/.env Normal file
View File

@ -0,0 +1,96 @@
#################################################################################
#################################################################################
#################################################################################
##
## Docker Compose Environment Variable file for Jellyfin / *ARR 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.
##
## The MediaStack Guide is located at https://MediaStack.Guide
##
#################################################################################
#################################################################################
#################################################################################
# Name of the project in Docker
COMPOSE_PROJECT_NAME=arrstack
# 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.
LOCAL_SUBNET=10.89.0.0/24 # This is the IP Subnet used on your home network
LOCAL_DOCKER_IP=10.89.0.107
# 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_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.
# Make sure these folders exists before running the "docker compose" command.
FOLDER_FOR_MEDIA=/home/docker/media
FOLDER_FOR_DATA=/home/docker/arrstack
# 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/New_York
# Update your own Internet VPN provide details below
# Online documentation: https://github.com/qdm12/gluetun-wiki/tree/main/setup/providers
VPN_TYPE=openvpn
VPN_SERVICE_PROVIDER=protonvpn
VPN_USERNAME=RKACGjQuepNsr84Y
VPN_PASSWORD=kYWSKvCzkefrsnUuZ8Ig7YkTPSO4KSVN
# You MUST provide at least one entry to the SERVER variables below, that supports your VPN provider's settings.
# If you want to add more than one entry per line, use comma separated values: "one,two,three" etc...
SERVER_COUNTRIES="United States"
SERVER_REGIONS=
SERVER_CITIES=
SERVER_HOSTNAMES=
SERVER_CATEGORIES=
# 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_DATA location for gluetun.
OPENVPN_CUSTOM_CONFIG=
GLUETUN_CONTROL_PORT=8320
# 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=6881
FLARESOLVERR_PORT=8191
TDARR_SERVER_PORT=8266
WEBUI_PORT_PROWLARR=5001
WEBUI_PORT_SONARR=5002
WEBUI_PORT_RADARR=5003
WEBUI_PORT_WHISPARR=5005
WEBUI_PORT_READARR=5006
WEBUI_PORT_QBITTORRENT=5007
WEBUI_PORT_LIDARR=5008
WEBUI_PORT_MYLAR=5009
WEBUI_PORT_FILEBOT=5010
WEBUI_PORT_JELLYSEERR=5011
WEBUI_PORT_TDARR=5012
WEBUI_PORT_SABNZBD=5013

View File

@ -0,0 +1,385 @@
# TODO: Fix path mappings in containers since it's currently /data/data and /media/media
## Function: VPN Client
## Documentation: https://github.com/qdm12/gluetun-wiki
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
- "${WEBUI_PORT_QBITTORRENT:?err}:${WEBUI_PORT_QBITTORRENT:?err}" # WebUI Portal: qBittorrent
- "${QBIT_PORT:?err}:6881" # Transmission Torrent Port
volumes:
- ${FOLDER_FOR_DATA:?err}/gluetun:/gluetun
environment:
- PUID=${PUID:?err}
- PGID=${PGID:?err}
- UMASK=${UMASK:?err}
- TZ=${TIMEZONE:?err}
- VPN_SERVICE_PROVIDER=${VPN_SERVICE_PROVIDER:?err}
- OPENVPN_USER=${VPN_USERNAME:?err}
- OPENVPN_PASSWORD=${VPN_PASSWORD:?err}
- SERVER_COUNTRIES=${SERVER_COUNTRIES}
- SERVER_REGIONS=${SERVER_REGIONS}
- SERVER_CITIES=${SERVER_CITIES}
- SERVER_HOSTNAMES=${SERVER_HOSTNAMES}
- SERVER_CATEGORIES=${SERVER_CATEGORIES}
- FIREWALL_OUTBOUND_SUBNETS=${LOCAL_SUBNET:?err}
- OPENVPN_CUSTOM_CONFIG=${OPENVPN_CUSTOM_CONFIG}
- HTTP_CONTROL_SERVER_ADDRESS=:${GLUETUN_CONTROL_PORT:?err}
- 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
## Function: Cloudflare Proxy Server
## Documentation: https://github.com/FlareSolverr/FlareSolverr
##########################################################################
flaresolverr:
image: ghcr.io/flaresolverr/flaresolverr:latest
container_name: flaresolverr
restart: unless-stopped
ports:
- "${FLARESOLVERR_PORT:?err}:8191"
environment:
- LOG_LEVEL=info
- LOG_HTML=false
- CAPTCHA_SOLVER=none
- TZ=${TIMEZONE:?err}
## Function: Indexer and Search Manager
## Documentation: https://docs.linuxserver.io/images/docker-prowlarr
prowlarr:
image: lscr.io/linuxserver/prowlarr:develop
container_name: prowlarr
restart: unless-stopped
volumes:
- /home/docker/prowlarr:/config
ports:
- "${WEBUI_PORT_PROWLARR:?err}:9696"
environment:
- PUID=${PUID:?err}
- PGID=${PGID:?err}
- TZ=${TIMEZONE:?err}
- DOCKER_MODS=ghcr.io/themepark-dev/theme.park:prowlarr
- TP_THEME=${TP_THEME:?err}
## Function: Torrent Download Client
## Documentation: https://docs.linuxserver.io/images/docker-qbittorrent
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
container_name: qbittorrent
restart: unless-stopped
volumes:
- /home/docker/qbittorrent:/config
- /home/docker/media/torrents:/data/torrents
environment:
- PUID=${PUID:?err}
- PGID=${PGID:?err}
- UMASK=${UMASK:?err}
- TZ=${TIMEZONE:?err}
- WEBUI_PORT=${WEBUI_PORT_QBITTORRENT:?err}
- DOCKER_MODS=ghcr.io/themepark-dev/theme.park:qbittorrent
- TP_THEME=${TP_THEME:?err}
network_mode: "service:gluetun"
## Function: Series Library Manager (TV Shows)
## Documentation: https://docs.linuxserver.io/images/docker-sonarr
sonarr:
image: lscr.io/linuxserver/sonarr:latest
container_name: sonarr
restart: unless-stopped
volumes:
- /home/docker/sonarr:/config
- /home/docker/media:/data
ports:
- "${WEBUI_PORT_SONARR:?err}:8989"
environment:
- PUID=${PUID:?err}
- PGID=${PGID:?err}
- TZ=${TIMEZONE:?err}
- DOCKER_MODS=ghcr.io/themepark-dev/theme.park:sonarr
- TP_THEME=${TP_THEME:?err}
## Function: Movie Library Manager
## Documentation: https://docs.linuxserver.io/images/docker-radarr
radarr:
image: lscr.io/linuxserver/radarr:latest
container_name: radarr
restart: unless-stopped
volumes:
- /home/docker/radarr:/config
- /home/docker/media:/data
ports:
- "${WEBUI_PORT_RADARR:?err}:7878"
environment:
- PUID=${PUID:?err}
- PGID=${PGID:?err}
- TZ=${TIMEZONE:?err}
- DOCKER_MODS=ghcr.io/themepark-dev/theme.park:radarr
- TP_THEME=${TP_THEME:?err}
## Function: Usenet Download Client
## Documentation: https://docs.linuxserver.io/images/docker-sabnzbd
sabnzbd:
image: lscr.io/linuxserver/sabnzbd:latest
container_name: sabnzbd
restart: unless-stopped
volumes:
- /home/docker/sabnzbd:/config
- /home/docker/media/usenet:/data/usenet
ports:
- "${WEBUI_PORT_SABNZBD:?err}:8080"
environment:
- PUID=${PUID:?err}
- PGID=${PGID:?err}
- TZ=${TIMEZONE:?err}
- DOCKER_MODS=ghcr.io/themepark-dev/theme.park:sabnzbd
- TP_THEME=${TP_THEME:?err}
## Function: Book Library Manager
## Documentation: https://docs.linuxserver.io/images/docker-readarr
readarr:
image: lscr.io/linuxserver/readarr:develop
container_name: readarr
restart: unless-stopped
volumes:
- /home/docker/readarr:/config
- /home/docker/media:/data
ports:
- "${WEBUI_PORT_READARR:?err}:8787"
environment:
- PUID=${PUID:?err}
- PGID=${PGID:?err}
- TZ=${TIMEZONE:?err}
- DOCKER_MODS=ghcr.io/themepark-dev/theme.park:readarr
- TP_THEME=${TP_THEME:?err}
## Function: Lookup and Rename Media from Internet Databases
## Docker Page: https://github.com/filebot/filebot-docker#filebot-xpra
## Homepage: https://www.filebot.net/
## User Forum: https://www.filebot.net/forums
# filebot:
# image: rednoah/filebot:xpra
# container_name: filebot
# restart: unless-stopped
# ports:
# - "${WEBUI_PORT_FILEBOT:?err}:5454"
# volumes:
# - ${FOLDER_FOR_DATA:?err}/filebot:/data/filebot
# - ${FOLDER_FOR_MEDIA:?err}/filebot:/filebot
# environment:
# # - XPRA_AUTH=password:value=YOUR_PASSWORD
# - PUID=${PUID:?err}
# - PGID=${PGID:?err}
# - UMASK=${UMASK:?err}
# - TZ=${TIMEZONE:?err}
# - DARK_MODE=1
## Function: Media Request Manager
## Documentation: https://hub.docker.com/r/fallenbagel/jellyseerr
# jellyseerr:
# image: fallenbagel/jellyseerr:latest
# container_name: jellyseerr
# restart: unless-stopped
# volumes:
# - ${FOLDER_FOR_DATA:?err}/jellyseerr:/app/config
# ports:
# - "${WEBUI_PORT_JELLYSEERR:?err}:5055"
# environment:
# - PUID=${PUID:?err}
# - PGID=${PGID:?err}
# - UMASK=${UMASK:?err}
# - TZ=${TIMEZONE:?err}
## Function: Music Library Manager
## Documentation: https://docs.linuxserver.io/images/docker-lidarr
# lidarr:
# image: lscr.io/linuxserver/lidarr:latest
# container_name: lidarr
# restart: unless-stopped
# volumes:
# - ${FOLDER_FOR_DATA:?err}/lidarr:/config
# - ${FOLDER_FOR_MEDIA:?err}:/data
# ports:
# - "${WEBUI_PORT_LIDARR:?err}:8686"
# environment:
# - PUID=${PUID:?err}
# - PGID=${PGID:?err}
# - TZ=${TIMEZONE:?err}
# - DOCKER_MODS=ghcr.io/themepark-dev/theme.park:lidarr
# - TP_THEME=${TP_THEME:?err}
## Function: Comic Library Manager
## Documentation: https://github.com/mylar3/mylar3/wiki
# mylar:
# image: lscr.io/linuxserver/mylar3:latest
# container_name: mylar
# restart: unless-stopped
# volumes:
# - ${FOLDER_FOR_DATA:?err}/mylar:/config
# - ${FOLDER_FOR_MEDIA:?err}:/data
# ports:
# - "${WEBUI_PORT_MYLAR:?err}:8090"
# environment:
# - PUID=${PUID:?err}
# - PGID=${PGID:?err}
# - TZ=${TIMEZONE:?err}
# - DOCKER_MODS=ghcr.io/themepark-dev/theme.park:mylar3
# - TP_THEME=${TP_THEME:?err}
## Function: Tdarr V2 - Audio/Video library transcoding automation (Contains Tdarr_Server and WebUI )
## Documentation: https://docs.tdarr.io/docs/installation/docker/run-compose/
## https://docs.tdarr.io/docs/installation/docker/hardware-transcoding
# tdarr:
# image: ghcr.io/haveagitgat/tdarr:latest
# container_name: tdarr
# restart: unless-stopped
# volumes:
# - ${FOLDER_FOR_DATA:?err}/tdarr/server:/app/server
# - ${FOLDER_FOR_DATA:?err}/tdarr/configs:/app/configs
# - ${FOLDER_FOR_DATA:?err}/tdarr/logs:/app/logs
# - ${FOLDER_FOR_DATA:?err}/tdarr_transcode_cache:/temp
# - ${FOLDER_FOR_MEDIA:?err}/media:/data
# ports:
# - "${TDARR_SERVER_PORT:?err}:${TDARR_SERVER_PORT:?err}"
# - "${WEBUI_PORT_TDARR:?err}:${WEBUI_PORT_TDARR:?err}"
# environment:
# - PUID=${PUID:?err}
# - PGID=${PGID:?err}
# - UMASK=${UMASK:?err}
# - TZ=${TIMEZONE:?err}
# - serverIP=0.0.0.0
# - serverPort=${TDARR_SERVER_PORT:?err}
# - webUIPort=${WEBUI_PORT_TDARR:?err}
# - internalNode=true
# - nodeID=Tdarr_Server
# tdarr-node:
# image: ghcr.io/haveagitgat/tdarr_node:latest
# container_name: tdarr-node
# restart: unless-stopped
# volumes:
# - ${FOLDER_FOR_DATA:?err}/tdarr/configs:/app/configs
# - ${FOLDER_FOR_DATA:?err}/tdarr/logs:/app/logs
# - ${FOLDER_FOR_DATA:?err}/tdarr_transcode_cache:/temp
# - ${FOLDER_FOR_MEDIA:?err}/media:/data
# environment:
# - PUID=${PUID:?err}
# - PGID=${PGID:?err}
# - UMASK=${UMASK:?err}
# - TZ=${TIMEZONE:?err}
# - nodeID=Tdarr_Node_1
# - serverIP=0.0.0.0
# - serverPort=${TDARR_SERVER_PORT:?err}
# ## Function: Archive Media Extraction
# ## Documentation: https://github.com/davidnewhall/unpackerr
# ## https://github.com/davidnewhall/unpackerr/blob/master/examples/docker-compose.yml
# unpackerr:
# image: ghcr.io/hotio/unpackerr:latest
# container_name: unpackerr
# restart: unless-stopped
# volumes:
# - ${FOLDER_FOR_DATA:?err}/unpackerr:/config
# - ${FOLDER_FOR_MEDIA:?err}:/data
# environment:
# - PUID=${PUID:?err}
# - PGID=${PGID:?err}
# - UMASK=${UMASK:?err}
# - TZ=${TIMEZONE:?err}
# # Documentation on all Environment Variables can be found at:
# # https://github.com/davidnewhall/unpackerr#docker-env-variables
# - UN_DEBUG=false
# - UN_LOG_FILE=
# - UN_LOG_FILES=10
# - UN_LOG_FILE_MB=10
# - UN_INTERVAL=2m
# - UN_START_DELAY=1m
# - UN_RETRY_DELAY=5m
# - UN_MAX_RETRIES=3
# - UN_PARALLEL=1
# - UN_FILE_MODE=0664
# - UN_DIR_MODE=0775
# # Sonarr Config - Copy API Key from: http://sonarr:8989/general/settings
# - UN_SONARR_0_URL=http://sonarr:8989
# - UN_SONARR_0_API_KEY=
# - UN_SONARR_0_PATHS_0=/data/torrents/anime
# - UN_SONARR_0_PATHS_1=/data/torrents/tv
# - UN_SONARR_0_PROTOCOLS=torrent
# - UN_SONARR_0_TIMEOUT=10s
# - UN_SONARR_0_DELETE_ORIG=false
# - UN_SONARR_0_DELETE_DELAY=5m
# # Radarr Config - Copy API Key from: http://radarr:7878/general/settings
# - UN_RADARR_0_URL=http://radarr:7878
# - UN_RADARR_0_API_KEY=
# - UN_RADARR_0_PATHS_0=/data/torrents/movies
# - UN_RADARR_0_PROTOCOLS=torrent
# - UN_RADARR_0_TIMEOUT=10s
# - UN_RADARR_0_DELETE_ORIG=false
# - UN_RADARR_0_DELETE_DELAY=5m
# # Lidarr Config - Copy API Key from: http://lidarr:8686/general/settings
# - UN_LIDARR_0_URL=http://lidarr:8686
# - UN_LIDARR_0_API_KEY=
# - UN_LIDARR_0_PATHS_0=/data/torrents/music
# - UN_LIDARR_0_PROTOCOLS=torrent
# - UN_LIDARR_0_TIMEOUT=10s
# - UN_LIDARR_0_DELETE_ORIG=false
# - UN_LIDARR_0_DELETE_DELAY=5m
# # Readarr Config - Copy API Key from: http://readarr:8787/general/settings
# - UN_READARR_0_URL=http://readarr:8787
# - UN_READARR_0_API_KEY=
# - UN_READARR_0_PATHS_0=/data/torrents/books
# - UN_READARR_0_PROTOCOLS=torrent
# - UN_READARR_0_TIMEOUT=10s
# - UN_READARR_0_DELETE_ORIG=false
# - UN_READARR_0_DELETE_DELAY=5m
# # Folder Config
# - UN_FOLDER_0_PATH=
# - UN_FOLDER_0_EXTRACT_PATH=
# - UN_FOLDER_0_DELETE_AFTER=10m
# - UN_FOLDER_0_DELETE_ORIGINAL=false
# - UN_FOLDER_0_DELETE_FILES=false
# - UN_FOLDER_0_MOVE_BACK=false
# # Webhook Config
# - UN_WEBHOOK_0_URL=
# - UN_WEBHOOK_0_NAME=
# - UN_WEBHOOK_0_NICKNAME=Unpackerr
# - UN_WEBHOOK_0_CHANNEL=
# - UN_WEBHOOK_0_TIMEOUT=10s
# - UN_WEBHOOK_0_SILENT=false
# - UN_WEBHOOK_0_IGNORE_SSL=false
# - UN_WEBHOOK_0_EXCLUDE_0=
# - UN_WEBHOOK_0_EVENTS_0=0
# - UN_WEBHOOK_0_TEMPLATE_PATH=
# - UN_WEBHOOK_0_CONTENT_TYPE=application/json
# # Command Hook Config
# - UN_CMDHOOK_0_COMMAND=
# - UN_CMDHOOK_0_NAME=
# - UN_CMDHOOK_0_TIMEOUT=10s
# - UN_CMDHOOK_0_SILENT=false
# - UN_CMDHOOK_0_SHELL=false
# - UN_CMDHOOK_0_EXCLUDE_0=
# - UN_CMDHOOK_0_EVENTS_0=0
# security_opt:
# - no-new-privileges:true
# network_mode: none

View File

@ -0,0 +1,30 @@
---
services:
jellyfin:
image: jellyfin/jellyfin
container_name: jellyfin
ports:
- "5001:8096"
devices:
- /dev/dri:/dev/dri
volumes:
- /home/docker/jellyfin:/config
- /home/docker/jellyfin/cache:/cache
- type: bind
source: /home/docker/media
target: /media
restart: 'unless-stopped'
environment:
- JELLYFIN_PublishedServerUrl=https://watch.blinker.club
jellyseerr:
image: fallenbagel/jellyseerr
restart: unless-stopped
volumes:
- '/home/docker/jellyseer:/app/config'
ports:
- '5002:5055'
environment:
- PORT=5055
- TZ=America/New_York
- LOG_LEVEL=debug
container_name: jellyseerr

View File

@ -0,0 +1,34 @@
---
services:
stash:
image: stashapp/stash:latest
container_name: stash
restart: unless-stopped
ports:
- "6969:9999"
logging:
driver: "json-file"
options:
max-file: "10"
max-size: "2m"
environment:
- STASH_STASH=/data/
- STASH_GENERATED=/generated/
- STASH_METADATA=/metadata/
- STASH_CACHE=/cache/
- STASH_PORT=9999
- STASH_DOCKER_FOLDER=/home/docker/stash
volumes:
- /etc/localtime:/etc/localtime:ro
## Keep configs, scrapers, and plugins here.
- ${STASH_DOCKER_FOLDER}/config:/root/.stash
## Point this at your collection.
- /home/docker/xrandr:/data
## This is where your stash's metadata lives
- ${STASH_DOCKER_FOLDER}/metadata:/metadata
## Any other cache content
- ${STASH_DOCKER_FOLDER}/cache:/cache
## Where to store binary blob data (scene covers, images)
- ${STASH_DOCKER_FOLDER}/blobs:/blobs
## Where to store generated content (screenshots,previews,transcodes,sprites)
- ${STASH_DOCKER_FOLDER}/generated:/generated

View File

@ -0,0 +1,36 @@
---
name: wizarr
services:
wizarr-server:
container_name: wizarr_server
image: ghcr.io/wizarrrrr/wizarr:${WIZARR_IMAGE_VERSION:-release}
volumes:
- /home/docker/wizarr:/usr/wizarr/data/storage
- /etc/localtime:/etc/localtime:ro
environment:
- DATABASE_TYPE=postgres
- DB_USERNAME=wizarr
- DB_PASSWORD=password
- DB_HOST=10.89.0.102
- DB_DATABASE_NAME=wizarr
- WIZARR_IMAGE_VERSION=release
- REDIS_HOST=redis
- REDIS_PORT=6379
- TZ=America/New_York
ports:
- "5003:5690"
depends_on:
- redis
restart: always
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5690/api/health"]
interval: 30s
timeout: 10s
retries: 5
redis:
container_name: wizarr_redis
image: docker.io/redis:6.2-alpine@sha256:eaba718fecd1196d88533de7ba49bf903ad33664a92debb24660a922ecd9cac8
healthcheck:
test: redis-cli ping || exit 1
restart: unless-stopped

1
group_vars/all.yml Normal file
View File

@ -0,0 +1 @@
ansible_become_pass: Cinnamonbun89$

27
hosts.yml Normal file
View File

@ -0,0 +1,27 @@
---
all:
children:
servers:
hosts:
node1:
ansible_host: 10.89.0.13
node2:
ansible_host: 10.89.0.11
node3:
ansible_host: 10.89.0.12
virtual_machines:
hosts:
portainer_main:
ansible_host: 10.89.0.101
prod_services:
ansible_host: 11.89.0.102
stash:
ansible_host: 10.89.0.103
plane_so:
ansible_host: 10.89.0.104
dev_services:
ansible_host: 10.89.0.105
streaming_services:
ansible_host: 10.89.0.106
streaming:
ansible_host: 10.89.0.107

1
makerole.sh Executable file
View File

@ -0,0 +1 @@
ROLE="$1"

108
playbooks/arrstack.yml Normal file
View File

@ -0,0 +1,108 @@
---
- name: Set up the arrstack
hosts: streaming
vars:
apps:
- sonarr
configs:
- src: '../assets/arrstack/sonarr/config.xml'
dest: '/home/docker/sonarr/config.xml'
- src: '../assets/arrstack/prowlarr/config.xml'
dest: '/home/docker/prowlarr/config.xml'
- src: '../assets/arrstack/radarr/config.xml'
dest: '/home/docker/radarr/config.xml'
- src: '../assets/arrstack/readarr/config.xml'
dest: '/home/docker/readarr/config.xml'
- src: '../assets/arrstack/qbittorrent/qBittorrent.conf'
dest: '/home/docker/qbittorrent/qBittorrent.conf'
dbs:
- arrstack_sonarr_main
- arrstack_sonarr_log
- arrstack_radarr_main
- arrstack_radarr_log
- arrstack_prowlarr_main
- arrstack_prowlarr_log
- arrstack_readarr_main
- arrstack_readarr_log
- arrstack_readarr_cache
tasks:
- name: Mount the media share to the VM
ansible.builtin.include_tasks:
file: ../tasks/mount_nfs.yml
vars:
mount_path: "/home/docker/media"
mount_source: "10.89.0.15:/mnt/main/media"
- name: Create arrstack user on postgres
ansible.builtin.include_tasks:
file: '../tasks/postgres/create_user.yml'
vars:
user: arrstack
password: password
- name: Create app databases on postgres
ansible.builtin.include_tasks:
file: '../tasks/postgres/create_database.yml'
vars:
database: "{{ item }}"
loop: "{{ dbs }}"
- name: Give the arrstack user full privs on the databases
ansible.builtin.include_tasks:
file: '../tasks/postgres/give_user_full_privs.yml'
vars:
user: arrstack
database: "{{ item }}"
loop: "{{ dbs }}"
- name: Ensure config directories exist
ansible.builtin.file:
path: "{{ item.dest | dirname }}"
state: directory
mode: '0777'
become: true
loop: "{{ configs }}"
- name: Copy configuration files
ansible.builtin.copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
owner: javi
group: javi
mode: '0777'
loop: "{{ configs }}"
- name: Ensure docker compose folder exists
ansible.builtin.file:
path: /home/javi/docker/arrstack
state: directory
mode: '0777'
become: true
- name: Copy docker-compose.yml to server
ansible.builtin.copy:
src: '../docker/arrstack/docker-compose.yml'
dest: '/home/javi/docker/arrstack/docker-compose.yml'
owner: javi
group: javi
mode: '0777'
- name: Copy docker .env to server
ansible.builtin.copy:
src: '../docker/arrstack/.env'
dest: '/home/javi/docker/arrstack/.env'
owner: javi
group: javi
mode: '0777'
- name: Start up the containers
ansible.builtin.command: docker compose up -d
args:
chdir: /home/javi/docker/arrstack
become: true
# - name: Restart just in case
# ansible.builtin.command: docker compose restart
# args:
# chdir: /home/javi/docker/arrstack
# become: true

30
playbooks/databases.yml Normal file
View File

@ -0,0 +1,30 @@
# Also create users
# Assign a user all priviledges on it's databases
---
- name: Ensure databases exist
hosts: localhost
connection: local
vars_files:
- ../../vars/pg_main.yml
vars:
dbs:
- arrstack_sonarr_main
- arrstack_sonarr_log
- arrstack_radarr_main
- arrstack_radarr_log
- arrstack_readarr_main
- arrstack_readarr_log
- arrstack_lidarr_main
- arrstack_lidarr_log
- arrstack_prowlarr_main
- arrstack_prowlarr_log
- planeso
- readeck
- spacebin
- linkwarden
- opengist
tasks:
- include_tasks: "../tasks/create_db.yml"
vars:
name: "{{ item }}"
loop: "{{ dbs }}"

View File

@ -0,0 +1,10 @@
---
- name: Distribute SSH public key to my hosts
hosts: all
become: true
tasks:
- name: Add SSH key for remote user
ansible.posix.authorized_key:
user: javi
state: present
key: "{{ lookup('file', '/home/javi/.ssh/homelab_keypair_ed25519.pub') }}"

28
playbooks/ftp.yml Normal file
View File

@ -0,0 +1,28 @@
---
- name: Setup FTP server on Ubuntu
hosts: all
become: true
tasks:
- name: Update apt cache
ansible.builtin.apt:
update_cache: true
- name: Install proftpd package
ansible.builtin.apt:
name: proftpd
state: present
- name: Ensure proftpd is enabled and started
ansible.builtin.service:
name: proftpd
state: started
enabled: true
become: true
- name: Allow FTP through UFW firewall (if UFW is enabled)
ansible.builtin.ufw:
rule: allow
port: 21
proto: tcp
ignore_errors: false

View File

@ -0,0 +1,20 @@
---
- name: Set up a new virtual machine
hosts: all
become: true
tasks:
- name: Install Docker
ansible.builtin.include_tasks:
file: '../tasks/provisioning/install_docker.yml'
- name: Pull and run the portainer agent
community.docker.docker_container:
name: portainer_agent
image: portainer/agent:2.27.0
state: started
restart_policy: always
published_ports:
- "9001:9001"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/volumes:/var/lib/docker/volumes
- /:/host

42
playbooks/jellyfin.yml Normal file
View File

@ -0,0 +1,42 @@
---
- name: Set up jellyfin
hosts: streaming_services
become: true
tasks:
- name: Mount the media share to the VM
ansible.builtin.include_tasks:
file: ../tasks/mount_nfs.yml
vars:
mount_path: "/home/docker/media"
mount_source: "10.89.0.15:/mnt/main/media"
- name: Create app mount directory
ansible.builtin.file:
path: /home/docker/jellyfin
state: directory
mode: '0777'
- name: Ensure jellyfin docker compose folder exists
ansible.builtin.file:
path: /home/javi/docker/jellyfin
state: directory
mode: '0777'
- name: Ensure jellyseer docker compose folder exists
ansible.builtin.file:
path: /home/javi/docker/jellyseer
state: directory
mode: '0777'
- name: Copy docker-compose.yml to server
ansible.builtin.copy:
src: '../docker/jellyfin/docker-compose.yml'
dest: '/home/javi/docker/jellyfin/docker-compose.yml'
owner: javi
group: javi
mode: '0777'
- name: Start up the containers
ansible.builtin.command: docker compose up -d
args:
chdir: /home/javi/docker/jellyfin

View File

@ -0,0 +1,16 @@
---
- name: Create standardized admin on all hosts
hosts: virtual_machines
become: true
vars:
username: serveradmin
password: "Cinnamonbun89$"
tasks:
- name: Create the standard user on the host
ansible.builtin.user:
name: "{{ username }}"
state: present
shell: /bin/bash
create_home: true
groups: sudo
append: true

44
playbooks/webmin.yml Normal file
View File

@ -0,0 +1,44 @@
---
- name: Install Webmin on Debian/Ubuntu
hosts: all
become: true
tasks:
- name: Install required dependencies
ansible.builtin.apt:
name:
- wget
- apt-transport-https
- software-properties-common
state: present
update_cache: true
- name: Add Webmin repository
ansible.builtin.copy:
dest: /etc/apt/sources.list.d/webmin.list
content: "deb http://download.webmin.com/download/repository sarge contrib"
owner: javi
group: javi
mode: '0777'
- name: Add Webmin GPG key
ansible.builtin.apt_key:
url: https://www.webmin.com/jcameron-key.asc
state: present
- name: Update apt cache
ansible.builtin.apt:
update_cache: true
- name: Install Webmin with recommended packages
ansible.builtin.apt:
name:
- webmin
state: present
update_cache: true
install_recommends: true
- name: Ensure Webmin service is enabled and running
systemd:
name: webmin
enabled: true
state: started

39
playbooks/wizarr.yml Normal file
View File

@ -0,0 +1,39 @@
---
- name: Set up wizarr
hosts: streaming_services
become: true
tasks:
- name: Create app DB
ansible.builtin.include_tasks:
file: '../tasks/create_app_db.yml'
vars:
app: wizarr
- name: Make sure UUID PG extension is installed
ansible.builtin.include_tasks:
file: '../tasks/postgres/install_extension.yml'
vars:
extension: uuid-ossp
database: wizarr
- name: Ensure config directories exist
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: '0777'
loop:
- '/home/docker/wizarr'
- '/home/javi/docker/wizarr'
- name: Copy docker-compose.yml to server
ansible.builtin.copy:
src: '../docker/wizarr/docker-compose.yml'
dest: '/home/javi/docker/wizarr/docker-compose.yml'
owner: javi
group: javi
mode: '0777'
- name: Start up the containers
ansible.builtin.command: docker compose up -d
args:
chdir: /home/javi/docker/wizarr

20
tasks/create_app_db.yml Normal file
View File

@ -0,0 +1,20 @@
---
- name: Create db user
ansible.builtin.include_tasks:
file: './postgres/create_user.yml'
vars:
user: "{{ app }}"
password: "password"
- name: Create database
ansible.builtin.include_tasks:
file: './postgres/create_database.yml'
vars:
database: "{{ app }}"
- name: Give user permissions on database
ansible.builtin.include_tasks:
file: './postgres/give_user_full_privs.yml'
vars:
database: "{{ app }}"
user: "{{ app }}"

21
tasks/mount_nfs.yml Normal file
View File

@ -0,0 +1,21 @@
---
- name: Ensure NFS client is installed
ansible.builtin.package:
name: nfs-common
state: present
become: true
- name: Create mount point directory
ansible.builtin.file:
path: "{{ mount_path }}"
state: directory
mode: '0777'
become: true
- name: Mount share
ansible.posix.mount:
src: "{{ mount_source }}"
path: "{{ mount_path }}"
fstype: nfs
state: mounted
become: true

View File

@ -0,0 +1,13 @@
---
- name: Load connection variables
include_vars: "../vars/pg_main.yml"
- name: Create database
delegate_to: localhost
community.postgresql.postgresql_db:
name: "{{ database }}"
state: present
login_host: "{{ db_host }}"
login_port: "{{ db_port }}"
login_user: "{{ db_user }}"
login_password: "{{ db_password }}"

View File

@ -0,0 +1,14 @@
---
- name: Include connection variables
ansible.builtin.include_vars: "../vars/pg_main.yml"
- name: Create postgres user
delegate_to: localhost
community.postgresql.postgresql_user:
name: "{{ user }}"
password: "{{ password }}"
state: present
login_host: "{{ db_host }}"
login_port: "{{ db_port }}"
login_user: "{{ db_user }}"
login_password: "{{ db_password }}"

View File

@ -0,0 +1,17 @@
---
- name: Include connection variables
include_vars: "../vars/pg_main.yml"
- name: Give user full priviledges on database
delegate_to: localhost
community.postgresql.postgresql_privs:
db: "{{ database }}"
type: schema
objs: public
privs: ALL
role: "{{ user }}"
state: present
login_host: "{{ db_host }}"
login_port: "{{ db_port }}"
login_user: "{{ db_user }}"
login_password: "{{ db_password }}"

View File

@ -0,0 +1,14 @@
---
- name: Load connection variables
include_vars: "../vars/pg_main.yml"
- name: Install extension on database
delegate_to: localhost
community.postgresql.postgresql_ext:
name: "{{ extension }}"
db: "{{ database }}"
state: present
login_host: "{{ db_host }}"
login_port: "{{ db_port }}"
login_user: "{{ db_user }}"
login_password: "{{ db_password }}"

View File

@ -0,0 +1,54 @@
---
- name: Update apt cache
ansible.builtin.apt:
update_cache: yes
- name: Install prerequisite packages
ansible.builtin.apt:
name:
- ca-certificates
- curl
state: present
- name: Create apt keyrings directory
ansible.builtin.file:
path: /etc/apt/keyrings
state: directory
mode: '0755'
- name: Download Docker GPG key
ansible.builtin.get_url:
url: "https://download.docker.com/linux/ubuntu/gpg"
dest: /etc/apt/keyrings/docker.asc
mode: '0644'
- name: Add Docker apt repository
ansible.builtin.apt_repository:
repo: "deb [arch={{ docker_arch }} signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable"
filename: docker
state: present
vars:
docker_arch: "{{ ansible_architecture | regex_replace('x86_64', 'amd64') }}"
- name: Update apt cache after adding Docker repository
ansible.builtin.apt:
update_cache: yes
- name: Install Docker packages
ansible.builtin.apt:
name:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-buildx-plugin
- docker-compose-plugin
state: present
# - name: Test Docker installation by running hello-world
# ansible.builtin.command: docker run hello-world
# register: docker_test
# ignore_errors: yes
# - name: Display Docker test output
# ansible.builtin.debug:
# msg: "{{ docker_test.stdout }}"

4
vars/pg_main.yml Normal file
View File

@ -0,0 +1,4 @@
db_host: 10.89.0.102
db_port: 5432
db_user: postgres
db_password: password