commit
0062095ae3
18
.env.sample
18
.env.sample
|
@ -1,3 +1,6 @@
|
|||
# Internal settings (they will not be passed to running services)
|
||||
CHECK_FOR_OUTDATED_CONFIG=true
|
||||
|
||||
# General Traefik (reverse proxy) settings
|
||||
TRAEFIK_DOMAIN=mydomain.com
|
||||
ACME_MAIL=my-email@my-provider.com
|
||||
|
@ -10,7 +13,11 @@ TZ="Europe/Paris"
|
|||
HTTP_USER=myuser
|
||||
HTTP_PASSWORD='mypassword_encoded' # Keep these simple quotes!
|
||||
|
||||
# Containers permissions mapping
|
||||
# Host paths + containers permissions mapping
|
||||
HOST_CONFIG_PATH="/data/config"
|
||||
HOST_MEDIA_PATH="/data/torrents"
|
||||
# Will be located in $HOST_MEDIA_PATH
|
||||
DOWNLOAD_SUBFOLDER="deluge"
|
||||
PGID=1000
|
||||
PUID=1000
|
||||
|
||||
|
@ -29,4 +36,11 @@ PORTAINER_ADMIN_PASSWORD=h4ckMePleAse
|
|||
|
||||
# Flood username declared in deluge rpc daemon
|
||||
FLOOD_PASSWORD=myfloodpassword
|
||||
FLOOD_AUTOCREATE_USER_IN_DELUGE_DAEMON=false
|
||||
FLOOD_AUTOCREATE_USER_IN_DELUGE_DAEMON=false
|
||||
|
||||
# Wireguard custom endpoint
|
||||
WIREGUARD_ENDPOINT=<ENDPOINT>
|
||||
WIREGUARD_PORT=51820
|
||||
WIREGUARD_PUBLIC_KEY=<WIREGUARD_PUBLIC_KEY>
|
||||
WIREGUARD_PRIVATE_KEY=<WIREGUARD_PRIVATE_KEY>
|
||||
WIREGUARD_ADDRESS=<WIREGUARD_LAN_ADDRESS>
|
|
@ -1,8 +1,16 @@
|
|||
.DS_Store
|
||||
|
||||
/config
|
||||
**/tunnel-options.sh
|
||||
**/.env
|
||||
**/traefik/http_auth
|
||||
backup/
|
||||
services.conf
|
||||
|
||||
traefik/custom/dynamic*.yaml
|
||||
traefik/custom/custom-*.yaml
|
||||
samples/custom*/*.yaml
|
||||
|
||||
config.yaml
|
||||
services/custom/*.yaml
|
||||
services/custom/*.yml
|
||||
services/generated/*.yaml
|
118
README.md
118
README.md
|
@ -1,9 +1,33 @@
|
|||
# Seedbox
|
||||
<h1 align="center">Seedbox</h1>
|
||||
<p align="center">
|
||||
An extensive and hackable collection of containerized services to set up a seedbox and personal media server.
|
||||
</p>
|
||||
<br>
|
||||
|
||||
A collection of Dockerfiles and a docker-compose configuration to set up a
|
||||
seedbox and personal media server.
|
||||
## ✨ Features
|
||||
|
||||
## Included Applications
|
||||
* Easy to configure personal media server without needing too much technical skills
|
||||
* Compatible with multiple systems (Linux servers, desktops, Synology NAS...)
|
||||
* Automatic HTTPS ceritificates management and renewal
|
||||
* Support for HTTP only too if required for your use-case
|
||||
* Everything is hackable
|
||||
* Add your own services
|
||||
* Disable the ones you do not want
|
||||
* Customize or add your own routing rules to integrate with existing services
|
||||
* Tweak any service to your need by using custom file parameter on any service
|
||||
* VPN support with multiple providers
|
||||
* Hide the service(s) of your choice behind a VPN tunnel
|
||||
* Non mandatory
|
||||
* Declarative configuration
|
||||
* Persistent data for your media
|
||||
* Install & update using the same script
|
||||
* Start with the [Configuration Guide](doc/configuration.md)
|
||||
|
||||
## ⚠️ News
|
||||
|
||||
Version 2 is released, please make sure you read [this V2 Migration Guide](doc/UPGRADE_V2.md) as there are breaking changes!
|
||||
|
||||
## 📦 Included Applications
|
||||
|
||||
| Application | Web Interface | Docker image | Version (image tag) | Notes |
|
||||
-----------------------|----------------------------|------------------------------------------------------------------------|-------------------------|---------------------|
|
||||
|
@ -14,6 +38,9 @@ seedbox and personal media server.
|
|||
| Radarr | radarr.yourdomain.com | [linuxserver/radarr](https://hub.docker.com/r/linuxserver/radarr) | *develop* | Movies monitor |
|
||||
| Bazarr | bazarr.yourdomain.com | [linuxserver/bazarr](https://hub.docker.com/r/linuxserver/bazarr) | *latest* | Subtitles monitor |
|
||||
| Lidarr | lidarr.yourdomain.com | [linuxserver/lidarr](https://hub.docker.com/r/linuxserver/lidarr) | *develop* | Music monitor |
|
||||
| Readarr | readarr.yourdomain.com | [linuxserver/readarr](https://hub.docker.com/r/linuxserver/readarr) | *nightly* | Ebook and comic monitor |
|
||||
| Komga | komga.yourdomain.com | [gotson/komga](https://hub.docker.com/r/gotson/komga) | *latest* | Comic Book Manager |
|
||||
| Kavita | Kavita.yourdomain.com | [gotson/komga](https://hub.docker.com/r/gotson/komga) | *latest* | Comic Book Manager |
|
||||
| Ombi | ombi.yourdomain.com | [linuxserver/ombi](https://hub.docker.com/r/linuxserver/ombi) | *latest* | Plex content requests |
|
||||
| Overseerr | overseerr.yourdomain.com | [linuxserver/overseerr](https://hub.docker.com/r/linuxserver/overseerr) | *latest* | Plex content requests |
|
||||
| Jackett | jackett.yourdomain.com | [linuxserver/jackett](https://hub.docker.com/r/linuxserver/jackett) | *latest* | Tracker indexer |
|
||||
|
@ -22,58 +49,41 @@ seedbox and personal media server.
|
|||
| Tautulli (plexPy) | tautulli.yourdomain.com | [linuxserver/tautulli](https://hub.docker.com/r/linuxserver/tautulli) | *latest* | Plex stats and admin|
|
||||
| Tdarr | tdarr.yourdomain.com | [haveagitgat/tdarr](https://hub.docker.com/r/haveagitgat/tdarr) | *latest* | Re-encode files |
|
||||
| NextCloud | nextcloud.yourdomain.com | [linuxserver/nextcloud](https://hub.docker.com/r/linuxserver/nextcloud) | *latest* | Files management |
|
||||
| NextCloud-db (MariaDB) | not reachable | [mariadb](https://hub.docker.com/r/_/mariadb) | *10* | DB for Nextcloud |
|
||||
| NextCloud-db (MariaDB) | *not reachable* | [mariadb](https://hub.docker.com/r/_/mariadb) | *10* | DB for Nextcloud |
|
||||
| Portainer | portainer.yourdomain.com | [portainer/portainer](https://hub.docker.com/r/portainer/portainer) | *latest* | Container management|
|
||||
| Netdata | netdata.yourdomain.com | [netdata/netdata](https://hub.docker.com/r/netdata/netdata) | *latest* | Server monitoring |
|
||||
| Duplicati | duplicati.yourdomain.com | [linuxserver/duplicati](https://hub.docker.com/r/linuxserver/duplicati)| *latest* | Backups |
|
||||
| Heimdall | yourdomain.com | [linuxserver/heimdall](https://hub.docker.com/r/linuxserver/heimdall)| *latest* | Main dashboard |
|
||||
| Syncthing | syncthing.yourdomain.com | [linuxserver/syncthing](https://hub.docker.com/r/linuxserver/syncthing) | *latest* | P2P files sharing |
|
||||
| Traefik | traefik.yourdomain.com | [traefik](https://hub.docker.com/_/traefik) | *latest* | Traefik reverse proxy (access to admin dashboard) |
|
||||
| Gluetun | - | [qmcgaw/gluetun](https://hub.docker.com/r/qmcgaw/gluetun)| *latest* | VPN client |
|
||||
| *Any application you want!* | *whatever.yourdomain.com* | *Any image* | *Any tag* | *Any service - See the [Configuration Guide](doc/configuration.md)* |
|
||||
|
||||
The front-end reverse proxy (Traefik - **check the next section if you have already the seedbox with Traefik v1**) routes based on the lowest level subdomain
|
||||
(e.g. `deluge.example.com` would route to deluge). Since this is how the router
|
||||
works, it is recommended for you to get a top level domain. If you do not have
|
||||
one, you can edit your domains locally by changing your hosts file or use a
|
||||
browser plugin that changes the host header.
|
||||
## 🌐 Traefik
|
||||
|
||||
The front-end reverse proxy (Traefik - **check [this guide](doc/traefik_v2.md) if you still have the seedbox with Traefik v1**) routes based on the lowest level subdomain (e.g. `deluge.example.com` would route to deluge). Since this is how the router works, it is recommended for you to get a top level domain. If you do not have one, you can edit your domains locally by changing your hosts file or use a browser plugin that changes the host header.
|
||||
|
||||
Traefik takes care of valid Let's Encrypt certificates and auto-renewal.
|
||||
|
||||
Note: Plex is also available directly through the `32400` port without going
|
||||
through the reverse proxy.
|
||||
Note: Plex is also available directly through the `32400` port without going through the reverse proxy.
|
||||
|
||||
## September 2020 - Upgrade to Traefik v2 instructions
|
||||
You can also add your own Traefik rules to integrate with other services (deployed wihthin docker or somewhere else on your LAN, or even on the Internet).
|
||||
Check the [Configuration Guide](doc/configuration.md).
|
||||
|
||||
Before upgrading Traefik to version 2, please check the following:
|
||||
## ⚙️ Installation
|
||||
|
||||
- In this repo, Traefik v2 upgrade is as seamless as possible (same environment variables than before, out-of-the-box config file...).
|
||||
- **First, ``git pull`` to grab the latest code.**
|
||||
- The ``HTTP_PASSWORD`` variable now must be simple-quoted in the .env file. See the updated ``.env.sample`` file (which has also been reorganized)
|
||||
- Run ``init.sh`` in order to create required Docker objects (network name has changed).
|
||||
- You can update your acme.json to a Traefik v2-compliant one by doing the following (before launching Traefik v2):
|
||||
|
||||
```sh
|
||||
mkdir -p /tmp/migration
|
||||
cd /tmp/migration
|
||||
sudo cp /opt/traefik/acme.json .
|
||||
sudo chmod 775 /tmp/migration/acme.json
|
||||
# Do *NOT* forget the --resolver at the end! (le = Let's Encrypt resolver, see traefik/traefik.yml)
|
||||
docker run --rm -v ${PWD}:/data -w /data containous/traefik-migration-tool acme -i acme.json -o acme2.json --resolver le
|
||||
mkdir -p /data/config/traefik
|
||||
sudo cp acme2.json /data/config/traefik/acme.json
|
||||
sudo chmod 600 /data/config/traefik/acme.json
|
||||
# When you already have a backup!
|
||||
sudo rm -rf /opt/traefik /tmp/migration
|
||||
```
|
||||
|
||||
- As from Traefik v2, as Http Authentication is now possible on the Traefik console, the latter is enabled at ``traefik.yourdomain.com``.
|
||||
- After all this, you can simply do: ``./update-all.sh``! Voilà!
|
||||
|
||||
## Dependencies
|
||||
### Dependencies
|
||||
|
||||
- [Docker](https://github.com/docker/docker) >= 20.10
|
||||
- [Docker Compose](https://github.com/docker/compose) >= 1.28.0
|
||||
- [local-persist Docker plugin](https://github.com/MatchbookLab/local-persist): installed directly on host (not in container). This is a volume plugin that extends the default local driver’s functionality by allowing you specify a mountpoint anywhere on the host, which enables the files to always persist, even if the volume is removed via `docker volume rm`. Use *systemd* install for Ubuntu 16.04.
|
||||
- [Docker Compose](https://github.com/docker/compose) >= 2.2
|
||||
- [local-persist Docker plugin](https://github.com/MatchbookLab/local-persist): installed directly on host (not in container). This is a volume plugin that extends the default local driver’s functionality by allowing you specify a mountpoint anywhere on the host, which enables the files to always persist, even if the volume is removed via `docker volume rm`. Use *systemd* install for Ubuntu.
|
||||
- [jq](https://stedolan.github.io/jq/download/) >= 1.5
|
||||
- [yq](https://github.com/mikefarah/yq/releases) >= 4
|
||||
|
||||
## Configuration
|
||||
### Prepare your host
|
||||
|
||||
Before running, please create the volumes which will be statically mapped to the ones on the host:
|
||||
For example:
|
||||
|
||||
```sh
|
||||
sudo su -c "mkdir /data && mkdir /data/config && mkdir /data/torrents"
|
||||
|
@ -83,29 +93,23 @@ sudo su -c "mkdir /data && mkdir /data/config && mkdir /data/torrents"
|
|||
Edit the `.env` file and change the variables as desired.
|
||||
The variables are all self-explanatory.
|
||||
|
||||
**NEW**
|
||||
You can also disable a service if you do not need it by editing the ``services.conf`` file.
|
||||
Simply change the "*enable*" key with the "*disable*" one for the service you want to disable.
|
||||
If you remove a line in this file, it will be considered as "enabled" as all services are enabled by default.
|
||||
### Review the configuration
|
||||
|
||||
## Running & updating
|
||||
The configuration lives in the ``config.yaml`` file.
|
||||
|
||||
All you need to know is located in the [Configuration Guide](doc/configuration.md).
|
||||
|
||||
### Running & updating
|
||||
|
||||
```sh
|
||||
./update-all.sh
|
||||
./run-seedbox.sh
|
||||
```
|
||||
|
||||
docker-compose should manage all the volumes and network setup for you. If it
|
||||
does not, verify that your docker and docker-compose version is updated.
|
||||
All services and synamic configuration will be automatically created without further action from your part.
|
||||
|
||||
Make sure you install the dependencies and finish configuration before doing
|
||||
this.
|
||||
Make sure you install the dependencies and finish configuration before doing this.
|
||||
|
||||
## PlexPass
|
||||
|
||||
Just set the `VERSION` environment variable to `latest` on the Plex service (enabled by default).
|
||||
See https://hub.docker.com/r/linuxserver/plex.
|
||||
|
||||
## Where is my data?
|
||||
### Where is my data?
|
||||
|
||||
All data is saved in the docker volumes `seedbox_config` or
|
||||
`seedbox_torrents`.
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
################################################################################
|
||||
### === config-updater.sh === ###
|
||||
### Script which takes as input the old format config file (services.conf) ###
|
||||
### and transforms it in the new format in yaml, using jq and yq ###
|
||||
################################################################################
|
||||
|
||||
cleanup_on_exit() {
|
||||
rm -f tmp.json config.json
|
||||
}
|
||||
trap cleanup_on_exit EXIT
|
||||
|
||||
# Load common functions
|
||||
source config/tools.sh
|
||||
|
||||
# Check that required tools are installed
|
||||
check_utilities
|
||||
|
||||
if [[ ! -f services.conf ]]; then
|
||||
echo "[$0] ERROR. Could nof find services.conf. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
jq -n '{"services": []}' > config.json
|
||||
|
||||
# First, add Traefik as it was not explicitely set by default in old config file (services.conf)
|
||||
if ! grep -q "traefik" services.conf; then
|
||||
jq -r '.services[.services| length] |= . +
|
||||
{
|
||||
"name": "traefik",
|
||||
"enabled": true,
|
||||
"traefik": {
|
||||
"enabled": true,
|
||||
"rules": [
|
||||
{
|
||||
"host": "traefik.'$(echo '${TRAEFIK_DOMAIN}')'",
|
||||
"service": "api@internal",
|
||||
"httpAuth": true,
|
||||
}
|
||||
]
|
||||
}
|
||||
}' config.json > tmp.json
|
||||
rm -f config.json
|
||||
mv tmp.json config.json
|
||||
fi
|
||||
|
||||
cat services.conf | while read line || [[ -n $line ]]; do
|
||||
key=$(echo $line | sed -r "s/^(.*):.*$/\1/")
|
||||
enabled="true"
|
||||
if grep -q "disable" <<< $line; then
|
||||
enabled="false"
|
||||
fi
|
||||
|
||||
# Compatibility for services.conf already on dev (with temporary syntax -vpn)
|
||||
if grep -q "\-vpn" <<< $line; then continue; fi
|
||||
|
||||
enableVpn="false"
|
||||
# If this service is disabled AND another one in the file is enabled with VPN mode, keep that information
|
||||
if grep -q "$key-vpn: enable" services.conf; then
|
||||
if [[ enabled="false" ]]; then
|
||||
#echo "[$0] $key => another service detected enabled with vpn..."
|
||||
enableVpn="true"
|
||||
enabled="true"
|
||||
fi
|
||||
fi
|
||||
|
||||
if grep -q "\-hardware-transcoding" <<< $line; then continue; fi
|
||||
|
||||
# Define if Traefik should be enabled on the service
|
||||
case $key in
|
||||
flaresolverr|gluetun)
|
||||
enableTraefik="false"
|
||||
rules=$(jq -n '[]')
|
||||
;;
|
||||
*)
|
||||
enableTraefik="true"
|
||||
# If Traefik enabled => define if http auth Traefik middleware must be set by default
|
||||
case $key in
|
||||
kavita|komga|nextcloud|ombi|overseerr|plex|portainer|tautulli)
|
||||
defaultHttpAuth="false"
|
||||
;;
|
||||
*)
|
||||
defaultHttpAuth="true"
|
||||
;;
|
||||
esac
|
||||
# Define scheme // For nextcloud, scheme must be https
|
||||
internalScheme="http"
|
||||
[[ $key == "nextcloud" ]] && internalScheme="https"
|
||||
|
||||
# Define service default port from bundled config file
|
||||
internalPort=$(cat config/ports | { grep $key || true; } | sed -r "s/^${key}: (.*)$/\1/")
|
||||
rules=$(jq -n '[
|
||||
{
|
||||
"host": "'"$key"'.'$(echo '${TRAEFIK_DOMAIN}')'",
|
||||
"httpAuth": '"${defaultHttpAuth}"',
|
||||
"internalPort": '"${internalPort}"',
|
||||
"internalScheme": "'"${internalScheme}"'"
|
||||
}
|
||||
]')
|
||||
;;
|
||||
esac
|
||||
|
||||
jq -r --argjson RULES "$rules" '.services[.services| length] |= . +
|
||||
{
|
||||
"name": "'"$key"'",
|
||||
"enabled": '"${enabled}"',
|
||||
"vpn": '"${enableVpn}"',
|
||||
"traefik": {
|
||||
"enabled": '"${enableTraefik}"',
|
||||
"rules": $RULES
|
||||
}
|
||||
}' config.json > tmp.json
|
||||
rm -f config.json
|
||||
mv tmp.json config.json
|
||||
|
||||
done
|
||||
|
||||
# Transform json into yaml, easier to manipulate for the user
|
||||
cat config.json | yq e -P - > config.yaml
|
|
@ -0,0 +1,238 @@
|
|||
services:
|
||||
- name: traefik
|
||||
enabled: true
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: traefik.${TRAEFIK_DOMAIN}
|
||||
service: api@internal
|
||||
httpAuth: true
|
||||
- name: deluge
|
||||
enabled: true
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: deluge.${TRAEFIK_DOMAIN}
|
||||
httpAuth: true
|
||||
internalPort: 8112
|
||||
# Uncomment to specify custom schme (http by default)
|
||||
# internalScheme: http
|
||||
# Uncomment to *NOT* generate LetsEncrypt certificate (useful for local domains)
|
||||
# httpOnly: true
|
||||
- name: flood
|
||||
enabled: true
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: flood.${TRAEFIK_DOMAIN}
|
||||
httpAuth: true
|
||||
internalPort: 3000
|
||||
- name: plex
|
||||
enabled: true
|
||||
vpn: false
|
||||
# uncomment to use custom file with specific parameters for hardware transcoding
|
||||
# customFile: plex-hardware-transcoding.yaml
|
||||
# You can also place you own file in services/custom/ and call it here like this:
|
||||
# customFile: custom/my_own_file.yaml
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: plex.${TRAEFIK_DOMAIN}
|
||||
httpAuth: false
|
||||
internalPort: 32400
|
||||
- name: flaresolverr
|
||||
enabled: true
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: false
|
||||
rules: []
|
||||
- name: jackett
|
||||
enabled: true
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: jackett.${TRAEFIK_DOMAIN}
|
||||
httpAuth: true
|
||||
internalPort: 9117
|
||||
- name: prowlarr
|
||||
enabled: true
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: prowlarr.${TRAEFIK_DOMAIN}
|
||||
httpAuth: true
|
||||
internalPort: 9696
|
||||
- name: sonarr
|
||||
enabled: true
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: sonarr.${TRAEFIK_DOMAIN}
|
||||
httpAuth: true
|
||||
internalPort: 8989
|
||||
- name: radarr
|
||||
enabled: true
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: radarr.${TRAEFIK_DOMAIN}
|
||||
httpAuth: true
|
||||
internalPort: 7878
|
||||
- name: bazarr
|
||||
enabled: true
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: bazarr.${TRAEFIK_DOMAIN}
|
||||
httpAuth: true
|
||||
internalPort: 6767
|
||||
- name: lidarr
|
||||
enabled: false
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: lidarr.${TRAEFIK_DOMAIN}
|
||||
httpAuth: true
|
||||
internalPort: 8686
|
||||
- name: readarr
|
||||
enabled: false
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: readarr.${TRAEFIK_DOMAIN}
|
||||
httpAuth: true
|
||||
internalPort: 8787
|
||||
- name: komga
|
||||
enabled: false
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: komga.${TRAEFIK_DOMAIN}
|
||||
httpAuth: false
|
||||
internalPort: 8080
|
||||
- name: kavita
|
||||
enabled: false
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: kavita.${TRAEFIK_DOMAIN}
|
||||
httpAuth: false
|
||||
internalPort: 5000
|
||||
- name: ombi
|
||||
enabled: false
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: ombi.${TRAEFIK_DOMAIN}
|
||||
httpAuth: false
|
||||
internalPort: 3579
|
||||
- name: overseerr
|
||||
enabled: true
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: overseerr.${TRAEFIK_DOMAIN}
|
||||
httpAuth: false
|
||||
internalPort: 5055
|
||||
- name: tautulli
|
||||
enabled: true
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: tautulli.${TRAEFIK_DOMAIN}
|
||||
httpAuth: false
|
||||
internalPort: 8181
|
||||
- name: jdownloader
|
||||
enabled: true
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: jdownloader.${TRAEFIK_DOMAIN}
|
||||
httpAuth: true
|
||||
internalPort: 5800
|
||||
- name: tdarr
|
||||
enabled: true
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: tdarr.${TRAEFIK_DOMAIN}
|
||||
httpAuth: true
|
||||
internalPort: 8265
|
||||
- name: nextcloud
|
||||
enabled: true
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: nextcloud.${TRAEFIK_DOMAIN}
|
||||
httpAuth: false
|
||||
internalPort: 443
|
||||
internalScheme: https
|
||||
- name: portainer
|
||||
enabled: true
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: portainer.${TRAEFIK_DOMAIN}
|
||||
httpAuth: false
|
||||
internalPort: 9443
|
||||
- name: netdata
|
||||
enabled: true
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: netdata.${TRAEFIK_DOMAIN}
|
||||
httpAuth: true
|
||||
internalPort: 19999
|
||||
- name: duplicati
|
||||
enabled: false
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: duplicati.${TRAEFIK_DOMAIN}
|
||||
httpAuth: true
|
||||
internalPort: 8200
|
||||
- name: syncthing
|
||||
enabled: false
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: syncthing.${TRAEFIK_DOMAIN}
|
||||
httpAuth: true
|
||||
internalPort: 8384
|
||||
- name: heimdall
|
||||
# Beware to the host when enabling it!
|
||||
enabled: false
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: ${TRAEFIK_DOMAIN}
|
||||
httpAuth: true
|
||||
internalPort: 80
|
||||
# Gluetun is the VPN client service.
|
||||
- name: gluetun
|
||||
enabled: false
|
||||
traefik:
|
||||
enabled: false
|
||||
rules: []
|
|
@ -0,0 +1,24 @@
|
|||
bazarr: 6767
|
||||
deluge: 8112
|
||||
flood: 3000
|
||||
heimdall: 80
|
||||
jackett: 9117
|
||||
jdownloader: 5800
|
||||
ombi: 3579
|
||||
overseerr: 5055
|
||||
plex: 32400
|
||||
prowlarr: 9696
|
||||
radarr: 7878
|
||||
sonarr: 8989
|
||||
lidarr: 8686
|
||||
readarr: 8787
|
||||
komga: 8080
|
||||
kavita: 5000
|
||||
nextcloud: 443
|
||||
portainer: 9443
|
||||
syncthing: 8384
|
||||
tdarr: 8265
|
||||
netdata: 19999
|
||||
duplicati: 8200
|
||||
tautulli: 8181
|
||||
traefik: 80
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/bash
|
||||
|
||||
##############################################################################
|
||||
############################### UTIL FUNCTIONS ###############################
|
||||
##############################################################################
|
||||
|
||||
check_utilities () {
|
||||
# Check that jq is installed
|
||||
if ! which jq >/dev/null; then
|
||||
echo "[$0] jq does not exist. Install it from here: https://stedolan.github.io/jq/download/"
|
||||
echo "[$0] Please install jq version 1.5 or above."
|
||||
echo "[$0] Also, please make sure it is in the PATH."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check that yq is installed
|
||||
if ! which yq >/dev/null; then
|
||||
echo "[$0] yq does not exist. Install it from here: https://github.com/mikefarah/yq/releases"
|
||||
echo "[$0] Please install yq version 4 or above."
|
||||
echo "[$0] Also, please make sure it is in the PATH."
|
||||
exit 1
|
||||
fi
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
# Upgrade to V2
|
||||
|
||||
**Seedbox version 2 is here!** 🔥
|
||||
|
||||
Since there are some breaking changes and a configuration structure migration, a major version was mandatory.
|
||||
|
||||
## What's new?
|
||||
|
||||
* **Configuration change to new YAML format**
|
||||
* Run ``config-updater.sh`` to migrate your old services.conf to the new config.yaml format.
|
||||
* ⚠️ ``jq`` (v1.5+) and ``yq`` (v4+) are now requirements
|
||||
* Easier feature switches
|
||||
* If a service is missing, it won't be enabled by default like before. The config is now more declarative.
|
||||
* Traefik routing rules are now dynamically generated in a file in Traefik config directory, so no more Docker labels. They became hard to maintain due to all possibilities caused by VPN support or custom files for example.
|
||||
* New config syntax documented in the [Configuration Guide](./configuration.md#configuration-structure-and-parameters).
|
||||
* **VPN support**
|
||||
* With ``gluetun`` service, you can now place any service behind a VPN.
|
||||
* Default gluetun configuration is Wireguard "custom" mode, but see below...
|
||||
* More details in the [VPN section of the Configuration Guide](./configuration.md#vpn).
|
||||
* **Support custom services and docker-compose yaml files**
|
||||
* Place a docker-compose yaml file in ``services/custom/`` directory, add a service in your config.yaml specifying a ``customFile``, and you are set.
|
||||
* Support Plex hardware transcoding using a custom-file, already available in the ``services`` directory (just specify a ``customFile`` on plex service - see [config.sample.yaml](../config.sample.yaml)).
|
||||
* More details in the [Configuration Guide](./configuration.md#add-your-own-service).
|
||||
* **Support arbitrary Traefik rules**
|
||||
* Place a Traefik YAML in ``samples/custom-traefik/`` directory, it will be copied in the Traefik configuration folder.
|
||||
* Ideal to forward traffic to other services which do not belong to this seedbox.
|
||||
* More details in [this section of the Configuration Guide](./configuration.md#integration-with-other-services-custom-traefik-config)
|
||||
* **Disable certificates for some domains**
|
||||
* Using the flag ``httpOnly: true`` on a service, access any service in unsecure mode, delegating certificates management on a higher level (reverse proxy, firewall...). More details in the [Configuration Guide](./configuration.md#disable-https-completely).
|
||||
* **Multiple hosts for any services**
|
||||
* The new config structure allows for more customization, for example you can now have many routes on the same service. Let's say, a local unsecured route + a secured one for remote access. Or anything you want.
|
||||
* **More customization**
|
||||
* Such as http authentication which is no more hardcoded but configurable for each service.
|
||||
* Configurable paths on host for persistent data
|
||||
* **New services**
|
||||
* ``Gluetun``: [VPN client (see above)](https://github.com/qdm12/gluetun)
|
||||
* ``Heimdall``: [Dashboard](https://github.com/linuxserver/Heimdall)
|
||||
* ``Readarr``: [Ebook and comic monitor](https://github.com/Readarr/Readarr)
|
||||
* ``Komga``: [Comic Book Manager](https://github.com/gotson/komga)
|
||||
* ``Kavita``: [Comic / Book Manager](https://github.com/Kareadita/Kavita)
|
||||
* ``Syncthing``: [P2P files synchronization](https://github.com/linuxserver/docker-syncthing)
|
||||
* ⚠️ Docker compose v2.2+ is now required
|
||||
|
||||
And also:
|
||||
|
||||
* ``update-all.sh`` is now called ``run-seedbox.sh`` but its purpose is the same.
|
||||
* More checks in ``run-seedbox.sh``. For example, throws an error if Flood is enabled but not Deluge, or if VPN is enabled on a service but the VPN client is not.
|
||||
* You can now specify where your data lives on your host through new environments variables (see [.env.sample](.env.sample)).
|
||||
* This change is backward-compatible as the ``run-seedbox.sh`` script will default to the old "/data/torrents" and "/data/config" paths if these variables are not set.
|
||||
* ``networks:`` section is now aligned with the new docker compose syntax
|
||||
* ⚠️ Nextcloud-db has moved. It is now in ``/data/config`` (or somewhere else if you set the new variables for host paths) (see below how to mitigate the errors). [See the dedicated section below](#nextcloud-db-has-moved).
|
||||
* Disable Traefik access logs
|
||||
* New flag ``--debug`` for ``run-seedbox.sh`` to see what is happening during configuration parsing.
|
||||
* Releases are named after LOST mythology. I exhausted all the characters of Person of Interest, so that's time for a change. Only geeks will get it, I know.
|
||||
|
||||
## Some reading about configuration
|
||||
|
||||
📖 Do not forget to read the [Configuration Guide](./configuration.md).
|
||||
|
||||
## How to migrate
|
||||
|
||||
```sh
|
||||
./config-updater.sh
|
||||
# Check the content of your .env file (in comparison with .env.sample which brings new variables)
|
||||
# Also, check your generated config.yaml and read the config documentation (in doc/configuration.md)
|
||||
./run-seedbox.sh
|
||||
```
|
||||
|
||||
When everything runs smoothly, you can delete your old configuration file which is now useless:
|
||||
|
||||
```sh
|
||||
rm -f services.conf
|
||||
```
|
||||
|
||||
> ⚠️ Also, please make sure you have read the next section about Nextcloud Database location.
|
||||
|
||||
## Nextcloud-db has moved
|
||||
|
||||
Since commit e4ede925a8ce09b177206f30487a889da9e10334, nextcloud-db directory (mapped on /var/lib/mysql) has moved from
|
||||
``/data/nextcloud-db`` to ``$HOST_CONFIG_PATH/nextcloud-db`` (*/data/config/nextcloud-db by default*).
|
||||
|
||||
To ensure a smooth transition, you will have to move the directory nextcloud-db into the correct new location, then run some commands to fix the schema:
|
||||
|
||||
```sh
|
||||
mv /data/nextcloud-db/ /data/config/
|
||||
./run-seedbox.sh
|
||||
source .env
|
||||
docker exec -it nextcloud-db mysql_upgrade -u root -p${MYSQL_ROOT_PASSWORD}
|
||||
docker restart nextcloud nextcloud-db
|
||||
```
|
||||
|
||||
Ensure everything runs nicely by looking at nextcloud-db and nextcloud logs, and by accessing your Nextcloud web UI.
|
|
@ -0,0 +1,318 @@
|
|||
# Seedbox configuration
|
||||
|
||||
## Table of content
|
||||
|
||||
* [General principles](#general-principles)
|
||||
* [Configuration structure and parameters](#configuration-structure-and-parameters)
|
||||
* [Environment variables](#environment-variables)
|
||||
* [Add your own service](#add-your-own-service)
|
||||
* [Particular case: Plex with Hardware Transcoding](#particular-case-plex-with-hardware-transcoding)
|
||||
* [Integration with other services (custom Traefik config)](#integration-with-other-services-custom-traefik-config)
|
||||
* [Disable HTTPS completely](#disable-https-completely)
|
||||
* [VPN](#vpn)
|
||||
* [Default mode - Wireguard custom](#default-mode---wireguard-custom)
|
||||
* [Your own mode (VPN provider supported by gluetun)](#your-own-mode-vpn-provider-supported-by-gluetun)
|
||||
* [How does VPN is handled?](#how-does-vpn-is-handled)
|
||||
* [Make the services communicate with each other](#make-the-services-communicate-with-each-other)
|
||||
* [How does the configuration work?](#how-does-the-configuration-work)
|
||||
|
||||
## General principles
|
||||
|
||||
Every service (Plex, Sonarr, Jackett, Nextcloud...) is defined in a dedicated file (in docker-compose format) in the [services](../services/) directory.
|
||||
|
||||
All your configuration such as:
|
||||
|
||||
* Which services must be enabled
|
||||
* What docker-compose file they are using if a a particular one must be applied instead of the default one (which is the one with the same name as the service)
|
||||
* Routing rules (example: ``sonarr.yourdomain.com`` for Sonarr)
|
||||
* If http authentication must be enabled (example: *enable* for Sonarr, *disable* for Nextcloud has it has built-in authentication)
|
||||
* Some other parameters (see below)
|
||||
|
||||
... is located in ``config.yaml``. If you are starting fresh, copy ``config.sample.yaml`` into ``config.yaml``. If you don't, on the first run, ``./run-seedbox.sh`` will copy the sample file for you.
|
||||
|
||||
Then, all your "sensitive" (or "personal") data configuration (passwords, usernames, domain name, paths on the machine for persistent data...) is located in ``.env`` file.
|
||||
|
||||
When running ``./run-seedbox.sh``:
|
||||
|
||||
* ``.env`` is loaded
|
||||
* ``config.yaml`` is parsed, some checks are performed
|
||||
* For each service, if enabled, Traefik rules are generated ([see this section](#how-does-the-configuration-work)) dynamically
|
||||
* docker-compose commands (pull, up...) are executed against all relevant files
|
||||
|
||||
## Configuration structure and parameters
|
||||
|
||||
Almost the whole stack can be configured by using the main configuration item: ``config.yaml``.
|
||||
Here is what it looks like:
|
||||
|
||||
```yaml
|
||||
# List of all services
|
||||
services:
|
||||
# Name of the service
|
||||
- name: traefik
|
||||
# Flag indicating if the service will be created or not
|
||||
enabled: true
|
||||
# Define traefik (reverse proxy) behavior for this service
|
||||
traefik:
|
||||
# Enable or disable Traefik routing. For example, if your service is a DB, disable Traefik.
|
||||
enabled: true
|
||||
# Routing rules, which will be processed and rendered as Traefik "dynamic configuration" via file provider
|
||||
rules:
|
||||
# Host to match request. Any environment variable is supported here, as long as there are braces around it.
|
||||
- host: traefik.${TRAEFIK_DOMAIN}
|
||||
# Traefik service to match (if it is a particular one). Here the "api@internal" service is internal to Traefik (dashboard access). If not specified, a "traefik service" with the same name as the docker service will be created.
|
||||
service: api@internal
|
||||
# Enable http authentication
|
||||
httpAuth: true
|
||||
# Another service
|
||||
- name: deluge
|
||||
enabled: true
|
||||
# Enable VPN (default to false). Service "gluetun" must be configured and enabled (with proper variables set in .env) to be able to use vpn mode on any service.
|
||||
vpn: true
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: deluge.${TRAEFIK_DOMAIN}
|
||||
# No service is defined here => a traefik service named "deluge" will be created automatically
|
||||
httpAuth: true
|
||||
# Internal container port on which we want to bind the Traefik routing
|
||||
internalPort: 8112
|
||||
# Another service
|
||||
- name: flaresolverr
|
||||
enabled: true
|
||||
# Do not use VPN (same as nothing as false is default)
|
||||
vpn: false
|
||||
traefik:
|
||||
# This service is not reachable directly (no UI). So Traefik is disabled and rules are an empty array.
|
||||
enabled: false
|
||||
# Optional, won't be evaluated as Traefik is disabled
|
||||
rules: []
|
||||
# Another service with 2 Traefik rules
|
||||
- name: sonarr
|
||||
enabled: true
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
# First "regular" routing rule
|
||||
- host: sonarr.${TRAEFIK_DOMAIN}
|
||||
httpAuth: true
|
||||
internalPort: 8989
|
||||
# Another rule which bypasses certificate generation using Let's Encrypt (ACME challenge).
|
||||
- host: sonarr-unsecure.${TRAEFIK_DOMAIN}
|
||||
httpAuth: true
|
||||
internalPort: 8989
|
||||
# Using this flag, sonarr-unsecure.domain.com (for example) will be accessible ONLY via http protocol
|
||||
httpOnly: true
|
||||
# Another service with backend using https
|
||||
- name: nextcloud
|
||||
enabled: false
|
||||
vpn: false
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: nextcloud.${TRAEFIK_DOMAIN}
|
||||
httpAuth: false
|
||||
internalPort: 443
|
||||
# Specify that the routing will be on https://nextcloud:443 (internally), while by default services expose only http.
|
||||
# Nextcloud is known to be an exception and exposes only port 443 with SSL
|
||||
internalScheme: https
|
||||
```
|
||||
|
||||
The provided ``config.sample.yaml`` is good enough to get started and will be used if no ``config.yaml`` is found.
|
||||
|
||||
Some general rules:
|
||||
|
||||
* In order to enable VPN (``vpn: true``) on a service, you must configure and enable gluetun service.
|
||||
* By default, all services match "http://service_name:port" for routing.
|
||||
* By default, when ``httpOnly`` is false or not set, service will be accessible from both http and https, but a redirection will be created from http to https.
|
||||
* And when ``httpOnly`` is set to true, the service will be accessible ONLY via http, bypassing certificate generation. It is useful when you do not want Traefik to handle certificates for this service.
|
||||
|
||||
## Environment variables
|
||||
|
||||
Also, do not forget to edit your ``.env`` file, which is where all the data which will be sent to containers (passwords, tokens, uid for disk permission...) lives.
|
||||
|
||||
## Add your own service
|
||||
|
||||
Let's say you want to add a container nginx without interfering or creating conflicts in this git repository. That's possible.
|
||||
|
||||
Start by creating a file named nginx.yaml in the [services/custom/](services/custom/) directory:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
nginx:
|
||||
image: nginx:latest
|
||||
container_name: nginx
|
||||
restart: always
|
||||
# ...
|
||||
```
|
||||
|
||||
Then, enable it in your ``config.yaml``:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
# ...
|
||||
- name: nginx
|
||||
enabled: true
|
||||
vpn: false
|
||||
# Specify the path to your custom docker-compose file, relative to the "services" directory
|
||||
customFile: custom/nginx.yaml
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: nginx.${TRAEFIK_DOMAIN}
|
||||
httpAuth: false
|
||||
# 80 because official nginx image uses this port
|
||||
internalPort: 80
|
||||
# ...
|
||||
```
|
||||
|
||||
...and you're set! Just run ``./run-seedbox.sh`` to apply configuration changes.
|
||||
|
||||
> Please note that the ``customFile`` flag **MUST** be relative to the "services" directory, because in some cases, some alternatives yaml files for bundled services are provided in the services directory. See the next section for more details.
|
||||
|
||||
### Particular case: Plex with Hardware Transcoding
|
||||
|
||||
This project provides a custom [plex-hardware-transcoding.yaml](../services/plex-hardware-transcoding.yaml) file, with all the necessary adaptations to make Plex run with hardware transcoding enabled.
|
||||
|
||||
Just add the ``customFile: plex-hardware-transcoding.yaml`` field in the ``plex`` service and this file will be used, instead of the default "plex.yaml":
|
||||
|
||||
```yaml
|
||||
services:
|
||||
# ...
|
||||
- name: plex
|
||||
enabled: true
|
||||
vpn: false
|
||||
# Here is the change: by default, without this flag, the applied file was "plex.yaml"
|
||||
customFile: plex-hardware-transcoding.yaml
|
||||
traefik:
|
||||
enabled: true
|
||||
rules:
|
||||
- host: plex.${TRAEFIK_DOMAIN}
|
||||
httpAuth: false
|
||||
internalPort: 32400
|
||||
# ...
|
||||
```
|
||||
|
||||
Then, run ``./run-seedbox.sh`` to make these changes taken into account and the new container Plex will have hardware transcoding.
|
||||
|
||||
> Note that you also have to enable Hardware Transcoding in your Plex Server settings after the container has started.
|
||||
|
||||
## Integration with other services (custom Traefik config)
|
||||
|
||||
You can also add you own Traefik configuration to integrate with local services on your LAN.
|
||||
Just put your Traefik configuration file in the [samples/custom-traefik/](../samples/custom-traefik/) directory.
|
||||
All files will be copied in the Traefik configuration directory on each ``run-seedbox`` execution.
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
http:
|
||||
routers:
|
||||
synology-admin:
|
||||
rule: 'Host(`synology-admin.{{ env "TRAEFIK_DOMAIN" }}`)'
|
||||
middlewares:
|
||||
- common-auth@file
|
||||
service: admin
|
||||
services:
|
||||
synology-admin:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "https://your-nas-hostname-on-your-local-network:5001"
|
||||
```
|
||||
|
||||
## Disable HTTPS completely
|
||||
|
||||
If you want to handle your certificates on a firewall or another reverse proxy somewhere else on your network, it is now possible.
|
||||
You just have to set ``httpOnly: true`` on all your services in ``config.yaml``.
|
||||
Then, make the machine which acts as reverse proxy (and handles certificates) points on every Traefik URL with the corresponding certificate, or make a wildcard redirection, based on your reverse proxy.
|
||||
|
||||
## VPN
|
||||
|
||||
In order to hide a service behind a VPN, just enable ``gluetun`` service.
|
||||
|
||||
By default, the file used is [gluetun.yaml](../services/gluetun.yaml), which is in "Wireguard custom" mode, meaning you must have somewhere a Wireguard server running and access to its client configuration. But you can add your own config to match your requirements. See sections below.
|
||||
|
||||
### Default mode - Wireguard custom
|
||||
|
||||
* Edit the ``.env`` file and replace the Wireguard variables with your own (take them in ``.env.sample``).
|
||||
* Enable ``gluetun`` service.
|
||||
* Enable vpn (``vpn: true``) on any service.
|
||||
* Run ``./run-seedbox.sh``.
|
||||
* The service now uses Wireguard. If gluetun is down or if the VPN link is broken, your service won't have any access to Internet.
|
||||
|
||||
### Your own mode (VPN provider supported by gluetun)
|
||||
|
||||
* Create a ``gluetun-custom.yaml`` in the [services/custom/](../services/custom/) directory. You can duplicate [this one](../services/gluetun.yaml) to avoid starting from scratch.
|
||||
* Adapt it to your needs (variables, mode...) according to your provider.
|
||||
* Add all variables you may need (used in your custom yaml file) in your ``.env`` file (replacing the wireguard ones).
|
||||
* Edit your ``config.yaml`` and add ``customFile: custom/gluetun-custom.yaml`` in the ``gluetun`` section.
|
||||
* Enable vpn (``vpn: true``) on any service.
|
||||
* Run ``./run-seedbox.sh``.
|
||||
* The service now uses your VPN by tunneling via gluetun container. If gluetun is down or if the VPN link is broken, your service won't have any access to Internet.
|
||||
|
||||
### How does VPN is handled?
|
||||
|
||||
Behind the scenes, the ``run-seedbox.sh`` script will mainly add 2 overrides when enabling VPN on a service:
|
||||
|
||||
* Adds a file in [services/generated/](../services/generated/) which adds a ``network_mode: gluetun`` for your service.
|
||||
* Specify in Traefik rule that the backend host is gluetun instead of the service directly.
|
||||
|
||||
## Make the services communicate with each other
|
||||
|
||||
With docker-compose, all services are in the same Docker network (it is called ``traefik-network`` and is defined [here](../docker-compose.yaml)). Docker provides DNS resolution in the same network based on the name of the services, which act as hostnames.
|
||||
|
||||
So, for example, in order to setup Deluge in Sonarr, just add ``http://deluge:8112`` in the Download Clients settings section in Sonarr.
|
||||
|
||||
⚠️ If you are trying to contact a container which has ``vpn`` flag enabled, you will have to point your config to ``gluetun`` instead, which acts as relay to contact the service. So if Deluge is behind the VPN, add ``http://gluetun:8112`` in Sonarr instead.
|
||||
|
||||
## How does the configuration work?
|
||||
|
||||
Behind the scenes, the ``run-seedbox.sh`` script will parse your ``config.yaml`` file and will generate a Traefik dynamic configuration file, which looks like this:
|
||||
|
||||
```yaml
|
||||
http:
|
||||
routers:
|
||||
deluge-1:
|
||||
rule: 'Host(`deluge.{{ env "TRAEFIK_DOMAIN" }}`)'
|
||||
middlewares:
|
||||
- common-auth@file
|
||||
- redirect-to-https
|
||||
service: deluge-1
|
||||
sonarr-1:
|
||||
rule: 'Host(`sonarr.{{ env "TRAEFIK_DOMAIN" }}`)'
|
||||
middlewares:
|
||||
- common-auth@file
|
||||
- redirect-to-https
|
||||
service: sonarr-1
|
||||
sonarr-2:
|
||||
rule: 'Host(`sonarr-unsecure.{{ env "TRAEFIK_DOMAIN" }}`)'
|
||||
middlewares:
|
||||
- common-auth@file
|
||||
service: sonarr-2
|
||||
entryPoints:
|
||||
- insecure
|
||||
nextcloud:
|
||||
rule: 'Host(`nextcloud.{{ env "TRAEFIK_DOMAIN" }}`)'
|
||||
middlewares:
|
||||
- redirect-to-https
|
||||
service: nextcloud-1
|
||||
services:
|
||||
deluge-1:
|
||||
loadBalancer:
|
||||
servers:
|
||||
# Gluetun is automatically set by run-seedbox.sh (instead of "deluge") because vpn was enabled on this service
|
||||
- url: "http://gluetun:8112"
|
||||
sonarr-1:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "http://sonarr:8989"
|
||||
sonarr-2:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "http://sonarr:8989"
|
||||
nextcloud-1:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "https://nextcloud:443"
|
||||
```
|
||||
|
||||
This file will be automatically placed in [traefik/custom/](../traefik/custom/) directory (mounted by Traefik container) so the config will dynamically apply. This file is updated on each ``run-seedbox.sh`` execution.
|
|
@ -0,0 +1,28 @@
|
|||
# September 2020 - Upgrade to Traefik v2 instructions
|
||||
|
||||
> This guide is useful if you already are using the seedbox but did not update before September 2020.
|
||||
|
||||
Before upgrading Traefik to version 2, please check the following:
|
||||
|
||||
- In this repo, Traefik v2 upgrade is as seamless as possible (same environment variables than before, out-of-the-box config file...).
|
||||
- **First, ``git pull`` to grab the latest code.**
|
||||
- The ``HTTP_PASSWORD`` variable now must be simple-quoted in the .env file. See the updated ``.env.sample`` file (which has also been reorganized)
|
||||
- Run ``init.sh`` in order to create required Docker objects (network name has changed).
|
||||
- You can update your acme.json to a Traefik v2-compliant one by doing the following (before launching Traefik v2):
|
||||
|
||||
```sh
|
||||
mkdir -p /tmp/migration
|
||||
cd /tmp/migration
|
||||
sudo cp /opt/traefik/acme.json .
|
||||
sudo chmod 775 /tmp/migration/acme.json
|
||||
# Do *NOT* forget the --resolver at the end! (le = Let's Encrypt resolver, see traefik/traefik.yml)
|
||||
docker run --rm -v ${PWD}:/data -w /data containous/traefik-migration-tool acme -i acme.json -o acme2.json --resolver le
|
||||
mkdir -p /data/config/traefik
|
||||
sudo cp acme2.json /data/config/traefik/acme.json
|
||||
sudo chmod 600 /data/config/traefik/acme.json
|
||||
# When you already have a backup!
|
||||
sudo rm -rf /opt/traefik /tmp/migration
|
||||
```
|
||||
|
||||
- As from Traefik v2, as Http Authentication is now possible on the Traefik console, the latter is enabled at ``traefik.yourdomain.com``.
|
||||
- After all this, you can simply do: ``./update-all.sh``! Voilà!
|
|
@ -6,21 +6,20 @@ version: "3.8"
|
|||
|
||||
# Common network used by all services
|
||||
networks:
|
||||
default:
|
||||
external:
|
||||
name: "traefik-network"
|
||||
default:
|
||||
name: "traefik-network"
|
||||
|
||||
# Common volumes used by at least 2 services
|
||||
volumes:
|
||||
config:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config
|
||||
mountpoint: $HOST_CONFIG_PATH
|
||||
torrents:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/torrents
|
||||
mountpoint: $HOST_MEDIA_PATH
|
||||
downloads:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/torrents/deluge
|
||||
mountpoint: $HOST_MEDIA_PATH/$DOWNLOAD_SUBFOLDER
|
||||
|
|
|
@ -0,0 +1,286 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# Load common functions
|
||||
source config/tools.sh
|
||||
|
||||
# Check that required tools are installed
|
||||
check_utilities
|
||||
|
||||
SKIP_PULL=0
|
||||
DEBUG=0
|
||||
|
||||
for i in "$@"; do
|
||||
case $i in
|
||||
--no-pull)
|
||||
SKIP_PULL=1
|
||||
;;
|
||||
--debug)
|
||||
DEBUG=1
|
||||
;;
|
||||
*)
|
||||
echo "[$0] ❌ ERROR: unknown parameter \"$i\""
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
cleanup_on_exit() {
|
||||
rm -f rules.props *-vpn.props config.json
|
||||
}
|
||||
trap cleanup_on_exit EXIT
|
||||
|
||||
echo-debug() {
|
||||
if [[ ${DEBUG} == "1" ]]; then echo "$@"; fi
|
||||
}
|
||||
|
||||
###############################################################################################
|
||||
####################################### Load variables ########################################
|
||||
###############################################################################################
|
||||
|
||||
echo "[$0] ***** Checking environment variables and files... *****"
|
||||
|
||||
if [[ ! -f .env ]]; then
|
||||
echo "[$0] ERROR. \".env\" file not found. Please copy \".env.sample\" and edit its values. Then, re-run this script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create/update http_auth file according to values in .env file
|
||||
source .env
|
||||
echo "${HTTP_USER}:${HTTP_PASSWORD}" > traefik/http_auth
|
||||
|
||||
# Docker-compose settings
|
||||
export COMPOSE_HTTP_TIMEOUT=240
|
||||
|
||||
# Retro-compatibility
|
||||
[[ -z $HOST_CONFIG_PATH ]] && export HOST_CONFIG_PATH="/data/config"
|
||||
[[ -z $HOST_MEDIA_PATH ]] && export HOST_MEDIA_PATH="/data/torrents"
|
||||
[[ -z $DOWNLOAD_SUBFOLDER ]] && export DOWNLOAD_SUBFOLDER="deluge"
|
||||
|
||||
if [[ ! -f config.yaml ]]; then
|
||||
echo "[$0] No config.yaml file found. Copying from sample file..."
|
||||
cp config.sample.yaml config.yaml
|
||||
fi
|
||||
|
||||
###############################################################################################
|
||||
###################################### Pre-flight checks ######################################
|
||||
###############################################################################################
|
||||
|
||||
echo "[$0] ***** Checking configuration... *****"
|
||||
|
||||
yq eval -o json config.yaml > config.json
|
||||
|
||||
if [[ ${CHECK_FOR_OUTDATED_CONFIG} == true ]]; then
|
||||
nb_services=$(cat config.json | jq '.services | length')
|
||||
nb_services_sample=$(yq eval -o json config.sample.yaml | jq '.services | length')
|
||||
if [[ $nb_services_sample -gt $nb_services ]]; then
|
||||
echo "[$0] There are more services in the config.sample.yaml than in your config.yaml"
|
||||
echo "[$0] You should check config.sample.yaml because it seems there are new services available for you:"
|
||||
diff -u config.yaml config.sample.yaml | grep "name:" | grep -E "^\+" || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if some services have vpn enabled, that gluetun itself is enabled
|
||||
nb_vpn=$(cat config.json | jq '[.services[] | select(.enabled==true and .vpn==true)] | length')
|
||||
gluetun_enabled=$(cat config.json | jq '[.services[] | select(.name=="gluetun" and .enabled==true)] | length')
|
||||
if [[ ${nb_vpn} -gt 0 && ${gluetun_enabled} == 0 ]]; then
|
||||
echo "[$0] ERROR. ${nb_vpn} VPN-enabled services have been enabled BUT gluetun has not been enabled. Please check your config.yaml file."
|
||||
echo "[$0] ******* Exiting *******"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Determine what host Flood should connect to
|
||||
# => If deluge vpn is enabled => gluetun
|
||||
# => If deluge vpn is disabled => deluge
|
||||
if [[ $(cat config.json | jq '[.services[] | select(.name=="flood" and .enabled==true)] | length') -eq 1 ]]; then
|
||||
# Check that if flood is enabled, deluge should also be enabled
|
||||
if [[ $(cat config.json | jq '[.services[] | select(.name=="deluge" and .enabled==false)] | length') -eq 1 ]]; then
|
||||
echo "[$0] ERROR. Flood is enabled but Deluge is not. Please either enable Deluge or disable Flood as Flood depends on Deluge."
|
||||
echo "[$0] ******* Exiting *******"
|
||||
exit 1
|
||||
fi
|
||||
# Determine deluge hostname (for flood) based on the VPN status (enabled or not) of deluge
|
||||
if [[ $(cat config.json | jq '[.services[] | select(.name=="deluge" and .enabled==true and .vpn==true)] | length') -eq 1 ]]; then
|
||||
export DELUGE_HOST="gluetun"
|
||||
elif [[ $(cat config.json | jq '[.services[] | select(.name=="deluge" and .enabled==true and .vpn==false)] | length') -eq 1 ]]; then
|
||||
export DELUGE_HOST="deluge"
|
||||
fi
|
||||
|
||||
# Specific instructions for Flood
|
||||
# User for Deluge daemon RPC has to be created in deluge auth config file
|
||||
if [[ ! -z ${FLOOD_PASSWORD} && ${FLOOD_AUTOCREATE_USER_IN_DELUGE_DAEMON} == true ]]; then
|
||||
if ! grep -q "flood" $HOST_CONFIG_PATH/deluge/auth; then
|
||||
echo "flood:${FLOOD_PASSWORD}:10" >> $HOST_CONFIG_PATH/deluge/auth
|
||||
else
|
||||
echo "[$0] No need to add user/password for flood as it has already been created."
|
||||
echo "[$0] Consider setting FLOOD_AUTOCREATE_USER_IN_DELUGE_DAEMON variable to false in .env file."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Apply other arbitrary custom Traefik config files
|
||||
rm -f $f traefik/custom/custom-*
|
||||
for f in `find samples/custom-traefik -maxdepth 1 -mindepth 1 -type f | grep -E "\.yml$|\.yaml$" | sort`; do
|
||||
echo "[$0] Applying custom Traefik config $f..."
|
||||
cp $f traefik/custom/custom-$(basename $f)
|
||||
done
|
||||
|
||||
# Detect Synology devices for Netdata compatibility
|
||||
if [[ $(cat config.json | jq '[.services[] | select(.name=="netdata" and .enabled==true)] | length') -eq 1 ]]; then
|
||||
if [[ $(uname -a | { grep synology || true; } | wc -l) -eq 1 ]]; then
|
||||
export OS_RELEASE_FILEPATH="/etc/VERSION"
|
||||
else
|
||||
export OS_RELEASE_FILEPATH="/etc/os-release"
|
||||
fi
|
||||
fi
|
||||
|
||||
###############################################################################################
|
||||
####################################### SERVICES PARSING ######################################
|
||||
###############################################################################################
|
||||
|
||||
echo "[$0] ***** Generating configuration... *****"
|
||||
|
||||
# Cleanup files before start, in case there was a change we start from scratch at every script execution
|
||||
rm -f services/generated/*-vpn.yaml
|
||||
|
||||
ALL_SERVICES="-f docker-compose.yaml"
|
||||
|
||||
# Parse the config.yaml master configuration file
|
||||
for json in $(yq eval -o json config.yaml | jq -c ".services[]"); do
|
||||
name=$(echo $json | jq -r .name)
|
||||
enabled=$(echo $json | jq -r .enabled)
|
||||
vpn=$(echo $json | jq -r .vpn)
|
||||
|
||||
# Skip disabled services
|
||||
if [[ ${enabled} == "false" ]]; then
|
||||
echo-debug "[$0] Service $name is disabled. Skipping it."
|
||||
continue
|
||||
fi
|
||||
|
||||
echo-debug "[$0] ➡️ Parsing service: \"$name\"..."
|
||||
|
||||
# Default docker-compose filename is the service name + .yaml.
|
||||
# Take into account explicit filename if specified in config
|
||||
customFile=$(echo $json | jq -r .customFile)
|
||||
file="$name.yaml"
|
||||
if [[ ${customFile} != "null" ]]; then
|
||||
file=${customFile}
|
||||
fi
|
||||
echo-debug "[$0] File: \"$file\"..."
|
||||
|
||||
# Append $file to global list of files which will be passed to docker commands
|
||||
ALL_SERVICES="${ALL_SERVICES} -f services/${file}"
|
||||
|
||||
# For services with VPN enabled, add a docker-compose "override" file specifying that the service network should
|
||||
# go through gluetun (main vpn client service).
|
||||
if [[ ${vpn} == "true" ]]; then
|
||||
echo "services.${name}.network_mode: service:gluetun" > ${name}-vpn.props
|
||||
yq -p=props ${name}-vpn.props > services/generated/${name}-vpn.yaml
|
||||
rm -f ${name}-vpn.props
|
||||
# Append config/${name}-vpn.yaml to global list of files which will be passed to docker commands
|
||||
ALL_SERVICES="${ALL_SERVICES} -f services/generated/${name}-vpn.yaml"
|
||||
fi
|
||||
|
||||
###################################### TRAEFIK RULES ######################################
|
||||
|
||||
# Skip this part for services which have Traefik rules disabled in config
|
||||
traefikEnabled=$(echo $json | jq -r .traefik.enabled)
|
||||
if [[ ${traefikEnabled} == "false" ]]; then
|
||||
echo-debug "[$0] Traefik is disabled. Skipping rules creation..."
|
||||
continue
|
||||
fi
|
||||
|
||||
# Loop over all Traefik rules and create the corresponding entries in the generated rules.yaml
|
||||
echo-debug "[$0] Generating Traefik rules..."
|
||||
i=0
|
||||
for rule in $(echo $json | jq -c .traefik.rules[]); do
|
||||
((i=i+1))
|
||||
host=$(echo $rule | jq -r .host)
|
||||
internalPort=$(echo $rule | jq -r .internalPort)
|
||||
httpAuth=$(echo $rule | jq -r .httpAuth)
|
||||
echo-debug "[$0] Host => ${host}"
|
||||
echo-debug "[$0] Internal Port => ${internalPort}"
|
||||
echo-debug "[$0] Http Authentication => ${httpAuth}"
|
||||
|
||||
# If VPN => Traefik rule should redirect to gluetun container
|
||||
backendHost=${name}
|
||||
[[ ${vpn} == "true" ]] && backendHost="gluetun"
|
||||
|
||||
# Handle custom scheme (default if non-specified is http)
|
||||
internalScheme="http"
|
||||
customInternalScheme=$(echo $rule | jq -r .internalScheme)
|
||||
[[ ${customInternalScheme} != "null" ]] && internalScheme=${customInternalScheme}
|
||||
|
||||
# Transform the bash syntax into Traefik/go one => anything.${TRAEFIK_DOMAIN} to anything.{{ env "TRAEFIK_DOMAIN" }}
|
||||
hostTraefik=$(echo ${host} | sed --regexp-extended 's/^(.*)(\$\{(.*)\})/\1\{\{ env "\3" \}\}/')
|
||||
|
||||
ruleId="${name}-${i}"
|
||||
echo 'http.routers.'"${ruleId}"'.rule: Host(`'${hostTraefik}'`)' >> rules.props
|
||||
|
||||
middlewareCount=0
|
||||
if [[ ${httpAuth} == "true" ]]; then
|
||||
echo "http.routers.${ruleId}.middlewares.${middlewareCount}: common-auth@file" >> rules.props
|
||||
((middlewareCount=middlewareCount+1))
|
||||
fi
|
||||
|
||||
traefikService=$(echo $rule | jq -r .service)
|
||||
if [[ ${traefikService} != "null" ]]; then
|
||||
echo "http.routers.${ruleId}.service: ${traefikService}" >> rules.props
|
||||
else
|
||||
echo "http.routers.${ruleId}.service: ${ruleId}" >> rules.props
|
||||
fi
|
||||
|
||||
# Check if httpOnly flag is enabled
|
||||
# If enabled => Specify to use only "insecure" (port 80) entrypoint
|
||||
# If not => use all entryPoints (by not specifying any) but force redirection to https
|
||||
httpOnly=$(echo $rule | jq -r .httpOnly)
|
||||
if [[ ${httpOnly} == true ]]; then
|
||||
echo "http.routers.${ruleId}.entryPoints.0: insecure" >> rules.props
|
||||
else
|
||||
echo "http.routers.${ruleId}.middlewares.${middlewareCount}: redirect-to-https" >> rules.props
|
||||
((middlewareCount=middlewareCount+1))
|
||||
fi
|
||||
|
||||
# If the specified service does not contain a "@" => we create it
|
||||
# If the service has a @, it means it is defined elsewhere so we do not create it (custom file, @internal...)
|
||||
if echo ${traefikService} | grep -vq "@"; then
|
||||
echo "http.services.${ruleId}.loadBalancer.servers.0.url: ${internalScheme}://${backendHost}:${internalPort}" >> rules.props
|
||||
fi
|
||||
|
||||
done
|
||||
done
|
||||
|
||||
# Convert properties files into Traefik-ready YAML and place it in the correct folder loaded by Traefik
|
||||
mv traefik/custom/dynamic-rules.yaml traefik/custom/dynamic-rules-old.yaml || true
|
||||
yq -p=props rules.props > traefik/custom/dynamic-rules.yaml
|
||||
rm -f rules.props
|
||||
|
||||
# Post-transformations on the rules file
|
||||
# sed -i "s/EMPTYMAP/{}/g" traefik/custom/dynamic-rules.yaml
|
||||
# Add simple quotes around Host rule
|
||||
sed -i --regexp-extended "s/^(.*: )(Host.*$)/\1'\2'/g" traefik/custom/dynamic-rules.yaml
|
||||
# Add double quotes around the backend traefik service
|
||||
sed -i --regexp-extended "s/^(.*url: )(.*$)/\1\"\2\"/g" traefik/custom/dynamic-rules.yaml
|
||||
|
||||
rm -f traefik/custom/dynamic-rules-old.yaml
|
||||
|
||||
echo-debug "[$0] Here is the list of all files which are going to be processed: ${ALL_SERVICES}"
|
||||
|
||||
echo "[$0] ***** Config OK. Launching services... *****"
|
||||
|
||||
if [[ "${SKIP_PULL}" != "1" ]]; then
|
||||
echo "[$0] ***** Pulling all images... *****"
|
||||
docker-compose ${ALL_SERVICES} pull
|
||||
fi
|
||||
|
||||
echo "[$0] ***** Recreating containers if required... *****"
|
||||
docker-compose ${ALL_SERVICES} up -d --remove-orphans
|
||||
echo "[$0] ***** Done updating containers *****"
|
||||
|
||||
echo "[$0] ***** Clean unused images and volumes... *****"
|
||||
docker image prune -af
|
||||
docker volume prune -f
|
||||
|
||||
echo "[$0] ***** Done! *****"
|
||||
exit 0
|
|
@ -0,0 +1,3 @@
|
|||
# Custom Traefik config files
|
||||
|
||||
Place in this directory any custom Traefik config file, they will be copied to Traefik folder when running ``run-seedbox.sh`` script.
|
|
@ -1,19 +0,0 @@
|
|||
deluge: enable
|
||||
flood: enable
|
||||
plex: enable
|
||||
flaresolverr: enable
|
||||
jackett: enable
|
||||
prowlarr: enable
|
||||
sonarr: enable
|
||||
radarr: enable
|
||||
bazarr: enable
|
||||
lidarr: enable
|
||||
ombi: disable
|
||||
overseerr: enable
|
||||
tautulli: enable
|
||||
jdownloader: enable
|
||||
tdarr: enable
|
||||
nextcloud: enable
|
||||
portainer: enable
|
||||
netdata: enable
|
||||
duplicati: enable
|
|
@ -10,13 +10,9 @@ services:
|
|||
- PGID=${PGID}
|
||||
- PUID=${PUID}
|
||||
- TZ=${TZ}
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.bazarr.rule=Host(`bazarr.${TRAEFIK_DOMAIN}`)"
|
||||
- "traefik.http.routers.bazarr.middlewares=common-auth@file"
|
||||
|
||||
volumes:
|
||||
configbazarr:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/bazarr
|
||||
mountpoint: $HOST_CONFIG_PATH/bazarr
|
|
@ -0,0 +1,4 @@
|
|||
# Services custom folder
|
||||
|
||||
Here, you can place all custom docker-compose files (yaml format) which will be specified in your ``config.yaml``.
|
||||
All YAML files placed here are ignored in .gitignore.
|
|
@ -11,13 +11,9 @@ services:
|
|||
- PGID=${PGID}
|
||||
- PUID=${PUID}
|
||||
- TZ=${TZ}
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.deluge.rule=Host(`deluge.${TRAEFIK_DOMAIN}`)"
|
||||
- "traefik.http.routers.deluge.middlewares=common-auth@file"
|
||||
|
||||
volumes:
|
||||
configdeluge:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/deluge
|
||||
mountpoint: $HOST_CONFIG_PATH/deluge
|
|
@ -10,22 +10,14 @@ services:
|
|||
volumes:
|
||||
- configduplicati:/config
|
||||
- backups:/backups
|
||||
- alldata:/source
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.duplicati.rule=Host(`duplicati.${TRAEFIK_DOMAIN}`)"
|
||||
- "traefik.http.routers.duplicati.middlewares=common-auth@file"
|
||||
- config:/source
|
||||
|
||||
volumes:
|
||||
alldata:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data
|
||||
configduplicati:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/duplicati
|
||||
mountpoint: $HOST_CONFIG_PATH/duplicati
|
||||
backups:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/backups
|
||||
mountpoint: $HOST_CONFIG_PATH/backups
|
|
@ -8,7 +8,7 @@ services:
|
|||
user: ${PUID}:${PGID}
|
||||
command:
|
||||
- --auth=none
|
||||
- --dehost=deluge
|
||||
- --dehost=${DELUGE_HOST}
|
||||
- --deport=58846
|
||||
- --deuser=flood
|
||||
- --depass=${FLOOD_PASSWORD}
|
||||
|
@ -18,15 +18,9 @@ services:
|
|||
- torrents:/torrents
|
||||
- downloads:/downloads
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.flood.rule=Host(`flood.${TRAEFIK_DOMAIN}`)"
|
||||
- "traefik.http.routers.flood.middlewares=common-auth@file"
|
||||
- "traefik.http.routers.flood.service=flood-service"
|
||||
- "traefik.http.services.flood-service.loadbalancer.server.port=3000"
|
||||
|
||||
volumes:
|
||||
configflood:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/flood
|
||||
mountpoint: $HOST_CONFIG_PATH/flood
|
|
@ -0,0 +1,3 @@
|
|||
# Generated files
|
||||
|
||||
This directory contains all generated overrides files. They are in .gitignore so there should be no conflict when running ``git pull``.
|
|
@ -0,0 +1,25 @@
|
|||
services:
|
||||
gluetun:
|
||||
image: qmcgaw/gluetun
|
||||
container_name: gluetun
|
||||
restart: always
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
environment:
|
||||
- PUID=${PUID}
|
||||
- PGIDq=${PGID}
|
||||
- TZ=${TZ}
|
||||
- VPNSP=custom
|
||||
- VPN_TYPE=wireguard
|
||||
# For Wireguard
|
||||
- VPN_ENDPOINT_IP=${WIREGUARD_ENDPOINT}
|
||||
- VPN_ENDPOINT_PORT=${WIREGUARD_PORT}
|
||||
- WIREGUARD_PUBLIC_KEY=${WIREGUARD_PUBLIC_KEY}
|
||||
- WIREGUARD_PRIVATE_KEY=${WIREGUARD_PRIVATE_KEY}
|
||||
- WIREGUARD_ADDRESS=${WIREGUARD_ADDRESS}
|
||||
|
||||
volumes:
|
||||
configgluetun:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: $HOST_CONFIG_PATH/gluetun
|
|
@ -0,0 +1,17 @@
|
|||
services:
|
||||
heimdall:
|
||||
image: lscr.io/linuxserver/heimdall
|
||||
container_name: heimdall
|
||||
restart: always
|
||||
volumes:
|
||||
- configheimdall:/config
|
||||
environment:
|
||||
- PGID=${PGID}
|
||||
- PUID=${PUID}
|
||||
- TZ=${TZ}
|
||||
|
||||
volumes:
|
||||
configheimdall:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: $HOST_CONFIG_PATH/heimdall
|
|
@ -12,7 +12,3 @@ services:
|
|||
- PUID=${PUID}
|
||||
- TZ=${TZ}
|
||||
- RUN_OPTS='-FlareSolverrURL="http://flaresolverr:8191"'
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.jackett.rule=Host(`jackett.${TRAEFIK_DOMAIN}`)"
|
||||
- "traefik.http.routers.jackett.middlewares=common-auth@file"
|
||||
|
|
|
@ -10,14 +10,9 @@ services:
|
|||
- USER_ID=${PUID}
|
||||
- GROUP_ID=${PGID}
|
||||
- TZ=${TZ}
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.services.jdownloader-seedbox.loadbalancer.server.port=5800"
|
||||
- "traefik.http.routers.jdownloader.rule=Host(`jdownloader.${TRAEFIK_DOMAIN}`)"
|
||||
- "traefik.http.routers.jdownloader.middlewares=common-auth@file"
|
||||
|
||||
volumes:
|
||||
configjdownloader:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/jdownloader
|
||||
mountpoint: $HOST_CONFIG_PATH/jdownloader
|
|
@ -0,0 +1,19 @@
|
|||
services:
|
||||
kavita:
|
||||
image: kizaing/kavita:latest
|
||||
container_name: kavita
|
||||
restart: always
|
||||
volumes:
|
||||
- configkavita:/kavita/config
|
||||
- torrents:/torrents
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
environment:
|
||||
- TZ=${TZ}
|
||||
# Wait for https://github.com/Kareadita/Kavita/issues/301 to be resolved
|
||||
#user: "${PUID}:${PGID}"
|
||||
|
||||
volumes:
|
||||
configkavita:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: $HOST_CONFIG_PATH/kavita
|
|
@ -0,0 +1,18 @@
|
|||
services:
|
||||
komga:
|
||||
image: gotson/komga
|
||||
container_name: komga
|
||||
restart: always
|
||||
volumes:
|
||||
- configkomga:/config
|
||||
- torrents:/torrents
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
environment:
|
||||
- TZ=${TZ}
|
||||
user: "${PUID}:${PGID}"
|
||||
|
||||
volumes:
|
||||
configkomga:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: $HOST_CONFIG_PATH/komga
|
|
@ -10,13 +10,9 @@ services:
|
|||
- PGID=${PGID}
|
||||
- PUID=${PUID}
|
||||
- TZ=${TZ}
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.lidarr.rule=Host(`lidarr.${TRAEFIK_DOMAIN}`)"
|
||||
- "traefik.http.routers.lidarr.middlewares=common-auth@file"
|
||||
|
||||
volumes:
|
||||
configlidarr:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/lidarr
|
||||
mountpoint: $HOST_CONFIG_PATH/lidarr
|
|
@ -15,9 +15,5 @@ services:
|
|||
- /sys:/host/sys:ro
|
||||
- /etc/passwd:/host/etc/passwd:ro
|
||||
- /etc/group:/host/etc/group:ro
|
||||
- /etc/os-release:/host/etc/os-release:ro
|
||||
- ${OS_RELEASE_FILEPATH}:/host/etc/os-release:ro
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.netdata.rule=Host(`netdata.${TRAEFIK_DOMAIN}`)"
|
||||
- "traefik.http.routers.netdata.middlewares=common-auth@file"
|
|
@ -3,6 +3,7 @@ services:
|
|||
image: mariadb:10
|
||||
container_name: nextcloud-db
|
||||
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --innodb-file-per-table=1 --skip-innodb-read-only-compressed
|
||||
user: ${PUID}:${PGID}
|
||||
restart: always
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
|
||||
|
@ -31,22 +32,17 @@ services:
|
|||
- nextclouddata:/data
|
||||
- torrents:/torrents
|
||||
- config:/seedbox-config
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.nextcloud.rule=Host(`nextcloud.${TRAEFIK_DOMAIN}`)"
|
||||
- "traefik.http.services.nextcloud-seedbox.loadbalancer.server.scheme=https"
|
||||
- "traefik.http.services.nextcloud-seedbox.loadbalancer.server.port=443"
|
||||
|
||||
volumes:
|
||||
nextclouddb:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/nextcloud-db
|
||||
mountpoint: $HOST_CONFIG_PATH/nextcloud-db
|
||||
confignextcloud:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/nextcloud
|
||||
mountpoint: $HOST_CONFIG_PATH/nextcloud
|
||||
nextclouddata:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/nextcloud-data
|
||||
mountpoint: $HOST_CONFIG_PATH/nextcloud-data
|
|
@ -10,13 +10,9 @@ services:
|
|||
- PUID=${PUID}
|
||||
- TZ=${TZ}
|
||||
- BASE_URL=/
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.ombi.rule=Host(`ombi.${TRAEFIK_DOMAIN}`)"
|
||||
#- "traefik.http.routers.ombi.middlewares=common-auth@file"
|
||||
|
||||
volumes:
|
||||
configombi:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/ombi
|
||||
mountpoint: $HOST_CONFIG_PATH/ombi
|
|
@ -9,12 +9,9 @@ services:
|
|||
- PGID=${PGID}
|
||||
- PUID=${PUID}
|
||||
- TZ=${TZ}
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.overseerr.rule=Host(`overseerr.${TRAEFIK_DOMAIN}`)"
|
||||
|
||||
volumes:
|
||||
configoverseerr:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/overseerr
|
||||
mountpoint: $HOST_CONFIG_PATH/overseerr
|
|
@ -0,0 +1,27 @@
|
|||
services:
|
||||
plex:
|
||||
image: ghcr.io/linuxserver/plex
|
||||
container_name: plex
|
||||
restart: always
|
||||
ports:
|
||||
- "32400:32400"
|
||||
- "32400:32400/udp"
|
||||
- "32469:32469"
|
||||
- "32469:32469/udp"
|
||||
devices:
|
||||
- /dev/dri:/dev/dri # for hardware transcoding
|
||||
volumes:
|
||||
- configplex:/config
|
||||
- torrents:/torrents
|
||||
- /dev/shm:/transcode
|
||||
environment:
|
||||
- PGID=${PGID}
|
||||
- PUID=${PUID}
|
||||
- TZ=${TZ}
|
||||
- VERSION=latest
|
||||
|
||||
volumes:
|
||||
configplex:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: $HOST_CONFIG_PATH/Plex
|
|
@ -8,8 +8,6 @@ services:
|
|||
- "32400:32400/udp"
|
||||
- "32469:32469"
|
||||
- "32469:32469/udp"
|
||||
- "5353:5353/udp"
|
||||
- "1900:1900/udp"
|
||||
volumes:
|
||||
- configplex:/config
|
||||
- torrents:/torrents
|
||||
|
@ -18,13 +16,9 @@ services:
|
|||
- PUID=${PUID}
|
||||
- TZ=${TZ}
|
||||
- VERSION=latest
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.services.plex-seedbox.loadbalancer.server.port=32400"
|
||||
- "traefik.http.routers.plex.rule=Host(`plex.${TRAEFIK_DOMAIN}`)"
|
||||
|
||||
volumes:
|
||||
configplex:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/Plex
|
||||
mountpoint: $HOST_CONFIG_PATH/Plex
|
|
@ -5,8 +5,4 @@ services:
|
|||
restart: always
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
command: --admin-password ${PORTAINER_ADMIN_PASSWORD} --host=unix:///var/run/docker.sock
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.portainer.rule=Host(`portainer.${TRAEFIK_DOMAIN}`)"
|
||||
- "traefik.http.services.portainer-seedbox.loadbalancer.server.port=9000"
|
||||
command: --admin-password ${PORTAINER_ADMIN_PASSWORD} --host=unix:///var/run/docker.sock
|
|
@ -9,13 +9,9 @@ services:
|
|||
- PGID=${PGID}
|
||||
- PUID=${PUID}
|
||||
- TZ=${TZ}
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.prowlarr.rule=Host(`prowlarr.${TRAEFIK_DOMAIN}`)"
|
||||
- "traefik.http.routers.prowlarr.middlewares=common-auth@file"
|
||||
|
||||
volumes:
|
||||
configprowlarr:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/prowlarr
|
||||
mountpoint: $HOST_CONFIG_PATH/prowlarr
|
|
@ -11,13 +11,9 @@ services:
|
|||
- PGID=${PGID}
|
||||
- PUID=${PUID}
|
||||
- TZ=${TZ}
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.radarr.rule=Host(`radarr.${TRAEFIK_DOMAIN}`)"
|
||||
- "traefik.http.routers.radarr.middlewares=common-auth@file"
|
||||
|
||||
volumes:
|
||||
configradarr:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/radarr
|
||||
mountpoint: $HOST_CONFIG_PATH/radarr
|
|
@ -0,0 +1,19 @@
|
|||
services:
|
||||
readarr:
|
||||
image: lscr.io/linuxserver/readarr:nightly
|
||||
container_name: readarr
|
||||
restart: always
|
||||
volumes:
|
||||
- configreadarr:/config
|
||||
- torrents:/torrents
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
environment:
|
||||
- PGID=${PGID}
|
||||
- PUID=${PUID}
|
||||
- TZ=${TZ}
|
||||
|
||||
volumes:
|
||||
configreadarr:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: $HOST_CONFIG_PATH/readarr
|
|
@ -11,13 +11,9 @@ services:
|
|||
- PGID=${PGID}
|
||||
- PUID=${PUID}
|
||||
- TZ=${TZ}
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.sonarr.rule=Host(`sonarr.${TRAEFIK_DOMAIN}`)"
|
||||
- "traefik.http.routers.sonarr.middlewares=common-auth@file"
|
||||
|
||||
volumes:
|
||||
configsonarr:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/sonarr
|
||||
mountpoint: $HOST_CONFIG_PATH/sonarr
|
|
@ -0,0 +1,24 @@
|
|||
services:
|
||||
syncthing:
|
||||
image: lscr.io/linuxserver/syncthing
|
||||
container_name: syncthing
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- PGID=${PGID}
|
||||
- PUID=${PUID}
|
||||
- TZ=${TZ}
|
||||
volumes:
|
||||
- configsyncthing:/config
|
||||
- torrents:/torrents
|
||||
- config:/allconfig
|
||||
ports:
|
||||
# #- 8384:8384
|
||||
- 22000:22000/tcp
|
||||
- 22000:22000/udp
|
||||
- 21027:21027/udp
|
||||
|
||||
volumes:
|
||||
configsyncthing:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: $HOST_CONFIG_PATH/configsyncthing
|
|
@ -10,12 +10,9 @@ services:
|
|||
- PGID=${PGID}
|
||||
- PUID=${PUID}
|
||||
- TZ=${TZ}
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.tautulli.rule=Host(`tautulli.${TRAEFIK_DOMAIN}`)"
|
||||
|
||||
volumes:
|
||||
configtautulli:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/tautulli
|
||||
mountpoint: $HOST_CONFIG_PATH/tautulli
|
|
@ -15,11 +15,6 @@ services:
|
|||
- transcodes:/temp
|
||||
- configtdarrv2:/app/server
|
||||
- settingstdarrv2:/app/configs
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.services.tdarrv2-seedbox.loadbalancer.server.port=8265"
|
||||
- "traefik.http.routers.tdarrv2.rule=Host(`tdarr.${TRAEFIK_DOMAIN}`)"
|
||||
- "traefik.http.routers.tdarrv2.middlewares=common-auth@file"
|
||||
|
||||
tdarr_node:
|
||||
image: haveagitgat/tdarr_node:latest
|
||||
|
@ -45,12 +40,12 @@ volumes:
|
|||
configtdarrv2:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/tdarrv2/server
|
||||
mountpoint: $HOST_CONFIG_PATH/tdarrv2/server
|
||||
settingstdarrv2:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/tdarrv2/configs
|
||||
mountpoint: $HOST_CONFIG_PATH/tdarrv2/configs
|
||||
transcodes:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/tdarrv2/transcodes
|
||||
mountpoint: $HOST_CONFIG_PATH/tdarrv2/transcodes
|
|
@ -16,15 +16,9 @@ services:
|
|||
environment:
|
||||
- TRAEFIK_DOMAIN=${TRAEFIK_DOMAIN}
|
||||
- TZ=${TZ}
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
# Docker labels for enabling Traefik dashboard
|
||||
- "traefik.http.routers.traefik.rule=Host(`traefik.${TRAEFIK_DOMAIN}`)"
|
||||
- "traefik.http.routers.traefik.service=api@internal"
|
||||
- "traefik.http.routers.traefik.middlewares=common-auth@file"
|
||||
|
||||
volumes:
|
||||
configtraefik:
|
||||
driver: local-persist
|
||||
driver_opts:
|
||||
mountpoint: /data/config/traefik
|
||||
mountpoint: $HOST_CONFIG_PATH/traefik
|
|
@ -25,7 +25,7 @@ find $1 -maxdepth 10 -type f | grep -v -E "\.webm$|\.flv$|\.vob$|\.ogg$|\.ogv$|\
|
|||
while true; do
|
||||
read -p "[$0] Do you want to REMOVE these files?" yn
|
||||
case $yn in
|
||||
[Yy]* ) find $1 -maxdepth 10 -type f | grep -v -E "\.webm$|\.flv$|\.vob$|\.ogg$|\.ogv$|\.drc$|\.gifv$|\.mng$|\.avi$|\.mov$|\.qt$|\.wmv$|\.yuv$|\.rm$|\.rmvb$|/.asf$|\.amv$|\.mp4$|\.m4v$|\.mp*$|\.m?v$|\.svi$|\.3gp$|\.flv$|\.f4v$" | xargs rm -f; break;;
|
||||
[Yy]* ) find $1 -maxdepth 10 -type f | grep -v -E "\.webm$|\.flv$|\.vob$|\.ogg$|\.ogv$|\.drc$|\.gifv$|\.mng$|\.avi$|\.mov$|\.qt$|\.wmv$|\.yuv$|\.rm$|\.rmvb$|/.asf$|\.amv$|\.mp4$|\.m4v$|\.mp*$|\.m?v$|\.svi$|\.3gp$|\.flv$|\.f4v$" | xargs -0 rm -f; break;;
|
||||
[Nn]* ) echo "[$0] Skipping this part. Continuing...";;
|
||||
* ) echo "[$0] Please answer yes or no.";;
|
||||
esac
|
||||
|
|
|
@ -15,3 +15,7 @@ http:
|
|||
frameDeny: true
|
||||
contentTypeNosniff: true
|
||||
browserXssFilter: true
|
||||
redirect-to-https:
|
||||
redirectScheme:
|
||||
scheme: https
|
||||
permanent: false
|
||||
|
|
|
@ -2,10 +2,10 @@ api:
|
|||
dashboard: true
|
||||
|
||||
# Set Access logs timezone
|
||||
accessLog:
|
||||
fields:
|
||||
names:
|
||||
StartUTC: drop
|
||||
# accessLog:
|
||||
# fields:
|
||||
# names:
|
||||
# StartUTC: drop
|
||||
|
||||
providers:
|
||||
docker:
|
||||
|
@ -19,11 +19,11 @@ providers:
|
|||
entryPoints:
|
||||
insecure:
|
||||
address: ":80"
|
||||
http:
|
||||
redirections:
|
||||
entryPoint:
|
||||
to: secure
|
||||
scheme: https
|
||||
# http:
|
||||
# redirections:
|
||||
# entryPoint:
|
||||
# to: secure
|
||||
# scheme: https
|
||||
secure:
|
||||
address: ":443"
|
||||
http:
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
SKIP_PULL=0
|
||||
|
||||
for i in "$@"; do
|
||||
case $i in
|
||||
--no-pull)
|
||||
SKIP_PULL=1
|
||||
;;
|
||||
*)
|
||||
echo "[$0] ❌ ERROR: unknown parameter \"$i\""
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Create/update http_auth file according to values in .env file
|
||||
source .env
|
||||
echo "${HTTP_USER}:${HTTP_PASSWORD}" > traefik/http_auth
|
||||
|
||||
# Docker-compose settings
|
||||
export COMPOSE_HTTP_TIMEOUT=240
|
||||
|
||||
if [[ ! -f services.conf ]]; then
|
||||
echo "[$0] No services.conf file found. Copying from sample file..."
|
||||
cp services.conf.sample services.conf
|
||||
fi
|
||||
|
||||
# Alert in case new services have been added (or removed) in sample but active file has not changed
|
||||
NB_SERVICES_ACTIVE=$(cat services.conf | wc -l)
|
||||
NB_SERVICES_ORIG=$(cat services.conf.sample | wc -l)
|
||||
if [[ ${NB_SERVICES_ACTIVE} != ${NB_SERVICES_ORIG} ]]; then
|
||||
echo "[$0] Your services.conf file seems outdated. It appears there are new services available, or services that have been removed."
|
||||
diff -yt services.conf services.conf.sample
|
||||
fi
|
||||
|
||||
# Fetch all YAML files
|
||||
disabled_pattern=""
|
||||
while read -r line ; do
|
||||
disabled_pattern="${disabled_pattern} ! -name $line.yaml"
|
||||
done < <(grep "disable" services.conf | awk -F : '{print $1}' )
|
||||
|
||||
SERVICES=$(find services -mindepth 1 -maxdepth 1 -name "*.yaml" ${disabled_pattern} | sed -e 's/^/-f /')
|
||||
ALL_SERVICES="-f docker-compose.yaml $SERVICES"
|
||||
|
||||
# Specific instructions for Flood
|
||||
# User for Deluge daemon RPC has to be created in deluge auth config file
|
||||
if [[ ! -z ${FLOOD_PASSWORD} && ${FLOOD_AUTOCREATE_USER_IN_DELUGE_DAEMON} == true ]]; then
|
||||
if ! grep -q "flood" /data/config/deluge/auth; then
|
||||
echo "flood:${FLOOD_PASSWORD}:10" >> /data/config/deluge/auth
|
||||
else
|
||||
echo "[$0] No need to add user/password for flood as it has already been created."
|
||||
echo "[$0] Consider setting FLOOD_AUTOCREATE_USER_IN_DELUGE_DAEMON variable to false in .env file."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${SKIP_PULL}" != "1" ]]; then
|
||||
echo "[$0] ***** Pulling all images... *****"
|
||||
docker-compose ${ALL_SERVICES} pull
|
||||
fi
|
||||
|
||||
echo "[$0] ***** Recreating containers if required... *****"
|
||||
docker-compose ${ALL_SERVICES} up -d --remove-orphans
|
||||
echo "[$0] ***** Done updating containers *****"
|
||||
echo "[$0] ***** Clean unused images and volumes... *****"
|
||||
docker image prune -af
|
||||
docker volume prune -f
|
||||
echo "[$0] ***** Done! *****"
|
||||
exit 0
|
Loading…
Reference in New Issue