├── .env ├── README.md ├── deploy.sh ├── docker-compose.yml └── traefik.toml /.env: -------------------------------------------------------------------------------- 1 | # SYSTEM CONFIGURATION 2 | USER_NAME= 3 | PASSWORD= 4 | BASE_DIR=/mnt/media/data 5 | MEDIA_DIR=/mnt/media/data/Media 6 | DOWNLOAD_DIR=/mnt/media/data/downloads 7 | TIMEZONE=Europe/Amsterdam 8 | 9 | # QBITTORRENT VPN CONFIGURATION 10 | VPN_ENABLED= 11 | VPN_USER= 12 | VPN_PASS= 13 | ENABLE_PRIVOXY= 14 | LAN_NETWORK=/ 15 | NAME_SERVERS= 16 | 17 | # LETSENCRYPT CONFIGURATION 18 | DOMAIN= 19 | SUBDOMAINS=media,controle,download,index,tv,film,muziek,portainer 20 | EMAIL= 21 | ONLY_SUBDOMAINS=true 22 | EXTRA_DOMAINS= 23 | 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Docker Mediaserver installer 2 | 3 | This image should work on debian and ubuntu based systems. 4 | 5 | This wil install Docker and linux Cockpit on your system, al other apps are docker's. 6 | 7 | Pull the installer to your server and create a folder : 8 | `sudo git clone https://github.com/Qballjos/one-script-to-install-them-all.git /media-docker/ && cd /media-docker/` 9 | 10 | Edit the `.env` file with the correct info before running the script! 11 | 12 | Make the deploy.sh executable with: `chmod +x ./deploy.sh` 13 | Now run it with: `./deplot.sh` 14 | 15 | You can edit the docker-compose.yml to add or remove apps but these apps are included: 16 | 17 | | service | purpose | url / ports | 18 | | ------- | ------- | :---------: | 19 | | Jellyfin | movie / tv / music interface | https://media.${DOMAIN} | 20 | | Organizr V2 | dashboard | https://controle.${DOMAIN} | 21 | | Qbittorrent VPN | torrent download | https://download.${DOMAIN} | 22 | | Jackett | torznab searcher | https://index.${DOMAIN} | 23 | | Sonarr | tv management | https://tv.${DOMAIN} | 24 | | Radarr | movie management | https://film.${DOMAIN} | 25 | | Lidarr | music management | https://muziek.${DOMAIN} | 26 | | Cockpit | server statistics & management | :9090 | 27 | | Portainer | Docker container installation & management | https://portainer.${DOMAIN} | 28 | | Watchtower | Docker container updater | none | 29 | | Letsencrypt | Docker container updater | none | 30 | 31 | I Still need to generate the subdomain configs for the letsencrypt container 32 | 33 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Perform initial setup and configuration of Docker environment for 4 | # full media server goodness. 5 | 6 | ## FUNCTIONS 7 | info() { 8 | echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $@" 9 | } 10 | 11 | err() { 12 | RED='\033[0;31m' 13 | NC='\033[0m' # No Color 14 | echo -e "${RED}[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $@${NC}" >&2 15 | } 16 | 17 | success() { 18 | GREEN='\033[0;32m' 19 | NC='\033[0m' # No Color 20 | echo -e "${GREEN}[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $@${NC}" 21 | } 22 | 23 | get_env_var() { 24 | VAR=$(grep $1 $2 | xargs) 25 | IFS="=" read -ra VAR <<< "$VAR" 26 | echo ${VAR[1]} | tr -d "\r" 27 | } 28 | 29 | apt_update() { 30 | sudo apt-get update &> /dev/null 31 | if [[ "$?" -ne "$SUCCESS" ]] 32 | then 33 | err "Error occurred updating apt packages." 34 | exit 1 35 | fi 36 | success "apt packages up-to-date." 37 | } 38 | 39 | apt_install() { 40 | apt_update 41 | 42 | sudo apt-get install -y $1 $2 $3 $4 $5 $6 &> /dev/null 43 | if [[ "$?" -ne "$SUCCESS" && "$?" -ne 9 ]] 44 | then 45 | err "Error installing packages." 46 | fi 47 | success "Successfully installed requested packages." 48 | } 49 | 50 | ## VARIABLES 51 | ROOT_UID=0 52 | username=$(get_env_var USER_NAME .env) 53 | password=$(get_env_var PASSWORD .env) 54 | timezone=$(get_env_var TIMEZONE .env) 55 | base_dir=$(get_env_var BASE_DIR .env) 56 | VPN_ENABLED=$(get_env_var VPN_ENABLED .env) 57 | VPN_USER=$(get_env_var VPN_USER .env) 58 | VPN_PASS=$(get_env_var VPN_PASS .env) 59 | ENABLE_PRIVOXY=$(get_env_var ENABLE_PRIVOXY .env) 60 | VPN_ENABLED=$(get_env_var VPN_ENABLED .env) 61 | LAN_NETWORK=$(get_env_var LAN_NETWORK .env) 62 | NAME_SERVERS=$(get_env_var NAME_SERVERS .env) 63 | DOMAIN=$(get_env_var DOMAIN .env) 64 | SUBDOMAINS=$(get_env_var SUBDOMAINS .env) 65 | ONLY_SUBDOMAINS=$(get_env_var ONLY_SUBDOMAINS .env) 66 | EXTRA_DOMAINS=$(get_env_var EXTRA_DOMAINS .env) 67 | 68 | ## EXECUTION 69 | # Must be root 70 | if [[ "${UID}" -ne "${ROOT_UID}" ]] 71 | then 72 | err "Must be root to perform this operation." 73 | exit 1 74 | fi 75 | 76 | # Must have apt 77 | command -v apt-get &> /dev/null 78 | if [[ "$?" -ne "$SUCCESS" ]] 79 | then 80 | err "Process requires apt but doesn't appear to be installed." 81 | exit 1 82 | fi 83 | 84 | # System Configuration 85 | info "Performing system pre-configuration." 86 | # Create user 87 | sudo useradd -p "${password}" -d /home/"${username}" -m -g users -s /bin/bash "${username}" &> /dev/null 88 | if [[ "$?" -ne "$SUCCESS" && "$?" -ne 9 ]] 89 | then 90 | err "Could not create user: ${username}." 91 | fi 92 | success "Created user: ${username}." 93 | 94 | sudo usermod -aG sudo ${username} &> /dev/null 95 | if [[ "$?" -ne "$SUCCESS" ]] 96 | then 97 | err "Error setting user as sudo-er." 98 | exit 1 99 | fi 100 | success "Set user as sudo-er." 101 | 102 | # Set timezone 103 | sudo timedatectl set-timezone "${timezone}" 104 | if [[ "$?" -ne "$SUCCESS" ]] 105 | then 106 | err "Error setting timezone." 107 | exit 1 108 | fi 109 | success "Timezone set to ${timezone}." 110 | 111 | sudo apt-get remove docker docker-engine docker.io &> /dev/null 112 | if [[ "$?" -ne "$SUCCESS" ]] 113 | then 114 | err "Error occurred removing legacy Docker packages." 115 | exit 1 116 | fi 117 | success "Ensured legacy Docker packages are gone." 118 | 119 | # curl install 120 | info "Ensuring curl is installed." 121 | apt_install -y "curl" 122 | 123 | # docker packages & pre-configure 124 | info "Installing Docker CE." 125 | sudo curl -sSL https://get.docker.com | sh &> /dev/null 126 | if [[ "$?" -ne "$SUCCESS" ]] 127 | then 128 | err "Error occurred installing legacy Docker ." 129 | exit 1 130 | fi 131 | success "Docker is installed." 132 | 133 | # pip for docker-compose 134 | info "Ensuring packages for pip and docker-compose are installed." 135 | apt_install -y "libffi-dev" "libssl-dev" "python" "python-pip" 136 | sudo apt-get remove -y "python-configparser" 137 | 138 | info "Installing Docker Compose." 139 | info "Downloading Compose from GitHub." 140 | sudo pip -q install docker-compose 141 | &> /dev/null 142 | if [[ "$?" -ne "$SUCCESS" ]] 143 | then 144 | err "Error downloading Docker Compose." 145 | exit 1 146 | fi 147 | success "Docker Compose installed." 148 | 149 | # cockpit install 150 | info "Installing Cockpit." 151 | apt_install "cockpit" 152 | sudo systemctl enable cockpit.socket > /dev/null 153 | if [[ "$?" -ne "$SUCCESS" ]] 154 | then 155 | err "Cockpit auto-start failed." 156 | exit 1 157 | fi 158 | success "Cockpit set to auto-start." 159 | 160 | # container installation 161 | 162 | info "Building the Docker containers." 163 | sudo docker-compose up --force-recreate -d 164 | if [[ "$?" -ne "$SUCCESS" ]] 165 | then 166 | err "Docker build failed." 167 | exit 1 168 | fi 169 | # All done! 170 | success "Successfully built media server Docker environment!" 171 | exit 0 -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | 4 | ## Media Interfaces 5 | # Plex Server 6 | plex: 7 | image: linuxserver/jellyfin 8 | container_name: jellyfin 9 | hostname: jellyfin 10 | volumes: 11 | - ${BASE_DIR}/jellyfin/config:/config 12 | - ${MEDIA_DIR}/TV:/data/tv 13 | - ${MEDIA_DIR}/Movies:/data/movies 14 | - ${MEDIA_DIR}/Music:/data/music 15 | environment: 16 | - PUID=1000 17 | - PGID=1000 18 | - TZ=${TIMEZONE} 19 | ports: 20 | - 8096:8096 21 | - 8920:8920 22 | restart: always 23 | 24 | ## /Media Interfaces 25 | 26 | ## Downloaders 27 | jackett: 28 | image: linuxserver/jackett:latest 29 | container_name: jackett 30 | volumes: 31 | - ${BASE_DIR}/jackett/config:/config 32 | - ${BASE_DIR}/jackett/blackhole:/downloads 33 | - /etc/localtime:/etc/localtime:ro 34 | environment: 35 | - PUID=1000 36 | - PGID=1000 37 | - TZ=${TIMEZONE} 38 | ports: 39 | - 9117:9117 40 | restart: always 41 | qbittorrent: 42 | image: binhex/arch-qbittorrentvpn:latest 43 | container_name: qbittorrent 44 | volumes: 45 | - ${BASE_DIR}/qbittorrent:/data 46 | - ${BASE_DIR}/qbittorrent:/config 47 | - /etc/localtime:/etc/localtime:ro 48 | environment: 49 | - PUID=1000 50 | - PGID=1000 51 | - TZ=${TIMEZONE} 52 | - VPN_ENABLED=${VPN_ENABLED} 53 | - VPN_USER=${VPN_USER} 54 | - VPN_PASS=${VPN_PASS} 55 | - VPN_PROV=custom 56 | - ENABLE_PRIVOXY=${ENABLE_PRIVOXY} 57 | - LAN_NETWORK=${LAN_NETWORK} 58 | - NAME_SERVERS=${NAME_SERVERS} 59 | - DEBUG=false 60 | - WEBUI_PORT=8080 61 | ports: 62 | - 6881:6881 63 | - 8080:8080 64 | - 8118:8118 65 | - 6881:6881/udp 66 | restart: always 67 | 68 | ## / Downloaders 69 | 70 | ## Searchers 71 | # Sonarr 72 | sonarr: 73 | image: linuxserver/sonarr:latest 74 | container_name: sonarr 75 | volumes: 76 | - ${BASE_DIR}/sonarr/config:/config 77 | - ${MEDIA_DIR}/TV:/tv 78 | - ${DOWNLOAD_DIR}:/downloads 79 | environment: 80 | - PUID=1000 81 | - PGID=1000 82 | - TZ=${TIMEZONE} 83 | ports: 84 | - 8989:8989 85 | restart: always 86 | 87 | # Radarr 88 | radarr: 89 | image: linuxserver/radarr:latest 90 | container_name: radarr 91 | volumes: 92 | - ${BASE_DIR}/radarr/config:/config 93 | - ${MEDIA_DIR}/Movies:/movies 94 | - ${DOWNLOAD_DIR}:/downloads 95 | environment: 96 | - PUID=1000 97 | - PGID=1000 98 | - TZ=${TIMEZONE} 99 | ports: 100 | - 7878:7878 101 | restart: always 102 | 103 | # Lidarr 104 | lidarr: 105 | image: linuxserver/lidarr:latest 106 | container_name: lidarr 107 | volumes: 108 | - ${BASE_DIR}/lidarr/config:/config 109 | - ${MEDIA_DIR}/Music:/music 110 | - ${DOWNLOAD_DIR}:/downloads 111 | environment: 112 | - PUID=1000 113 | - PGID=1000 114 | - TZ=${TIMEZONE} 115 | ports: 116 | - 8686:8686 117 | restart: always 118 | ## /Searchers 119 | 120 | ## Helper Apps 121 | # Organizr 122 | Organizr: 123 | image: linuxserver/organizr:latest 124 | container_name: organizr 125 | volumes: 126 | - ${BASE_DIR}/organizr/config:/config 127 | environment: 128 | - PUID=1000 129 | - PGID=1000 130 | - TZ=${TIMEZONE} 131 | ports: 132 | - 180:80 133 | - 1443:443 134 | restart: always 135 | 136 | # Portainer 137 | Portainer: 138 | image: portainer/portainer:latest 139 | container_name: portainer 140 | volumes: 141 | - /var/run/docker.sock:/var/run/docker.sock 142 | - /var/lib/docker/volumes:/var/lib/docker/volumes 143 | - ${BASE_DIR}/portainer/data:/data 144 | environment: 145 | - PUID=1000 146 | - PGID=1000 147 | - TZ=${TIMEZONE} 148 | ports: 149 | - 9000:9000 150 | - 8000:8000 151 | restart: always 152 | 153 | # Let's encrypt 154 | letsencrypt: 155 | image: linuxserver/letsencrypt 156 | container_name: letsencrypt 157 | cap_add: 158 | - NET_ADMIN 159 | environment: 160 | - PUID=1000 161 | - PGID=1000 162 | - TZ=${TIMEZONE} 163 | - URL=${DOMAIN} 164 | - SUBDOMAINS=${SUBDOMAINS} 165 | - VALIDATION=http 166 | - EMAIL=${EMAIL} 167 | - DHLEVEL=2048 #optional 168 | - ONLY_SUBDOMAINS=${ONLY_SUBDOMAINS} 169 | - EXTRA_DOMAINS=${EXTRA_DOMAINS} #optional 170 | - STAGING=false #optional 171 | volumes: 172 | - ${BASE_DIR}/letsencrypt/config:/config 173 | ports: 174 | - 443:443 175 | - 80:80 #optional 176 | restart: unless-stopped 177 | ## /Helper Apps 178 | 179 | ## Watchtower Updater 180 | watchtower: 181 | image: containrrr/watchtower:latest 182 | container_name: watchtower 183 | volumes: 184 | - /var/run/docker.sock:/var/run/docker.sock 185 | command: 186 | - --cleanup --schedule "0 0 2 * * *" 187 | restart: unless-stopped 188 | ## /Watchtower Updater -------------------------------------------------------------------------------- /traefik.toml: -------------------------------------------------------------------------------- 1 | defaultEntryPoints = ["http","https"] 2 | 3 | [web] 4 | address = ":8080" 5 | 6 | [entryPoints] 7 | [entryPoints.http] 8 | address = ":80" 9 | [entryPoints.http.redirect] 10 | entryPoint = "https" 11 | [entryPoints.https] 12 | address = ":443" 13 | [entryPoints.https.tls] 14 | 15 | [docker] 16 | endpoint="unix:///var/run/docker.sock" 17 | domain="#DOMAIN#" 18 | watch=true 19 | 20 | [acme] 21 | email = "#EMAIL_ADDRESS#" 22 | storage = "acme.json" 23 | entryPoint = "https" 24 | onHostRule = true 25 | onDemand = false --------------------------------------------------------------------------------