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
|
# General Traefik (reverse proxy) settings
|
||||||
TRAEFIK_DOMAIN=mydomain.com
|
TRAEFIK_DOMAIN=mydomain.com
|
||||||
ACME_MAIL=my-email@my-provider.com
|
ACME_MAIL=my-email@my-provider.com
|
||||||
|
@ -10,7 +13,11 @@ TZ="Europe/Paris"
|
||||||
HTTP_USER=myuser
|
HTTP_USER=myuser
|
||||||
HTTP_PASSWORD='mypassword_encoded' # Keep these simple quotes!
|
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
|
PGID=1000
|
||||||
PUID=1000
|
PUID=1000
|
||||||
|
|
||||||
|
@ -29,4 +36,11 @@ PORTAINER_ADMIN_PASSWORD=h4ckMePleAse
|
||||||
|
|
||||||
# Flood username declared in deluge rpc daemon
|
# Flood username declared in deluge rpc daemon
|
||||||
FLOOD_PASSWORD=myfloodpassword
|
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
|
.DS_Store
|
||||||
|
|
||||||
/config
|
|
||||||
**/tunnel-options.sh
|
**/tunnel-options.sh
|
||||||
**/.env
|
**/.env
|
||||||
**/traefik/http_auth
|
**/traefik/http_auth
|
||||||
backup/
|
backup/
|
||||||
services.conf
|
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
|
## ✨ Features
|
||||||
seedbox and personal media server.
|
|
||||||
|
|
||||||
## 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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|
|
| 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 |
|
| 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 | 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|
|
| 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 |
|
| 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 |
|
| 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
|
## 🌐 Traefik
|
||||||
(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
|
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.
|
||||||
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.
|
Traefik takes care of valid Let's Encrypt certificates and auto-renewal.
|
||||||
|
|
||||||
Note: Plex is also available directly through the `32400` port without going
|
Note: Plex is also available directly through the `32400` port without going through the reverse proxy.
|
||||||
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...).
|
### Dependencies
|
||||||
- **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
|
|
||||||
|
|
||||||
- [Docker](https://github.com/docker/docker) >= 20.10
|
- [Docker](https://github.com/docker/docker) >= 20.10
|
||||||
- [Docker Compose](https://github.com/docker/compose) >= 1.28.0
|
- [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 16.04.
|
- [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:
|
Before running, please create the volumes which will be statically mapped to the ones on the host:
|
||||||
|
For example:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo su -c "mkdir /data && mkdir /data/config && mkdir /data/torrents"
|
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.
|
Edit the `.env` file and change the variables as desired.
|
||||||
The variables are all self-explanatory.
|
The variables are all self-explanatory.
|
||||||
|
|
||||||
**NEW**
|
### Review the configuration
|
||||||
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.
|
|
||||||
|
|
||||||
## 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
|
```sh
|
||||||
./update-all.sh
|
./run-seedbox.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
docker-compose should manage all the volumes and network setup for you. If it
|
All services and synamic configuration will be automatically created without further action from your part.
|
||||||
does not, verify that your docker and docker-compose version is updated.
|
|
||||||
|
|
||||||
Make sure you install the dependencies and finish configuration before doing
|
Make sure you install the dependencies and finish configuration before doing this.
|
||||||
this.
|
|
||||||
|
|
||||||
## PlexPass
|
### Where is my data?
|
||||||
|
|
||||||
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?
|
|
||||||
|
|
||||||
All data is saved in the docker volumes `seedbox_config` or
|
All data is saved in the docker volumes `seedbox_config` or
|
||||||
`seedbox_torrents`.
|
`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
|
# Common network used by all services
|
||||||
networks:
|
networks:
|
||||||
default:
|
default:
|
||||||
external:
|
name: "traefik-network"
|
||||||
name: "traefik-network"
|
|
||||||
|
|
||||||
# Common volumes used by at least 2 services
|
# Common volumes used by at least 2 services
|
||||||
volumes:
|
volumes:
|
||||||
config:
|
config:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
driver_opts:
|
||||||
mountpoint: /data/config
|
mountpoint: $HOST_CONFIG_PATH
|
||||||
torrents:
|
torrents:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
driver_opts:
|
||||||
mountpoint: /data/torrents
|
mountpoint: $HOST_MEDIA_PATH
|
||||||
downloads:
|
downloads:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
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}
|
- PGID=${PGID}
|
||||||
- PUID=${PUID}
|
- PUID=${PUID}
|
||||||
- TZ=${TZ}
|
- TZ=${TZ}
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.bazarr.rule=Host(`bazarr.${TRAEFIK_DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.bazarr.middlewares=common-auth@file"
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
configbazarr:
|
configbazarr:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
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}
|
- PGID=${PGID}
|
||||||
- PUID=${PUID}
|
- PUID=${PUID}
|
||||||
- TZ=${TZ}
|
- TZ=${TZ}
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.deluge.rule=Host(`deluge.${TRAEFIK_DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.deluge.middlewares=common-auth@file"
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
configdeluge:
|
configdeluge:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
driver_opts:
|
||||||
mountpoint: /data/config/deluge
|
mountpoint: $HOST_CONFIG_PATH/deluge
|
|
@ -10,22 +10,14 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- configduplicati:/config
|
- configduplicati:/config
|
||||||
- backups:/backups
|
- backups:/backups
|
||||||
- alldata:/source
|
- config:/source
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.duplicati.rule=Host(`duplicati.${TRAEFIK_DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.duplicati.middlewares=common-auth@file"
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
alldata:
|
|
||||||
driver: local-persist
|
|
||||||
driver_opts:
|
|
||||||
mountpoint: /data
|
|
||||||
configduplicati:
|
configduplicati:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
driver_opts:
|
||||||
mountpoint: /data/config/duplicati
|
mountpoint: $HOST_CONFIG_PATH/duplicati
|
||||||
backups:
|
backups:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
driver_opts:
|
||||||
mountpoint: /data/backups
|
mountpoint: $HOST_CONFIG_PATH/backups
|
|
@ -8,7 +8,7 @@ services:
|
||||||
user: ${PUID}:${PGID}
|
user: ${PUID}:${PGID}
|
||||||
command:
|
command:
|
||||||
- --auth=none
|
- --auth=none
|
||||||
- --dehost=deluge
|
- --dehost=${DELUGE_HOST}
|
||||||
- --deport=58846
|
- --deport=58846
|
||||||
- --deuser=flood
|
- --deuser=flood
|
||||||
- --depass=${FLOOD_PASSWORD}
|
- --depass=${FLOOD_PASSWORD}
|
||||||
|
@ -18,15 +18,9 @@ services:
|
||||||
- torrents:/torrents
|
- torrents:/torrents
|
||||||
- downloads:/downloads
|
- downloads:/downloads
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /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:
|
volumes:
|
||||||
configflood:
|
configflood:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
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}
|
- PUID=${PUID}
|
||||||
- TZ=${TZ}
|
- TZ=${TZ}
|
||||||
- RUN_OPTS='-FlareSolverrURL="http://flaresolverr:8191"'
|
- 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}
|
- USER_ID=${PUID}
|
||||||
- GROUP_ID=${PGID}
|
- GROUP_ID=${PGID}
|
||||||
- TZ=${TZ}
|
- 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:
|
volumes:
|
||||||
configjdownloader:
|
configjdownloader:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
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}
|
- PGID=${PGID}
|
||||||
- PUID=${PUID}
|
- PUID=${PUID}
|
||||||
- TZ=${TZ}
|
- TZ=${TZ}
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.lidarr.rule=Host(`lidarr.${TRAEFIK_DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.lidarr.middlewares=common-auth@file"
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
configlidarr:
|
configlidarr:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
driver_opts:
|
||||||
mountpoint: /data/config/lidarr
|
mountpoint: $HOST_CONFIG_PATH/lidarr
|
|
@ -15,9 +15,5 @@ services:
|
||||||
- /sys:/host/sys:ro
|
- /sys:/host/sys:ro
|
||||||
- /etc/passwd:/host/etc/passwd:ro
|
- /etc/passwd:/host/etc/passwd:ro
|
||||||
- /etc/group:/host/etc/group: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
|
- /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
|
image: mariadb:10
|
||||||
container_name: nextcloud-db
|
container_name: nextcloud-db
|
||||||
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --innodb-file-per-table=1 --skip-innodb-read-only-compressed
|
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --innodb-file-per-table=1 --skip-innodb-read-only-compressed
|
||||||
|
user: ${PUID}:${PGID}
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
|
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
|
||||||
|
@ -31,22 +32,17 @@ services:
|
||||||
- nextclouddata:/data
|
- nextclouddata:/data
|
||||||
- torrents:/torrents
|
- torrents:/torrents
|
||||||
- config:/seedbox-config
|
- 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:
|
volumes:
|
||||||
nextclouddb:
|
nextclouddb:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
driver_opts:
|
||||||
mountpoint: /data/nextcloud-db
|
mountpoint: $HOST_CONFIG_PATH/nextcloud-db
|
||||||
confignextcloud:
|
confignextcloud:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
driver_opts:
|
||||||
mountpoint: /data/config/nextcloud
|
mountpoint: $HOST_CONFIG_PATH/nextcloud
|
||||||
nextclouddata:
|
nextclouddata:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
driver_opts:
|
||||||
mountpoint: /data/config/nextcloud-data
|
mountpoint: $HOST_CONFIG_PATH/nextcloud-data
|
|
@ -10,13 +10,9 @@ services:
|
||||||
- PUID=${PUID}
|
- PUID=${PUID}
|
||||||
- TZ=${TZ}
|
- TZ=${TZ}
|
||||||
- BASE_URL=/
|
- BASE_URL=/
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.ombi.rule=Host(`ombi.${TRAEFIK_DOMAIN}`)"
|
|
||||||
#- "traefik.http.routers.ombi.middlewares=common-auth@file"
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
configombi:
|
configombi:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
driver_opts:
|
||||||
mountpoint: /data/config/ombi
|
mountpoint: $HOST_CONFIG_PATH/ombi
|
|
@ -9,12 +9,9 @@ services:
|
||||||
- PGID=${PGID}
|
- PGID=${PGID}
|
||||||
- PUID=${PUID}
|
- PUID=${PUID}
|
||||||
- TZ=${TZ}
|
- TZ=${TZ}
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.overseerr.rule=Host(`overseerr.${TRAEFIK_DOMAIN}`)"
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
configoverseerr:
|
configoverseerr:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
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"
|
- "32400:32400/udp"
|
||||||
- "32469:32469"
|
- "32469:32469"
|
||||||
- "32469:32469/udp"
|
- "32469:32469/udp"
|
||||||
- "5353:5353/udp"
|
|
||||||
- "1900:1900/udp"
|
|
||||||
volumes:
|
volumes:
|
||||||
- configplex:/config
|
- configplex:/config
|
||||||
- torrents:/torrents
|
- torrents:/torrents
|
||||||
|
@ -18,13 +16,9 @@ services:
|
||||||
- PUID=${PUID}
|
- PUID=${PUID}
|
||||||
- TZ=${TZ}
|
- TZ=${TZ}
|
||||||
- VERSION=latest
|
- 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:
|
volumes:
|
||||||
configplex:
|
configplex:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
driver_opts:
|
||||||
mountpoint: /data/config/Plex
|
mountpoint: $HOST_CONFIG_PATH/Plex
|
|
@ -5,8 +5,4 @@ services:
|
||||||
restart: always
|
restart: always
|
||||||
volumes:
|
volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
command: --admin-password ${PORTAINER_ADMIN_PASSWORD} --host=unix:///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"
|
|
|
@ -9,13 +9,9 @@ services:
|
||||||
- PGID=${PGID}
|
- PGID=${PGID}
|
||||||
- PUID=${PUID}
|
- PUID=${PUID}
|
||||||
- TZ=${TZ}
|
- TZ=${TZ}
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.prowlarr.rule=Host(`prowlarr.${TRAEFIK_DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.prowlarr.middlewares=common-auth@file"
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
configprowlarr:
|
configprowlarr:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
driver_opts:
|
||||||
mountpoint: /data/config/prowlarr
|
mountpoint: $HOST_CONFIG_PATH/prowlarr
|
|
@ -11,13 +11,9 @@ services:
|
||||||
- PGID=${PGID}
|
- PGID=${PGID}
|
||||||
- PUID=${PUID}
|
- PUID=${PUID}
|
||||||
- TZ=${TZ}
|
- TZ=${TZ}
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.radarr.rule=Host(`radarr.${TRAEFIK_DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.radarr.middlewares=common-auth@file"
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
configradarr:
|
configradarr:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
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}
|
- PGID=${PGID}
|
||||||
- PUID=${PUID}
|
- PUID=${PUID}
|
||||||
- TZ=${TZ}
|
- TZ=${TZ}
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.sonarr.rule=Host(`sonarr.${TRAEFIK_DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.sonarr.middlewares=common-auth@file"
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
configsonarr:
|
configsonarr:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
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}
|
- PGID=${PGID}
|
||||||
- PUID=${PUID}
|
- PUID=${PUID}
|
||||||
- TZ=${TZ}
|
- TZ=${TZ}
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.tautulli.rule=Host(`tautulli.${TRAEFIK_DOMAIN}`)"
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
configtautulli:
|
configtautulli:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
driver_opts:
|
||||||
mountpoint: /data/config/tautulli
|
mountpoint: $HOST_CONFIG_PATH/tautulli
|
|
@ -15,11 +15,6 @@ services:
|
||||||
- transcodes:/temp
|
- transcodes:/temp
|
||||||
- configtdarrv2:/app/server
|
- configtdarrv2:/app/server
|
||||||
- settingstdarrv2:/app/configs
|
- 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:
|
tdarr_node:
|
||||||
image: haveagitgat/tdarr_node:latest
|
image: haveagitgat/tdarr_node:latest
|
||||||
|
@ -45,12 +40,12 @@ volumes:
|
||||||
configtdarrv2:
|
configtdarrv2:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
driver_opts:
|
||||||
mountpoint: /data/config/tdarrv2/server
|
mountpoint: $HOST_CONFIG_PATH/tdarrv2/server
|
||||||
settingstdarrv2:
|
settingstdarrv2:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
driver_opts:
|
||||||
mountpoint: /data/config/tdarrv2/configs
|
mountpoint: $HOST_CONFIG_PATH/tdarrv2/configs
|
||||||
transcodes:
|
transcodes:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
driver_opts:
|
||||||
mountpoint: /data/config/tdarrv2/transcodes
|
mountpoint: $HOST_CONFIG_PATH/tdarrv2/transcodes
|
|
@ -16,15 +16,9 @@ services:
|
||||||
environment:
|
environment:
|
||||||
- TRAEFIK_DOMAIN=${TRAEFIK_DOMAIN}
|
- TRAEFIK_DOMAIN=${TRAEFIK_DOMAIN}
|
||||||
- TZ=${TZ}
|
- 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:
|
volumes:
|
||||||
configtraefik:
|
configtraefik:
|
||||||
driver: local-persist
|
driver: local-persist
|
||||||
driver_opts:
|
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
|
while true; do
|
||||||
read -p "[$0] Do you want to REMOVE these files?" yn
|
read -p "[$0] Do you want to REMOVE these files?" yn
|
||||||
case $yn in
|
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...";;
|
[Nn]* ) echo "[$0] Skipping this part. Continuing...";;
|
||||||
* ) echo "[$0] Please answer yes or no.";;
|
* ) echo "[$0] Please answer yes or no.";;
|
||||||
esac
|
esac
|
||||||
|
|
|
@ -15,3 +15,7 @@ http:
|
||||||
frameDeny: true
|
frameDeny: true
|
||||||
contentTypeNosniff: true
|
contentTypeNosniff: true
|
||||||
browserXssFilter: true
|
browserXssFilter: true
|
||||||
|
redirect-to-https:
|
||||||
|
redirectScheme:
|
||||||
|
scheme: https
|
||||||
|
permanent: false
|
||||||
|
|
|
@ -2,10 +2,10 @@ api:
|
||||||
dashboard: true
|
dashboard: true
|
||||||
|
|
||||||
# Set Access logs timezone
|
# Set Access logs timezone
|
||||||
accessLog:
|
# accessLog:
|
||||||
fields:
|
# fields:
|
||||||
names:
|
# names:
|
||||||
StartUTC: drop
|
# StartUTC: drop
|
||||||
|
|
||||||
providers:
|
providers:
|
||||||
docker:
|
docker:
|
||||||
|
@ -19,11 +19,11 @@ providers:
|
||||||
entryPoints:
|
entryPoints:
|
||||||
insecure:
|
insecure:
|
||||||
address: ":80"
|
address: ":80"
|
||||||
http:
|
# http:
|
||||||
redirections:
|
# redirections:
|
||||||
entryPoint:
|
# entryPoint:
|
||||||
to: secure
|
# to: secure
|
||||||
scheme: https
|
# scheme: https
|
||||||
secure:
|
secure:
|
||||||
address: ":443"
|
address: ":443"
|
||||||
http:
|
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