4278 lines
132 KiB
Org Mode
4278 lines
132 KiB
Org Mode
#+TITLE: Home Server
|
|
#+SETUPFILE: ./setup/org-setup-file.org
|
|
|
|
* Hardware
|
|
|
|
#+caption: Home Server Hardware
|
|
| *Part* | *Model* |
|
|
|-------------+-------------------------------------------------|
|
|
| Case | Fractal Design Node 804 |
|
|
| Motherboard | ASUS PRIME B450M-A |
|
|
| CPU | AMD Ryzen 3 3200G |
|
|
| RAM | Corsair Vengeance LPX 16Go (2x8Go) DDR4 3200MHz |
|
|
| Cooler | ARCTIC Freezer 34 eSports DUO |
|
|
| PSU | Corsair SF450 |
|
|
| SSD M.2 | Samsung 970 EVO Plus 250Gb |
|
|
| Disk Drives | Various drives ranging from 3Tb to 8Tb |
|
|
|
|
* Installation
|
|
** Ubuntu
|
|
- Download *Ubuntu Server 20.04 LTS* ([[https://ubuntu.com/download/server][link]]).
|
|
- Activate OpenSSH and add SSH Keys
|
|
- Account: =thomas=, hostname: =homelab=
|
|
|
|
** Install Important software
|
|
#+begin_src bash :eval no
|
|
sudo apt install neovim tmux fd-find ripgrep fzf apache2-utils unrar ranger
|
|
#+end_src
|
|
|
|
** Terminal Problem
|
|
On the local host, using Termite:
|
|
#+begin_src bash :eval no
|
|
infocmp > termite.terminfo # export Termite's Terminfo
|
|
scp termite.terminfo user@remote-host:~/ # or any other method to copy to the remote host
|
|
#+end_src
|
|
|
|
On the remote host, in the directory where you copied =termite.terminfo=:
|
|
#+begin_src bash :eval no
|
|
tic -x termite.terminfo # import Terminfo for current user
|
|
rm termite.terminfo # optional: remove Terminfo file
|
|
#+end_src
|
|
|
|
** Minor Modifications of =~/.inputrc=
|
|
Modify =~/.inputrc=, like so:
|
|
#+begin_src conf
|
|
"\e[A": history-search-backward # arrow up
|
|
"\e[B": history-search-forward # arrow down
|
|
#+end_src
|
|
|
|
** Partition and Format Disk Drives
|
|
A nice tutorial is available [[https://www.digitalocean.com/community/tutorials/how-to-partition-and-format-storage-devices-in-linux][here]].
|
|
|
|
#+begin_src bash :eval no
|
|
lsblk
|
|
#+end_src
|
|
|
|
#+begin_src bash :eval no
|
|
sudo parted /dev/sda mklabel gpt
|
|
#+end_src
|
|
|
|
#+begin_src bash :eval no
|
|
sudo parted -a opt /dev/sda mkpart "partitionname" ext4 0% 100%
|
|
#+end_src
|
|
|
|
#+begin_src bash :eval no
|
|
sudo mkfs.ext4 -L partitionname /dev/sda1
|
|
#+end_src
|
|
|
|
** MergerFS and FStab
|
|
*MergerFS* is a transparent layer that sits on top of the data drives providing a single mount point for reads / writes ([[https://selfhostedhome.com/combining-different-sized-drives-with-mergerfs-and-snapraid/][link]]).
|
|
|
|
#+begin_src bash :eval no
|
|
sudo apt install mergerfs
|
|
#+end_src
|
|
|
|
Create mount points
|
|
#+begin_src bash :eval no
|
|
sudo mkdir /mnt/disk0
|
|
sudo mkdir /mnt/disk1
|
|
sudo mkdir /mnt/parity
|
|
#+end_src
|
|
|
|
Create folder where disks will be merged.
|
|
#+begin_src bash :eval no
|
|
sudo mkdir /srv/storage
|
|
#+end_src
|
|
|
|
Edit =/etc/fstab=.
|
|
#+begin_src conf :eval no
|
|
/dev/disk/by-uuid/7fb7873c-83bd-4805-98ab-506e6c7b56fa /mnt/disk0 ext4 defaults 0 0
|
|
/dev/disk/by-uuid/6574b7ae-321c-4078-9793-bc41a4fa5588 /mnt/disk1 ext4 defaults 0 0
|
|
/dev/disk/by-uuid/6fcd38b9-0886-46bd-900d-cb1f170dbcee /mnt/parity ext4 defaults 0 0
|
|
|
|
/mnt/disk* /srv/storage fuse.mergerfs direct_io,defaults,allow_other,minfreespace=50G,fsname=mergerfs 0 0
|
|
#+end_src
|
|
|
|
** SnapRAID ([[https://github.com/amadvance/snapraid][link]]) and SnapRAID Runner ([[https://github.com/Chronial/snapraid-runner][link]])
|
|
*SnapRAID* is a snapshot parity calculation tool which acts at the block level independent of filesystem ([[https://selfhostedhome.com/combining-different-sized-drives-with-mergerfs-and-snapraid/][link]]).
|
|
|
|
It is manually installed with docker ([[https://github.com/ironicbadger/docker-snapraid][link]]).
|
|
|
|
The configuration file is located in =/etc/snapraid.conf=:
|
|
#+begin_src conf :tangle /ssh:thomas@homelab:/etc/snapraid.conf
|
|
# Defines the file to use as parity storage
|
|
# It must NOT be in a data disk
|
|
# Format: "parity FILE_PATH"
|
|
parity /mnt/parity/snapraid.parity
|
|
|
|
# Defines the files to use as content list
|
|
# You can use multiple specification to store more copies
|
|
# You must have least one copy for each parity file plus one. Some more don't
|
|
# hurt
|
|
# They can be in the disks used for data, parity or boot,
|
|
# but each file must be in a different disk
|
|
# Format: "content FILE_PATH"
|
|
content /var/snapraid.content
|
|
content /mnt/disk0/.snapraid.content
|
|
content /mnt/disk1/.snapraid.content
|
|
|
|
# Defines the data disks to use
|
|
# The order is relevant for parity, do not change it
|
|
# Format: "disk DISK_NAME DISK_MOUNT_POINT"
|
|
disk disk0 /mnt/disk0
|
|
disk disk1 /mnt/disk1
|
|
|
|
# Excludes hidden files and directories (uncomment to enable).
|
|
#nohidden
|
|
|
|
# Defines files and directories to exclude
|
|
# Remember that all the paths are relative at the mount points
|
|
# Format: "exclude FILE"
|
|
# Format: "exclude DIR/"
|
|
# Format: "exclude /PATH/FILE"
|
|
# Format: "exclude /PATH/DIR/"
|
|
exclude /tmp/
|
|
exclude /lost+found/
|
|
exclude *.!sync
|
|
exclude .DS_Store
|
|
exclude ._.DS_Store
|
|
exclude .Thumbs.db
|
|
exclude .fseventsd
|
|
exclude .Spotlight-V100
|
|
exclude .TemporaryItems
|
|
exclude .Trashes
|
|
#+end_src
|
|
|
|
Go in the =/home/thomas/.local/soft/= directory and clone the =snapraid-runner= [[https://github.com/tdehaeze/snapraid-runner][repository]].
|
|
|
|
Then, create the =snapraid-runner.conf= file:
|
|
#+begin_src conf :noweb yes :tangle /ssh:thomas@homelab:~/.local/soft/snapraid-runner/snapraid-runner.conf
|
|
[snapraid]
|
|
; path to the snapraid executable (e.g. /bin/snapraid)
|
|
executable = /usr/local/bin/snapraid
|
|
; path to the snapraid config to be used
|
|
config = /etc/snapraid.conf
|
|
; abort operation if there are more deletes than this, set to -1 to disable
|
|
deletethreshold = -1
|
|
; if you want touch to be ran each time
|
|
touch = true
|
|
|
|
[logging]
|
|
; logfile to write to, leave empty to disable
|
|
file = snapraid.log
|
|
; maximum logfile size in KiB, leave empty for infinite
|
|
maxsize = 5000
|
|
|
|
[gotify]
|
|
sendon = error
|
|
url = https://gotify.tdehaeze.xyz
|
|
token = <<get-password(passname="nas/gotify_snapraid_token")>>
|
|
|
|
[scrub]
|
|
; set to true to run scrub after sync
|
|
enabled = true
|
|
; scrub plan - either a percentage or one of [bad, new, full]
|
|
plan = 12
|
|
; minimum block age (in days) for scrubbing. Only used with percentage plans
|
|
older-than = 10
|
|
#+end_src
|
|
|
|
And finally, create a =cronjob= with =sudo crontab -e= and add the following line:
|
|
#+begin_src conf
|
|
0 3 * * * python3 /home/thomas/.local/soft/snapraid-runner/snapraid-runner.py -c /home/thomas/.local/soft/snapraid-runner/snapraid-runner.conf >> /home/thomas/cron/snapraid_runner.log 2>&1
|
|
#+end_src
|
|
|
|
** Install Docker
|
|
The procedure is well explained [[https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04][here]].
|
|
|
|
If docker is already installed, remove it:
|
|
#+begin_src bash
|
|
sudo apt remove docker
|
|
#+end_src
|
|
|
|
** Executing the Docker Command Without Sudo
|
|
#+begin_src bash
|
|
sudo usermod -aG docker ${USER}
|
|
#+end_src
|
|
|
|
To apply the new group membership, log out of the server and back in, or type the following:
|
|
#+begin_src bash
|
|
su - ${USER}
|
|
#+end_src
|
|
|
|
** Install Docker-Compose
|
|
#+begin_src bash
|
|
sudo apt install docker-compose
|
|
#+end_src
|
|
|
|
** Setup Docker Networks
|
|
#+begin_src bash
|
|
docker network create --gateway 192.168.90.1 --subnet 192.168.90.0/24 t2_proxy
|
|
docker network create docker_default
|
|
#+end_src
|
|
|
|
** Change Timezone
|
|
#+begin_src bash :exec no
|
|
sudo timedatectl set-timezone Europe/Paris
|
|
#+end_src
|
|
|
|
** Secure the Web Server
|
|
Most of it comes from [[https://github.com/imthenachoman/How-To-Secure-A-Linux-Server][here]].
|
|
|
|
- Set =PasswordAuthentication= no in =/etc/ssh/sshd_config=
|
|
|
|
** Automatic Security Updates
|
|
The procedure is well explained [[https://www.linuxbabe.com/ubuntu/automatic-security-update-unattended-upgrades-ubuntu][here]].
|
|
#+begin_src bash
|
|
sudo apt install unattended-upgrades update-notifier-common
|
|
#+end_src
|
|
|
|
Edit =/etc/apt/apt.conf.d/50unattended-upgrades=, and change the following lines:
|
|
#+begin_src conf
|
|
Unattended-Upgrade::Remove-Unused-Dependencies "true";
|
|
Unattended-Upgrade::Automatic-Reboot "true";
|
|
Unattended-Upgrade::Automatic-Reboot-Time "04:00";
|
|
#+end_src
|
|
|
|
Edit =/etc/apt/apt.conf.d/20auto-upgrades=:
|
|
#+begin_src conf
|
|
APT::Periodic::Update-Package-Lists "1";
|
|
APT::Periodic::Unattended-Upgrade "1";
|
|
#+end_src
|
|
|
|
** Setup cronjobs
|
|
Create a folder =~/cron= with all the scripts and logs related to cron.
|
|
|
|
To edit the cron jobs, type =crontab -e= and add a line like:
|
|
#+begin_src conf
|
|
*/5 * * * * /home/thomas/cron/caddy_update.sh >> /home/thomas/cron/caddy_update.log 2>&1
|
|
#+end_src
|
|
|
|
That will run every 5 minutes.
|
|
To check how the first part of the crontab works, check [[https://crontab.guru/][this website]].
|
|
|
|
** Setup Traefik proxy
|
|
|
|
Follow [[https://www.smarthomebeginner.com/traefik-2-docker-tutorial/][this]] guide.
|
|
|
|
** Run =docker-compose=
|
|
#+begin_src bash
|
|
cd ~/docker && docker-compose up -d
|
|
#+end_src
|
|
|
|
** Docker config =~/.docker/config.json=
|
|
#+begin_src json :tangle /ssh:thomas@homelab:~/.docker/config.json
|
|
{
|
|
"psFormat": "table {{ .ID }}\\t{{ .Names }}\t{{ .Status }}"
|
|
}
|
|
#+end_src
|
|
|
|
* Maintenance - How To
|
|
** Update System/Packages
|
|
#+begin_src bash
|
|
sudo -- sh -c 'apt-get update; apt-get upgrade -y; apt-get dist-upgrade -y; apt-get autoremove -y; apt-get autoclean -y'
|
|
#+end_src
|
|
|
|
** Snapraid errors
|
|
If there are errors, you can check what is going on with:
|
|
#+begin_src bash :eval no
|
|
sudo snapraid status
|
|
#+end_src
|
|
|
|
To fix the errors:
|
|
#+begin_src bash :eval no
|
|
sudo snapraid -e fix
|
|
#+end_src
|
|
|
|
You can check again if everything is fixed using the =scrub= command:
|
|
#+begin_src bash :eval no
|
|
sudo snapraid scrub
|
|
#+end_src
|
|
|
|
** Docker Commands
|
|
- Starting a container: =$ docker start homeassistant=
|
|
- Stopping a container: =$ docker stop homeassistant=
|
|
- Restarting a container: =$ docker restart homeassistant=
|
|
- Listing the running containers: =$ docker ps or $ cd ~/docker/ && docker-compose ps=
|
|
- View the logs of a container: =$ docker logs -f homeassistant=
|
|
- Drop a shell into a container: =$ docker exec -it homeassistant /bin/bash=
|
|
- Update specific container: =docker-compose pull --ignore-pull-failures homeassistant=
|
|
|
|
Update All Containers
|
|
#+begin_src bash :eval no
|
|
cd ~/docker/ && docker-compose pull --ignore-pull-failures && docker-compose up -d
|
|
#+end_src
|
|
|
|
Clean up Docker environment
|
|
This will delete all unused images, volumes and networks.
|
|
#+begin_src bash :eval no
|
|
docker system prune -f && docker image prune -f && docker volume prune -f
|
|
#+end_src
|
|
|
|
** Add =wireguard= client
|
|
*** With an Android client
|
|
Show the QRcode corresponding the a specific peer with:
|
|
#+begin_src bash
|
|
docker exec -it wireguard /app/show-peer 1
|
|
#+end_src
|
|
|
|
Then, simply scan the QRcode with the [[https://github.com/WireGuard/wireguard-android][Wireguard]] application.
|
|
|
|
*** With a Linux client
|
|
|
|
Copy the file =$CONFIGDIR/wireguard/peeri/peeri.conf=, e.g.:
|
|
#+begin_src conf
|
|
[Interface]
|
|
Address = 10.13.13.4/24
|
|
DNS = 10.13.1.1
|
|
PrivateKey = ****
|
|
ListenPort = 51820
|
|
|
|
[Peer]
|
|
PublicKey = ****
|
|
Endpoint = wireguard.tdehaeze.xyz:51820
|
|
AllowedIPs = 0.0.0.0/0, ::0/0
|
|
#+end_src
|
|
|
|
Then, paste the file to =/etc/wireguard/interfacename.conf=.
|
|
And then:
|
|
- =sudo chmod 600 /etc/wireguard/interfacename.conf=
|
|
- =sudo chown root:root /etc/wireguard/interfacename.conf=
|
|
|
|
Then, start the tunnel with:
|
|
#+begin_src bash :eval no
|
|
wg-quick up interfacename
|
|
#+end_src
|
|
|
|
** Add new user to =authelia=
|
|
|
|
Modify the user database file:
|
|
#+begin_src bash :eval no
|
|
nvim ~/docker/config/authelia/users_database.yml
|
|
#+end_src
|
|
|
|
Add an entry for the new user.
|
|
Restart the container with =docker-compose restart authelia=.
|
|
Ask the new user to go to https://login.tdehaeze.xyz/ to reset his password.
|
|
|
|
* Docker-Compose
|
|
:PROPERTIES:
|
|
:header-args: :tangle /ssh:thomas@homelab:~/docker/docker-compose.yaml
|
|
:header-args+: :comments none :mkdirp yes
|
|
:END:
|
|
|
|
** Basic Config
|
|
#+begin_src yaml
|
|
version: "3.8"
|
|
#+end_src
|
|
|
|
#+begin_src yaml
|
|
networks:
|
|
t2_proxy:
|
|
external:
|
|
name: t2_proxy
|
|
immich:
|
|
external: false
|
|
backend:
|
|
external: false
|
|
default:
|
|
driver: bridge
|
|
#+end_src
|
|
|
|
#+begin_src yaml
|
|
x-logging:
|
|
&default-logging
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "200k"
|
|
max-file: "10"
|
|
#+end_src
|
|
|
|
#+begin_src yaml
|
|
services:
|
|
#+end_src
|
|
|
|
** Docker Config and Tools
|
|
*** =traefik= - Application proxy ([[https://github.com/traefik/traefik][link]])
|
|
#+begin_src yaml
|
|
traefik:
|
|
container_name: traefik
|
|
image: traefik:2.9
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- authelia
|
|
networks:
|
|
t2_proxy:
|
|
ipv4_address: 192.168.90.254 # You can specify a static IP
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
ports:
|
|
- 80:80 # http
|
|
- 443:443 # https
|
|
- 8448:8448 # Matrix
|
|
volumes:
|
|
- $CONFIGDIR/traefik2/acme.json:/acme.json
|
|
- $CONFIGDIR/traefik2/traefik.yaml:/etc/traefik/traefik.yaml
|
|
- $CONFIGDIR/traefik2/services.yaml:/etc/traefik/services.yaml
|
|
- /var/log/traefik:/var/log
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
environment:
|
|
- CF_API_EMAIL=$CLOUDFLARE_EMAIL
|
|
- CF_API_KEY=$CLOUDFLARE_API_KEY
|
|
labels:
|
|
- "traefik.enable=true"
|
|
# HTTP-to-HTTPS Redirect
|
|
- "traefik.http.routers.http-catchall.entryPoints=web"
|
|
- "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)"
|
|
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
|
|
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
|
|
# HTTP Routers
|
|
- "traefik.http.routers.traefik-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.traefik-rtr.rule=Host(`traefik.$DOMAINNAME`)"
|
|
- "traefik.http.routers.traefik-rtr.tls=true"
|
|
- "traefik.http.routers.traefik-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.routers.traefik-rtr.service=traefik-svc"
|
|
# - "traefik.http.routers.traefik-rtr.tls.certresolver=dns-cloudflare" # Comment out this line after first run of traefik to force the use of wildcard certs
|
|
- "traefik.http.routers.traefik-rtr.tls.domains[0].main=$DOMAINNAME"
|
|
- "traefik.http.routers.traefik-rtr.tls.domains[0].sans=*.$DOMAINNAME"
|
|
- "traefik.http.routers.traefik-rtr.tls.domains[1].main=wingaudio.fr"
|
|
- "traefik.http.routers.traefik-rtr.tls.domains[1].sans=*.wingaudio.fr"
|
|
- "traefik.http.services.traefik-svc.loadbalancer.server.port=8080"
|
|
# Services - API
|
|
- "traefik.http.routers.traefik-rtr.service=api@internal"
|
|
# Router
|
|
- "traefik.http.routers.openwrt.entrypoints=web-secure"
|
|
- "traefik.http.routers.openwrt.rule=Host(`openwrt.$DOMAINNAME`)"
|
|
- "traefik.http.routers.openwrt.tls=true"
|
|
- "traefik.http.routers.openwrt.service=openwrt@file"
|
|
# Valetudo
|
|
- "traefik.http.routers.valetudo.entrypoints=web-secure"
|
|
- "traefik.http.routers.valetudo.rule=Host(`valetudo.$DOMAINNAME`)"
|
|
- "traefik.http.routers.valetudo.tls=true"
|
|
- "traefik.http.routers.valetudo.middlewares=authelia@docker"
|
|
- "traefik.http.routers.valetudo.service=valetudo@file"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
=traefik.yaml=
|
|
#+begin_src yaml :tangle /ssh:thomas@homelab:/home/thomas/docker/config/traefik2/traefik.yaml
|
|
global:
|
|
checkNewVersion: true
|
|
sendAnonymousUsage: false
|
|
|
|
entryPoints:
|
|
web:
|
|
address: :80
|
|
web-secure:
|
|
address: :443
|
|
forwardedHeaders:
|
|
trustedIPs: 173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/12,172.64.0.0/13,131.0.72.0/22
|
|
matrix-federation:
|
|
address: :8448
|
|
|
|
api:
|
|
dashboard: true
|
|
|
|
log:
|
|
level: ERROR
|
|
|
|
metrics:
|
|
influxDB2:
|
|
address: https://influxdb.$DOMAINNAME
|
|
token: dhkvChi1tXrMY18plDTWifz8MZNUm2M4QGpEAd2FftmMlfsN7KLq96uQXADbiQxDb1Vo2pYTSblCGqrfVygqJw==
|
|
org: homelab
|
|
bucket: traefik
|
|
|
|
accessLog:
|
|
filePath: /var/log/access.log
|
|
filters:
|
|
statusCodes: 400-499
|
|
|
|
providers:
|
|
docker:
|
|
endpoint: unix:///var/run/docker.sock
|
|
defaultrule: Host(`{{ index .Labels "com.docker.compose.service" }}.$DOMAINNAME`)
|
|
exposedByDefault: false
|
|
network: t2_proxy
|
|
swarmMode: false
|
|
file:
|
|
filename: /etc/traefik/services.yaml
|
|
|
|
serversTransport:
|
|
insecureSkipVerify: true # Necessary for Unifi (but not recommended)
|
|
|
|
certificatesResolvers:
|
|
dns-cloudflare:
|
|
acme:
|
|
# caServer: https://acme-staging-v02.api.letsencrypt.org/directory # LetsEncrypt Staging Server - uncomment when testing
|
|
email: dehaeze.thomas@gmail.com
|
|
storage: /acme.json
|
|
dnsChallenge:
|
|
provider: cloudflare
|
|
resolvers: 1.1.1.1:53,1.0.0.1:53
|
|
# delayBeforeCheck: 90 # To delay DNS check and reduce LE hitrate
|
|
#+end_src
|
|
|
|
#+begin_src yaml :tangle /ssh:thomas@homelab:/home/thomas/docker/config/traefik2/services.yaml
|
|
http:
|
|
services:
|
|
openwrt:
|
|
loadBalancer:
|
|
servers:
|
|
- url: "http://192.168.1.1/"
|
|
valetudo:
|
|
loadBalancer:
|
|
servers:
|
|
- url: "http://192.168.1.110/"
|
|
- url: "http://192.168.2.157/"
|
|
- url: "http://192.168.5.157/"
|
|
healthCheck:
|
|
path: /
|
|
middlewares:
|
|
unifiHeaders:
|
|
headers:
|
|
customRequestHeaders:
|
|
Authorization: "" # Removes
|
|
#+end_src
|
|
|
|
*** =authelia= - Single Sign-On Multi-Factor portal ([[https://github.com/authelia/authelia][link]])
|
|
#+begin_src yaml
|
|
authelia:
|
|
image: authelia/authelia:4.35
|
|
container_name: authelia
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
- backend
|
|
volumes:
|
|
- $CONFIGDIR/authelia:/config
|
|
- /etc/timezone:/etc/timezone:ro
|
|
- /etc/localtime:/etc/localtime:ro
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- AUTHELIA_NOTIFIER_SMTP_PASSWORD=$GOOGLE_AUTHELIA_PASS
|
|
- AUTHELIA_JWT_SECRET=$AUTHELIA_JWT_SECRET
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.authelia-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.authelia-rtr.tls=true"
|
|
- "traefik.http.routers.authelia-rtr.service=authelia-svc"
|
|
- "traefik.http.routers.authelia-rtr.rule=Host(`login.$DOMAINNAME`)"
|
|
- "traefik.http.services.authelia-svc.loadbalancer.server.port=9091"
|
|
- "traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=https://login.$DOMAINNAME/"
|
|
- "traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true"
|
|
- "traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User, Remote-Groups, Remote-Name, Remote-Email"
|
|
- "treafik.http.middlewares.chain-authelia.chain.middlewares=middlewares-rate-limit, middlewares-secure-headers, middlewares-authelia"
|
|
- "traefik.docker.network=t2_proxy"
|
|
#+end_src
|
|
|
|
=configuration.yml=
|
|
#+begin_src yaml :tangle /ssh:thomas@homelab:/home/thomas/docker/config/authelia/configuration.yml
|
|
---
|
|
###############################################################
|
|
# Authelia configuration #
|
|
###############################################################
|
|
|
|
default_redirection_url: https://authelia.tdehaeze.xyz
|
|
|
|
server:
|
|
host: 0.0.0.0
|
|
port: 9091
|
|
|
|
log:
|
|
level: debug
|
|
|
|
totp:
|
|
issuer: authelia.com
|
|
period: 30
|
|
skew: 1
|
|
|
|
authentication_backend:
|
|
file:
|
|
path: /config/users_database.yml
|
|
password:
|
|
algorithm: argon2id
|
|
iterations: 1
|
|
salt_length: 16
|
|
parallelism: 8
|
|
memory: 1024
|
|
|
|
access_control:
|
|
default_policy: deny
|
|
rules:
|
|
- domain: valetudo.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- ["group:family"]
|
|
- domain: openwrt.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- domain: traefik.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- domain: scrutiny.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- domain: sync-ju.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- domain: sync-jm.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- domain: sync-anne.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- domain: syncthing.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- domain: uptime.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- domain: wireguard.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- domain: joal.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- domain: change.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- domain: esphome.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- domain: influxdb.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- domain: node-red.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- ["group:family"]
|
|
- domain: zigbee2mqtt.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- domain: qobuz.tdehaeze.xyz
|
|
policy: bypass
|
|
resources:
|
|
- "^/download.*$"
|
|
- domain: qobuz.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- ["group:friends"]
|
|
- ["group:family"]
|
|
- domain: sonarr.tdehaeze.xyz
|
|
policy: bypass
|
|
resources:
|
|
- "^/api.*$"
|
|
- domain: sonarr.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- domain: radarr.tdehaeze.xyz
|
|
policy: bypass
|
|
resources:
|
|
- "^/api.*$"
|
|
- domain: radarr.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
- domain: unifi.tdehaeze.xyz
|
|
policy: one_factor
|
|
subject:
|
|
- ["group:admins"]
|
|
|
|
session:
|
|
name: authelia_session
|
|
expiration: 3600
|
|
inactivity: 300
|
|
domain: tdehaeze.xyz
|
|
|
|
regulation:
|
|
max_retries: 3
|
|
find_time: 120
|
|
ban_time: 300
|
|
|
|
storage:
|
|
encryption_key: bUEO5bYNJYziXUxEWFYubUmUdUZPhy
|
|
local:
|
|
path: /config/db.sqlite3
|
|
|
|
notifier:
|
|
smtp:
|
|
host: smtp.gmail.com
|
|
port: 587
|
|
username: tdehaeze.xyz@gmail.com
|
|
sender: tdehaeze.xyz@gmail.com
|
|
#+end_src
|
|
|
|
*** =uptime-kuma= - Monitoring Tool ([[https://github.com/louislam/uptime-kuma][link]])
|
|
#+begin_src yaml
|
|
uptime-kuma:
|
|
container_name: uptime-kuma
|
|
image: louislam/uptime-kuma
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- TZ=$TZ
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
volumes:
|
|
- $CONFIGDIR/uptime-kuma:/app/data
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.uptime-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.uptime-rtr.rule=Host(`uptime.$DOMAINNAME`)"
|
|
- "traefik.http.routers.uptime-rtr.tls=true"
|
|
- "traefik.http.routers.uptime-rtr.service=uptime-svc"
|
|
- "traefik.http.routers.uptime-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.uptime-svc.loadbalancer.server.port=3001"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =gotify= - Notification service ([[https://github.com/gotify/server][link]])
|
|
In order to have notifications on Linux desktop use [[https://github.com/ztpnk/gotify-dunst][gotify-dunst]].
|
|
|
|
#+begin_src yaml
|
|
gotify:
|
|
container_name: gotify
|
|
image: gotify/server
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- GOTIFY_DEFAULTUSER_NAME=$GOTIFY_DEFAULTUSER_NAME
|
|
- GOTIFY_DEFAULTUSER_PASS=$GOTIFY_DEFAULTUSER_PASS
|
|
volumes:
|
|
- $CONFIGDIR/gotify:/app/data
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.gotify-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.gotify-rtr.rule=Host(`gotify.$DOMAINNAME`)"
|
|
- "traefik.http.routers.gotify-rtr.tls=true"
|
|
- "traefik.http.routers.gotify-rtr.service=gotify-svc"
|
|
- "traefik.http.services.gotify-svc.loadbalancer.server.port=80"
|
|
#+end_src
|
|
|
|
*** =scrutiny= - Hard drive monitoring ([[https://hub.docker.com/r/hotio/scrutiny][link]])
|
|
#+begin_src yaml
|
|
scrutiny-web:
|
|
container_name: scrutiny-web
|
|
image: ghcr.io/analogj/scrutiny:master-web
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
- backend
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- SCRUTINY_WEB_INFLUXDB_HOST=influxdb
|
|
volumes:
|
|
- $CONFIGDIR/scrutiny:/opt/scrutiny/config
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.scrutiny-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.scrutiny-rtr.rule=Host(`scrutiny.$DOMAINNAME`)"
|
|
- "traefik.http.routers.scrutiny-rtr.tls=true"
|
|
- "traefik.http.routers.scrutiny-rtr.service=scrutiny-svc"
|
|
- "traefik.http.routers.scrutiny-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.scrutiny-svc.loadbalancer.server.port=8080"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
#+begin_src yaml
|
|
scrutiny-collector:
|
|
container_name: scrutiny-collector
|
|
image: ghcr.io/analogj/scrutiny:master-collector
|
|
restart: unless-stopped
|
|
cap_add:
|
|
- SYS_RAWIO
|
|
- SYS_ADMIN
|
|
networks:
|
|
- backend
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- COLLECTOR_API_ENDPOINT=http://scrutiny-web:8080
|
|
volumes:
|
|
- /run/udev:/run/udev:ro
|
|
devices:
|
|
- /dev/sda:/dev/sda
|
|
- /dev/sdb:/dev/sdb
|
|
- /dev/sdc:/dev/sdc
|
|
- /dev/nvme0:/dev/nvme0
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =wireguard= - VPN ([[https://github.com/linuxserver/docker-wireguard][link]])
|
|
#+begin_src yaml
|
|
wireguard:
|
|
container_name: wireguard
|
|
image: weejewel/wg-easy
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
cap_add:
|
|
- NET_ADMIN
|
|
- SYS_MODULE
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- WG_HOST=82.66.44.13
|
|
- PASSWORD=$WIREGUARD_PASS
|
|
volumes:
|
|
- $CONFIGDIR/wg-easy:/etc/wireguard
|
|
ports:
|
|
- 51820:51820/udp
|
|
sysctls:
|
|
- net.ipv4.ip_forward=1
|
|
- net.ipv4.conf.all.src_valid_mark=1
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.wireguard-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.wireguard-rtr.rule=Host(`wireguard.$DOMAINNAME`)"
|
|
- "traefik.http.routers.wireguard-rtr.tls=true"
|
|
- "traefik.http.routers.wireguard-rtr.service=wireguard-svc"
|
|
- "traefik.http.routers.wireguard-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.wireguard-svc.loadbalancer.server.port=51821"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =nginx= - Root (used for Matrix)
|
|
#+begin_src yaml
|
|
root:
|
|
container_name: root
|
|
image: nginx
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/root/nginx.conf:/etc/nginx/nginx.conf
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.root-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.root-rtr.rule=Host(`$DOMAINNAME`)"
|
|
- "traefik.http.routers.root-rtr.tls=true"
|
|
- "traefik.http.routers.root-rtr.service=root-svc"
|
|
- "traefik.http.services.root-svc.loadbalancer.server.port=8080"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
=nginx.conf=
|
|
#+begin_src conf :tangle /ssh:thomas@homelab:/home/thomas/docker/config/root/nginx.conf
|
|
events {
|
|
|
|
}
|
|
|
|
http {
|
|
server {
|
|
server_name tdehaeze.xyz;
|
|
listen 8080;
|
|
|
|
location /.well-known/matrix/client {
|
|
proxy_pass https://matrix.tdehaeze.xyz/.well-known/matrix/client;
|
|
proxy_set_header X-Forwarded-For $remote_addr;
|
|
}
|
|
|
|
location /.well-known/matrix/server {
|
|
proxy_pass https://matrix.tdehaeze.xyz/.well-known/matrix/server;
|
|
proxy_set_header X-Forwarded-For $remote_addr;
|
|
}
|
|
}
|
|
}
|
|
#+end_src
|
|
|
|
*** =commento= - Commenting system ([[https://github.com/adtac/commento][link]])
|
|
#+begin_src yaml
|
|
commento:
|
|
container_name: commento
|
|
image: registry.gitlab.com/commento/commento
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
- backend
|
|
# ports:
|
|
# - 8080:8080
|
|
environment:
|
|
- TZ=$TZ
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- COMMENTO_ORIGIN=https://commento.tdehaeze.xyz/
|
|
- COMMENTO_PORT=8080
|
|
- COMMENTO_POSTGRES=postgres://postgres:$COMMENTO_DB_PASSWORD@commento_db:5432/commento?sslmode=disable
|
|
- COMMENTO_SMTP_HOST=smtp.gmail.com
|
|
- COMMENTO_SMTP_PORT=587
|
|
- COMMENTO_SMTP_USERNAME=tdehaeze.xyz@gmail.com
|
|
- COMMENTO_SMTP_PASSWORD=$GOOGLE_AUTHELIA_PASS
|
|
- COMMENTO_SMTP_FROM_ADDRESS=tdehaeze.xyz@gmail.com
|
|
depends_on:
|
|
- commento_db
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.commento-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.commento-rtr.rule=Host(`commento.$DOMAINNAME`)"
|
|
- "traefik.http.routers.commento-rtr.tls=true"
|
|
- "traefik.http.routers.commento-rtr.service=commento-svc"
|
|
- "traefik.http.services.commento-svc.loadbalancer.server.port=8080"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
#+begin_src yaml
|
|
commento_db:
|
|
container_name: commento_db
|
|
image: postgres:13
|
|
restart: unless-stopped
|
|
networks:
|
|
- backend
|
|
user: "${PUID}:${PGID}"
|
|
environment:
|
|
- POSTGRES_DB=commento
|
|
- POSTGRES_USER=postgres
|
|
- POSTGRES_PASSWORD=$COMMENTO_DB_PASSWORD
|
|
volumes:
|
|
- $CONFIGDIR/commento_db:/var/lib/postgresql/data
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =unifi-controller= - Software for Unifi devices ([[https://hub.docker.com/r/linuxserver/unifi-controller][link]])
|
|
#+begin_src yaml
|
|
unifi-mongodb:
|
|
container_name: unifi-mongodb
|
|
image: mongo:4
|
|
networks:
|
|
- backend
|
|
restart: unless-stopped
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/unifi-mongodb/db:/data/db
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
#+begin_src yaml
|
|
unifi-controller:
|
|
container_name: unifi-controller
|
|
image: linuxserver/unifi-network-application
|
|
networks:
|
|
- t2_proxy
|
|
- backend
|
|
restart: unless-stopped
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- MONGO_USER=unifi
|
|
- MONGO_PASS=bMhre3Nza6mZzz1m
|
|
- MONGO_HOST=unifi-mongodb
|
|
- MONGO_PORT=27017
|
|
- MONGO_DBNAME=unifi
|
|
volumes:
|
|
- $CONFIGDIR/unifi/data:/config
|
|
ports:
|
|
# - 8443:8443
|
|
- 3478:3478/udp
|
|
- 10001:10001/udp
|
|
- 8080:8080
|
|
# - 1900:1900/udp #optional
|
|
# - 8843:8843 #optional
|
|
# - 8880:8880 #optional
|
|
# - 6789:6789 #optional
|
|
# - 5514:5514/udp #optional
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.unifi-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.unifi-rtr.rule=Host(`unifi.$DOMAINNAME`)"
|
|
- "traefik.http.routers.unifi-rtr.tls=true"
|
|
- "traefik.http.routers.unifi-rtr.service=unifi-svc"
|
|
- "traefik.http.routers.unifi-rtr.middlewares=unifiHeaders@file"
|
|
- "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https"
|
|
# - "traefik.http.routers.unifi-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.unifi-svc.loadbalancer.server.port=8443"
|
|
- "traefik.http.services.unifi-svc.loadbalancer.server.scheme=https"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
#+begin_src yaml :tangle no
|
|
unifi-controller:
|
|
container_name: unifi-controller
|
|
image: jacobalberty/unifi
|
|
networks:
|
|
- t2_proxy
|
|
restart: unless-stopped
|
|
environment:
|
|
- RUNAS_UID0=false
|
|
- UNIFI_UID=$PUID
|
|
- UNIFI_GID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/unifi-controller/data:/unifi/data
|
|
- $CONFIGDIR/unifi-controller/log:/unifi/log
|
|
- $CONFIGDIR/unifi-controller/cert:/unifi/cert
|
|
- $CONFIGDIR/unifi-controller/init.d:/unifi/init.d
|
|
ports:
|
|
- 3478:3478/udp # STUN
|
|
- 10001:10001/udp # AP discovery
|
|
- 6789:6789/tcp # Speed test
|
|
- 8080:8080/tcp # Device/ controller comm.
|
|
- 8443:8443/tcp # Controller GUI/API as seen in a web browser
|
|
- 8880:8880/tcp # HTTP portal redirection
|
|
- 8843:8843/tcp # HTTPS portal redirection
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.unifi-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.unifi-rtr.rule=Host(`unifi.$DOMAINNAME`)"
|
|
- "traefik.http.routers.unifi-rtr.tls=true"
|
|
- "traefik.http.routers.unifi-rtr.service=unifi-svc"
|
|
- "traefik.http.services.unifi-svc.loadbalancer.serverstransport=ignorecert"
|
|
- "traefik.http.services.unifi-svc.loadbalancer.server.scheme=https"
|
|
- "traefik.http.services.unifi-svc.loadbalancer.server.port=8443"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** Metrics
|
|
*** =influxdb=
|
|
#+begin_src yaml
|
|
influxdb:
|
|
container_name: influxdb
|
|
image: influxdb
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
- backend
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/influxdb:/var/lib/influxdb2:rw
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.influxdb-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.influxdb-rtr.rule=Host(`influxdb.$DOMAINNAME`)"
|
|
- "traefik.http.routers.influxdb-rtr.tls=true"
|
|
- "traefik.http.routers.influxdb-rtr.service=influxdb-svc"
|
|
- "traefik.http.services.influxdb-svc.loadbalancer.server.port=8086"
|
|
healthcheck:
|
|
test: "curl -f http://localhost:8086/ping"
|
|
interval: 5s
|
|
timeout: 10s
|
|
retries: 5
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** Websites
|
|
*** =homer= - Home page for myself ([[https://github.com/bastienwirtz/homer][link]])
|
|
#+begin_src yaml
|
|
homer:
|
|
container_name: homer
|
|
image: b4bz/homer
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/homer/assets/:/www/assets
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.homer-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.homer-rtr.rule=Host(`homer.$DOMAINNAME`)"
|
|
- "traefik.http.routers.homer-rtr.tls=true"
|
|
- "traefik.http.routers.homer-rtr.service=homer-svc"
|
|
- "traefik.http.services.homer-svc.loadbalancer.server.port=8080"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
=config.yml=
|
|
#+begin_src yaml :tangle /ssh:thomas@homelab:/home/thomas/docker/config/homer/assets/config.yml
|
|
---
|
|
title: "Homepage"
|
|
subtitle: ""
|
|
logo: "assets/homer.png"
|
|
header: false
|
|
footer: false
|
|
|
|
columns: "auto"
|
|
connectivityCheck: false
|
|
|
|
theme: default
|
|
|
|
links: []
|
|
|
|
services:
|
|
- name: "Websites"
|
|
icon: "fas fa-desktop"
|
|
items:
|
|
- name: "Brain"
|
|
logo: "/assets/tools/brain.png"
|
|
subtitle: "Digital Brain"
|
|
url: "https://brain.tdehaeze.xyz"
|
|
- name: "Research"
|
|
logo: "/assets/tools/orgmode.png"
|
|
subtitle: "Research Pages"
|
|
url: "https://research.tdehaeze.xyz"
|
|
- name: "Help"
|
|
logo: "/assets/tools/help.png"
|
|
subtitle: "Help Page"
|
|
url: "https://help.tdehaeze.xyz"
|
|
- name: "Dotfiles"
|
|
logo: "/assets/tools/dotfiles.png"
|
|
subtitle: "My Literate Dotfiles"
|
|
url: "https://dotfiles.tdehaeze.xyz"
|
|
- name: "Miam"
|
|
logo: "/assets/tools/miam.png"
|
|
subtitle: "Personnal Recipes"
|
|
url: "https://miam.tdehaeze.xyz"
|
|
- name: "Miniflux"
|
|
logo: "/assets/tools/miniflux.png"
|
|
subtitle: "RSS Feeds"
|
|
url: "https://rss.tdehaeze.xyz"
|
|
- name: "LinkDing"
|
|
logo: "/assets/tools/linkding.png"
|
|
subtitle: "Bookmark Manager"
|
|
url: "https://bm.tdehaeze.xyz"
|
|
- name: "Multimedia"
|
|
icon: "fas fa-photo-video"
|
|
items:
|
|
- name: "Jellyfin"
|
|
logo: "/assets/tools/jellyfin.png"
|
|
subtitle: "Media Library"
|
|
url: "https://jellyfin.tdehaeze.xyz"
|
|
- name: "JFA-Go"
|
|
logo: "/assets/tools/jellyfin.png"
|
|
subtitle: "Manage Jellyfin Users"
|
|
url: "http://jfa.tdehaeze.xyz/"
|
|
# - name: "Audioserve"
|
|
# logo: "/assets/tools/audiobook.png"
|
|
# subtitle: "Audiobook Server"
|
|
# url: "https://audiobook.tdehaeze.xyz"
|
|
# - name: "Kavita"
|
|
# logo: "/assets/tools/kavita.png"
|
|
# subtitle: "Book Library"
|
|
# url: "https://kavita.tdehaeze.xyz"
|
|
- name: "Cloud"
|
|
icon: "fas fa-cloud"
|
|
items:
|
|
- name: "Cinny"
|
|
logo: "/assets/tools/cinny.png"
|
|
subtitle: "Matrix web client"
|
|
url: "https://cinny.tdehaeze.xyz"
|
|
- name: "File Browser"
|
|
logo: "/assets/tools/cloud.png"
|
|
subtitle: "Simple Personnal Could"
|
|
url: "https://cloud.tdehaeze.xyz"
|
|
- name: "Syncthing"
|
|
logo: "/assets/tools/syncthing.png"
|
|
subtitle: "Anne"
|
|
url: "https://sync-anne.tdehaeze.xyz"
|
|
- name: "Syncthing"
|
|
logo: "/assets/tools/syncthing.png"
|
|
subtitle: "Juliette"
|
|
url: "https://sync-ju.tdehaeze.xyz"
|
|
- name: "Syncthing"
|
|
logo: "/assets/tools/syncthing.png"
|
|
subtitle: "Jean-Marie"
|
|
url: "https://sync-jm.tdehaeze.xyz"
|
|
- name: "Syncthing"
|
|
logo: "/assets/tools/syncthing.png"
|
|
subtitle: "P2P Sync"
|
|
url: "https://syncthing.tdehaeze.xyz"
|
|
- name: "Radicale"
|
|
logo: "/assets/tools/radicale.png"
|
|
subtitle: "CalDAV/CardDAV Server"
|
|
url: "https://radicale.tdehaeze.xyz"
|
|
- name: "Gitea"
|
|
logo: "/assets/tools/gitea.png"
|
|
subtitle: "Git Server"
|
|
url: "https://git.tdehaeze.xyz"
|
|
- name: "Download"
|
|
icon: "fas fa-download"
|
|
items:
|
|
- name: "JellySrerr"
|
|
logo: "/assets/tools/jellyseerr.png"
|
|
subtitle: "Torrent Client"
|
|
url: "http://jellyseerr.tdehaeze.xyz/"
|
|
# - name: "Down"
|
|
# logo: "/assets/tools/down.png"
|
|
# subtitle: "Torrent Download"
|
|
# url: "https://down.tdehaeze.xyz/"
|
|
- name: "Qobuz"
|
|
subtitle: "Music Download"
|
|
logo: "/assets/tools/qobuz.png"
|
|
url: "https://qobuz.tdehaeze.xyz"
|
|
- name: "Sonarr"
|
|
logo: "/assets/tools/sonarr.png"
|
|
subtitle: "TVShows Download"
|
|
url: "http://sonarr.tdehaeze.xyz/"
|
|
- name: "Radarr"
|
|
logo: "/assets/tools/radarr.png"
|
|
subtitle: "Movies Download"
|
|
url: "http://radarr.tdehaeze.xyz/"
|
|
- name: "Prowlarr"
|
|
logo: "/assets/tools/prowlarr.png"
|
|
subtitle: "Torrent Indexer"
|
|
url: "http://prowlarr.tdehaeze.xyz/"
|
|
# - name: "Jackett"
|
|
# logo: "/assets/tools/jackett.png"
|
|
# subtitle: "Torrent Client"
|
|
# url: "http://jackett.tdehaeze.xyz/"
|
|
- name: "Transmission"
|
|
logo: "/assets/tools/transmission.png"
|
|
subtitle: "Torrent Client"
|
|
url: "http://torrent.tdehaeze.xyz/transmission/web/"
|
|
- name: "Config"
|
|
icon: "fas fa-cog"
|
|
items:
|
|
# - name: "Portainer"
|
|
# logo: "/assets/tools/portainer.png"
|
|
# subtitle: "Manger Docker"
|
|
# url: "https://portainer.tdehaeze.xyz/#/containers"
|
|
- name: "Traefik"
|
|
logo: "/assets/tools/traefik.png"
|
|
subtitle: "Reverse Proxy"
|
|
url: "https://traefik.tdehaeze.xyz"
|
|
- name: "Wireguard"
|
|
logo: "/assets/tools/wireguard.png"
|
|
subtitle: "Manger Docker"
|
|
url: "https://wireguard.tdehaeze.xyz/"
|
|
- name: "Uptime"
|
|
logo: "/assets/tools/uptime.png"
|
|
subtitle: "Monitoring"
|
|
url: "https://uptime.tdehaeze.xyz"
|
|
- name: "Commento"
|
|
logo: "/assets/tools/commento.png"
|
|
subtitle: "Commenting System"
|
|
url: "https://commento.tdehaeze.xyz"
|
|
- name: "Gotify"
|
|
logo: "/assets/tools/gotify.png"
|
|
subtitle: "Messaging System"
|
|
url: "https://gotify.tdehaeze.xyz"
|
|
- name: "Scrutiny"
|
|
logo: "/assets/tools/scrutiny.png"
|
|
subtitle: "S.M.A.R.T"
|
|
url: "http://scrutiny.tdehaeze.xyz/web/dashboard"
|
|
- name: "Home"
|
|
icon: "fas fa-home"
|
|
items:
|
|
- name: "OpenWRT"
|
|
logo: "/assets/tools/openwrt.png"
|
|
subtitle: "Router"
|
|
url: "https://openwrt.tdehaeze.xyz/"
|
|
- name: "Unifi"
|
|
logo: "/assets/tools/unifi.png"
|
|
subtitle: "Wifi Expander"
|
|
url: "https://unifi.tdehaeze.xyz/"
|
|
- name: "Changedetection.io"
|
|
logo: "/assets/tools/changedetection.png"
|
|
subtitle: "Detect change in websites"
|
|
url: "https://change.tdehaeze.xyz"
|
|
- name: "Zigbee2MQTT"
|
|
logo: "/assets/tools/zigbee2mqtt.png"
|
|
subtitle: "Zigbee2MQTT"
|
|
url: "https://zigbee2mqtt.tdehaeze.xyz/"
|
|
- name: "Node Red"
|
|
logo: "/assets/tools/node-red.png"
|
|
subtitle: "Event-driven applications"
|
|
url: "https://node-red.tdehaeze.xyz/"
|
|
- name: "InfluxDB"
|
|
logo: "/assets/tools/influxdb.png"
|
|
subtitle: "Time series database"
|
|
url: "https://influxdb.tdehaeze.xyz/"
|
|
- name: "ESPHome"
|
|
logo: "/assets/tools/esphome.png"
|
|
subtitle: "System to control ESP8266/ESP32"
|
|
url: "https://esphome.tdehaeze.xyz/"
|
|
- name: "OctoPrint"
|
|
logo: "/assets/tools/octoprint.png"
|
|
subtitle: "Tina2"
|
|
url: "https://3d-printer.tdehaeze.xyz/"
|
|
#+end_src
|
|
|
|
*** =family= - Home page for family ([[https://github.com/bastienwirtz/homer][link]])
|
|
#+begin_src yaml
|
|
famille:
|
|
container_name: famille
|
|
image: b4bz/homer
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/famille/assets/:/www/assets
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.famille-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.famille-rtr.rule=Host(`famille.$DOMAINNAME`)"
|
|
- "traefik.http.routers.famille-rtr.tls=true"
|
|
- "traefik.http.routers.famille-rtr.service=famille-svc"
|
|
- "traefik.http.services.famille-svc.loadbalancer.server.port=8080"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
=config.yml=
|
|
#+begin_src yaml :tangle /ssh:thomas@homelab:/home/thomas/docker/config/famille/assets/config.yml
|
|
---
|
|
title: "Homepage"
|
|
subtitle: ""
|
|
logo: "assets/homer.png"
|
|
header: false
|
|
footer: false
|
|
|
|
columns: "auto"
|
|
connectivityCheck: false
|
|
|
|
theme: default
|
|
|
|
message:
|
|
style: "" # See https://bulma.io/documentation/components/message/#colors for styling options.
|
|
title: "Coucou !"
|
|
content: "Ci dessous tu peux trouver différents sites accéssibles sur mon serveur. Si tu as besoin d'aide avec l'utilisation de Jellyfin, tout est expliqué <a href='https://help.tdehaeze.xyz/'>ici</a>."
|
|
|
|
|
|
links: []
|
|
|
|
services:
|
|
- name: "Websites"
|
|
icon: "fas fa-desktop"
|
|
items:
|
|
- name: "Jellyfin"
|
|
logo: "/assets/tools/jellyfin.png"
|
|
subtitle: "Librairie multimédia"
|
|
url: "https://jellyfin.tdehaeze.xyz"
|
|
- name: "File Browser"
|
|
logo: "/assets/tools/cloud.png"
|
|
subtitle: "Cloud personnel"
|
|
url: "https://cloud.tdehaeze.xyz"
|
|
- name: "Miam"
|
|
logo: "/assets/tools/miam.png"
|
|
subtitle: "Site de recettes partagées"
|
|
url: "https://miam.tdehaeze.xyz"
|
|
- name: "Multimedia"
|
|
icon: "fas fa-photo-video"
|
|
items:
|
|
- name: "Jellyseerr"
|
|
subtitle: "Ajout de Films/Séries sur Jellyfin"
|
|
logo: "/assets/tools/jellyseerr.png"
|
|
url: "https://jellyseerr.tdehaeze.xyz"
|
|
- name: "Qobuz"
|
|
subtitle: "Ajout de Musique sur Jellyfin"
|
|
logo: "/assets/tools/qobuz.png"
|
|
url: "https://qobuz.tdehaeze.xyz"
|
|
#+end_src
|
|
|
|
*** =hugo= - Wiki + Blog ([[https://git.tdehaeze.xyz/tdehaeze/digital-brain][link]])
|
|
#+begin_src yaml
|
|
hugo:
|
|
container_name: hugo
|
|
image: tdehaeze/hugo-caddy
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- REPO=git.tdehaeze.xyz/tdehaeze/digital-brain
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.hugo-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.hugo-rtr.rule=Host(`brain.$DOMAINNAME`)"
|
|
- "traefik.http.routers.hugo-rtr.tls=true"
|
|
- "traefik.http.routers.hugo-rtr.service=hugo-svc"
|
|
- "traefik.http.services.hugo-svc.loadbalancer.server.port=2015"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =research= - Research Pages ([[https://git.tdehaeze.xyz/tdehaeze/research-home-page][link]])
|
|
#+begin_src yaml
|
|
research:
|
|
container_name: research
|
|
image: abiosoft/caddy:1.0.3-no-stats
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- PLUGINS=git
|
|
volumes:
|
|
- $CONFIGDIR/research/Caddyfile:/etc/Caddyfile
|
|
- $CONFIGDIR/research/web:/srv
|
|
# - ~/.ssh:/root/.ssh
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.caddy-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.caddy-rtr.rule=Host(`research.$DOMAINNAME`)"
|
|
- "traefik.http.routers.caddy-rtr.tls=true"
|
|
- "traefik.http.routers.caddy-rtr.service=caddy-svc"
|
|
- "traefik.http.services.caddy-svc.loadbalancer.server.port=2015"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
=Caddyfile=
|
|
#+begin_src conf :tangle /ssh:thomas@homelab:/home/thomas/docker/config/caddy/Caddyfile
|
|
0.0.0.0:2015 {
|
|
root /srv/www/
|
|
|
|
git {
|
|
repo https://git.tdehaeze.xyz/tdehaeze/research-home-page
|
|
path /srv/www/
|
|
interval -1
|
|
hook /research-home-page/webhook QHZgAKjD8q2v54Ru
|
|
then git submodule update --init --recursive --merge --remote
|
|
}
|
|
}
|
|
#+end_src
|
|
|
|
*** =dotfiles= - Dotfiles ([[https://git.tdehaeze.xyz/tdehaeze/literate-dotfiles][link]])
|
|
#+begin_src yaml
|
|
dotfiles:
|
|
container_name: dotfiles
|
|
image: abiosoft/caddy:1.0.3-no-stats
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- PLUGINS=git
|
|
volumes:
|
|
- $CONFIGDIR/dotfiles/Caddyfile:/etc/Caddyfile
|
|
- $CONFIGDIR/dotfiles/www:/srv/www
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.dotfiles-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.dotfiles-rtr.rule=Host(`dotfiles.$DOMAINNAME`)"
|
|
- "traefik.http.routers.dotfiles-rtr.tls=true"
|
|
- "traefik.http.routers.dotfiles-rtr.service=dotfiles-svc"
|
|
- "traefik.http.services.dotfiles-svc.loadbalancer.server.port=2015"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
=Caddyfile=
|
|
#+begin_src conf :tangle /ssh:thomas@homelab:/home/thomas/docker/config/dotfiles/Caddyfile
|
|
0.0.0.0:2015 {
|
|
root /srv/www/docs/
|
|
|
|
git {
|
|
repo https://git.tdehaeze.xyz/tdehaeze/literate-dotfiles
|
|
path /srv/www/
|
|
interval -1
|
|
hook /literate-dotfiles/webhook QHZgAKjD8q2v54Ru
|
|
}
|
|
}
|
|
#+end_src
|
|
|
|
*** =help= - Help page for Jellyfin ([[https://git.tdehaeze.xyz/tdehaeze/family-page][link]])
|
|
#+begin_src yaml
|
|
help:
|
|
container_name: help
|
|
image: abiosoft/caddy:1.0.3-no-stats
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- PLUGINS=git
|
|
volumes:
|
|
- $CONFIGDIR/help/Caddyfile:/etc/Caddyfile
|
|
- $CONFIGDIR/help/www:/srv/www
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.help-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.help-rtr.rule=Host(`help.$DOMAINNAME`)"
|
|
- "traefik.http.routers.help-rtr.tls=true"
|
|
- "traefik.http.routers.help-rtr.service=help-svc"
|
|
- "traefik.http.services.help-svc.loadbalancer.server.port=2015"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
=Caddyfile=
|
|
#+begin_src conf :tangle /ssh:thomas@homelab:/home/thomas/docker/config/help/Caddyfile
|
|
0.0.0.0:2015 {
|
|
root /srv/www/
|
|
|
|
git {
|
|
repo https://git.tdehaeze.xyz/tdehaeze/family-page
|
|
path /srv/www/
|
|
interval -1
|
|
hook /help/webhook 0fdVzNShbcmw
|
|
}
|
|
}
|
|
#+end_src
|
|
|
|
*** =mealie= - Recipe Manager ([[https://github.com/hay-kot/mealie][link]])
|
|
#+begin_src yaml
|
|
miam:
|
|
container_name: miam
|
|
image: hkotel/mealie
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- db_type=sqlite
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/mealie:/app/data
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.miam-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.miam-rtr.rule=Host(`miam.$DOMAINNAME`)"
|
|
- "traefik.http.routers.miam-rtr.tls=true"
|
|
- "traefik.http.routers.miam-rtr.service=miam-svc"
|
|
- "traefik.http.services.miam-svc.loadbalancer.server.port=80"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =gitea= - Git server ([[https://github.com/go-gitea/gitea][link]])
|
|
#+begin_src yaml
|
|
gitea:
|
|
container_name: git
|
|
image: gitea/gitea
|
|
depends_on:
|
|
- gitea_db
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
- backend
|
|
volumes:
|
|
- $CONFIGDIR/gitea:/data
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- SSH_PORT=$GITEA_SSH_PORT
|
|
ports:
|
|
- "2222:22"
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.git-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.git-rtr.rule=Host(`git.$DOMAINNAME`)"
|
|
- "traefik.http.routers.git-rtr.tls=true"
|
|
- "traefik.http.routers.git-rtr.service=git-svc"
|
|
- "traefik.http.services.git-svc.loadbalancer.server.port=3000"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
#+begin_src yaml
|
|
gitea_db:
|
|
container_name: gitea_db
|
|
image: mariadb:10
|
|
restart: unless-stopped
|
|
networks:
|
|
- backend
|
|
ports:
|
|
- 3306:3306
|
|
user: "${PUID}:${PGID}"
|
|
environment:
|
|
- MYSQL_ROOT_PASSWORD=$GITEA_DB_MYSQL_ROOT_PASSWORD
|
|
- MYSQL_DATABASE=gitea
|
|
- MYSQL_USER=gitea
|
|
- MYSQL_PASSWORD=$GITEA_DB_MYSQL_PASSWORD
|
|
volumes:
|
|
- $CONFIGDIR/gitea_db:/var/lib/mysql
|
|
#+end_src
|
|
|
|
*** =changedetection= - Detect change in websites ([[https://github.com/dgtlmoon/changedetection.io][link]])
|
|
#+begin_src yaml
|
|
changedetection:
|
|
container_name: changedetection
|
|
image: ghcr.io/dgtlmoon/changedetection.io
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- BASE_URL=https://change.tdehaeze.xyz
|
|
volumes:
|
|
- $CONFIGDIR/changedetection:/datastore
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.changedetection-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.changedetection-rtr.rule=Host(`change.$DOMAINNAME`)"
|
|
- "traefik.http.routers.changedetection-rtr.tls=true"
|
|
- "traefik.http.routers.changedetection-rtr.service=changedetection-svc"
|
|
- "traefik.http.routers.changedetection-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.changedetection-svc.loadbalancer.server.port=5000"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** WingAudio
|
|
*** =wordpress=
|
|
#+begin_src yaml
|
|
wingaudio:
|
|
container_name: wingaudio
|
|
image: wordpress
|
|
depends_on:
|
|
- wingaudio_db
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
- backend
|
|
volumes:
|
|
- $CONFIGDIR/wingaudio:/var/www/html
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- WORDPRESS_DB_HOST=wingaudio_db
|
|
- WORDPRESS_DB_USER=wingaudio
|
|
- WORDPRESS_DB_PASSWORD=$WINGAUDIO_DB_MYSQL_PASSWORD
|
|
- WORDPRESS_DB_NAME=wingaudio
|
|
user: "${PUID}:${PGID}"
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.wingaudio-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.wingaudio-rtr.rule=Host(`wingaudio.fr`)"
|
|
- "traefik.http.routers.wingaudio-rtr.tls=true"
|
|
- "traefik.http.routers.wingaudio-rtr.service=wingaudio-svc"
|
|
- "traefik.http.services.wingaudio-svc.loadbalancer.server.port=80"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
#+begin_src yaml
|
|
wingaudio_db:
|
|
container_name: wingaudio_db
|
|
image: mysql:5.7
|
|
restart: unless-stopped
|
|
networks:
|
|
- backend
|
|
user: "${PUID}:${PGID}"
|
|
environment:
|
|
- MYSQL_DATABASE=wingaudio
|
|
- MYSQL_USER=wingaudio
|
|
- MYSQL_PASSWORD=$WINGAUDIO_DB_MYSQL_PASSWORD
|
|
- MYSQL_RANDOM_ROOT_PASSWORD=$WINGAUDIO_DB_MYSQL_ROOT_PASSWORD
|
|
volumes:
|
|
- $CONFIGDIR/wingaudio_db:/var/lib/mysql
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** Multimedia
|
|
*** =jellyfin= - Media server ([[https://hub.docker.com/r/linuxserver/jellyfin][link]])
|
|
#+begin_src yaml
|
|
jellyfin:
|
|
container_name: jellyfin
|
|
image: linuxserver/jellyfin
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
volumes:
|
|
- $CONFIGDIR/jellyfin:/config
|
|
- /srv/storage/TVShows:/data/tvshows
|
|
- /srv/storage/Documentaries:/data/documentaries
|
|
- /srv/storage/LiveMusic:/data/livemusic
|
|
- /srv/storage/Animes:/data/animes
|
|
- /srv/storage/Movies:/data/movies
|
|
- /srv/storage/Music:/data/music
|
|
- /srv/storage/StandUp:/data/standup
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
group_add:
|
|
- 109
|
|
devices:
|
|
# VAAPI Devices
|
|
- /dev/dri/renderD128:/dev/dri/renderD128
|
|
- /dev/dri/card0:/dev/dri/card0
|
|
ports:
|
|
- 8096:8096
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.jellyfin-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.jellyfin-rtr.rule=Host(`jellyfin.$DOMAINNAME`)"
|
|
- "traefik.http.routers.jellyfin-rtr.tls=true"
|
|
- "traefik.http.routers.jellyfin-rtr.service=jellyfin-svc"
|
|
- "traefik.http.services.jellyfin-svc.loadbalancer.server.port=8096"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =jfa-go= - Manage Jellyfin Users ([[https://github.com/hrfee/jfa-go][link]])
|
|
#+begin_src yaml
|
|
jfa:
|
|
container_name: jfa
|
|
image: hrfee/jfa-go
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- jellyfin
|
|
networks:
|
|
- t2_proxy
|
|
volumes:
|
|
- $CONFIGDIR/jfa:/data
|
|
- $CONFIGDIR/jellyfin:/jf
|
|
- /etc/localtime:/etc/localtime:ro
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.jfa-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.jfa-rtr.rule=Host(`jfa.$DOMAINNAME`)"
|
|
- "traefik.http.routers.jfa-rtr.tls=true"
|
|
- "traefik.http.routers.jfa-rtr.service=jfa-svc"
|
|
- "traefik.http.services.jfa-svc.loadbalancer.server.port=8056"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** Cloud
|
|
*** =syncthing= - File Synchronization ([[https://hub.docker.com/r/linuxserver/syncthing][link]])
|
|
#+begin_src yaml
|
|
syncthing:
|
|
container_name: syncthing
|
|
image: linuxserver/syncthing
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- UMASK_SET=022
|
|
volumes:
|
|
- $CONFIGDIR/syncthing:/config
|
|
- /srv/storage/Cloud:/Cloud
|
|
- /srv/storage/Cloud/pictures/phone:/Pictures
|
|
- /srv/storage/Cloud/pdfs:/Onyx/Download
|
|
- /srv/storage/Cloud/pdfs-notes:/Onyx/note
|
|
- /srv/storage/Cloud/.stfolder:/Onyx/.stfolder
|
|
- /srv/storage/.password-store:/.password-store
|
|
ports:
|
|
- 22000:22000
|
|
- 21027:21027/udp
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.syncthing-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.syncthing-rtr.rule=Host(`syncthing.$DOMAINNAME`)"
|
|
- "traefik.http.routers.syncthing-rtr.tls=true"
|
|
- "traefik.http.routers.syncthing-rtr.service=syncthing-svc"
|
|
- "traefik.http.routers.syncthing-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.syncthing-svc.loadbalancer.server.port=8384"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =sync-anne= - File Synchronization ([[https://hub.docker.com/r/linuxserver/syncthing][link]])
|
|
#+begin_src yaml
|
|
sync-anne:
|
|
container_name: sync-anne
|
|
image: linuxserver/syncthing
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- UMASK_SET=022
|
|
volumes:
|
|
- $CONFIGDIR/sync-anne:/config
|
|
- /srv/storage/Users/anne:/Cloud
|
|
- /srv/storage/Users/anne/Photos/telephone:/telephone
|
|
ports:
|
|
- 22001:22001
|
|
- 21028:21028/udp
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.sync-anne-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.sync-anne-rtr.rule=Host(`sync-anne.$DOMAINNAME`)"
|
|
- "traefik.http.routers.sync-anne-rtr.tls=true"
|
|
- "traefik.http.routers.sync-anne-rtr.service=sync-anne-svc"
|
|
- "traefik.http.routers.sync-anne-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.sync-anne-svc.loadbalancer.server.port=8384"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =sync-jm= - File Synchronization ([[https://hub.docker.com/r/linuxserver/syncthing][link]])
|
|
#+begin_src yaml
|
|
sync-jm:
|
|
container_name: sync-jm
|
|
image: linuxserver/syncthing
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- UMASK_SET=022
|
|
volumes:
|
|
- $CONFIGDIR/sync-jm:/config
|
|
- /srv/storage/Users/jean-marie:/Cloud
|
|
# - /srv/storage/Users/jean-marie/Photos/telephone:/telephone
|
|
ports:
|
|
- 22002:22002
|
|
- 21029:21029/udp
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.sync-jm-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.sync-jm-rtr.rule=Host(`sync-jm.$DOMAINNAME`)"
|
|
- "traefik.http.routers.sync-jm-rtr.tls=true"
|
|
- "traefik.http.routers.sync-jm-rtr.service=sync-jm-svc"
|
|
- "traefik.http.routers.sync-jm-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.sync-jm-svc.loadbalancer.server.port=8384"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =sync-ju= - File Synchronization ([[https://hub.docker.com/r/linuxserver/syncthing][link]])
|
|
#+begin_src yaml
|
|
sync-ju:
|
|
container_name: sync-ju
|
|
image: linuxserver/syncthing
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- UMASK_SET=022
|
|
volumes:
|
|
- $CONFIGDIR/sync-ju:/config
|
|
- /srv/storage/Users/juliette:/Cloud
|
|
- /srv/storage/Cloud/personnal:/Cloud/Thomas
|
|
ports:
|
|
- 22003:22003
|
|
- 21030:21030/udp
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.sync-ju-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.sync-ju-rtr.rule=Host(`sync-ju.$DOMAINNAME`)"
|
|
- "traefik.http.routers.sync-ju-rtr.tls=true"
|
|
- "traefik.http.routers.sync-ju-rtr.service=sync-ju-svc"
|
|
- "traefik.http.routers.sync-ju-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.sync-ju-svc.loadbalancer.server.port=8384"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =filebrowser= - Web file browser ([[https://hub.docker.com/r/filebrowser/filebrowser][link]])
|
|
#+begin_src yaml
|
|
filebrowser:
|
|
container_name: filebrowser
|
|
image: filebrowser/filebrowser
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
volumes:
|
|
- $CONFIGDIR/filebrowser/database.db:/database.db
|
|
- $CONFIGDIR/filebrowser/.filebrowser.json:/.filebrowser.json
|
|
- /srv/storage:/srv/storage
|
|
user: "${PUID}:${PGID}"
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.filebrowser-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.filebrowser-rtr.rule=Host(`cloud.$DOMAINNAME`)"
|
|
- "traefik.http.routers.filebrowser-rtr.tls=true"
|
|
- "traefik.http.routers.filebrowser-rtr.service=filebrowser-svc"
|
|
- "traefik.http.services.filebrowser-svc.loadbalancer.server.port=80"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
=.filebrowser.json=
|
|
|
|
#+begin_src json :tangle /ssh:thomas@homelab:/home/thomas/docker/config/filebrowser/.filebrowser.json
|
|
{
|
|
"port": 80,
|
|
"baseURL": "",
|
|
"address": "",
|
|
"log": "stdout",
|
|
"database": "/database.db",
|
|
"root": "/srv/storage"
|
|
}
|
|
#+end_src
|
|
|
|
*** =radicale= - CalDAV/CardDAV server ([[https://github.com/tomsquest/docker-radicale][link]])
|
|
#+begin_src yaml
|
|
radicale:
|
|
container_name: radicale
|
|
image: tomsquest/docker-radicale
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
volumes:
|
|
- $CONFIGDIR/radicale/config:/config:ro
|
|
- $CONFIGDIR/radicale/data:/data
|
|
environment:
|
|
- TZ=$TZ
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
cap_drop:
|
|
- ALL
|
|
cap_add:
|
|
- SETUID
|
|
- SETGID
|
|
- CHOWN
|
|
- KILL
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.radicale-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.radicale-rtr.rule=Host(`radicale.$DOMAINNAME`)"
|
|
- "traefik.http.routers.radicale-rtr.tls=true"
|
|
- "traefik.http.routers.radicale-rtr.service=radicale-svc"
|
|
- "traefik.http.services.radicale-svc.loadbalancer.server.port=5232"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
=config=
|
|
#+begin_src conf :tangle /ssh:thomas@homelab:/home/thomas/docker/config/radicale/config/config
|
|
[server]
|
|
hosts = 0.0.0.0:5232
|
|
|
|
[auth]
|
|
type = htpasswd
|
|
htpasswd_filename = /config/users
|
|
htpasswd_encryption = md5
|
|
|
|
[storage]
|
|
filesystem_folder = /data/collections
|
|
#+end_src
|
|
|
|
*** =linkding= - Bookmark manager ([[https://github.com/sissbruecker/linkding][link]])
|
|
#+begin_src yaml
|
|
linkding:
|
|
container_name: linkding
|
|
image: sissbruecker/linkding
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
volumes:
|
|
- $CONFIGDIR/linkding:/etc/linkding/data
|
|
user: "${PUID}:${PGID}"
|
|
environment:
|
|
- TZ=$TZ
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.linkding-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.linkding-rtr.rule=Host(`bm.$DOMAINNAME`)"
|
|
- "traefik.http.routers.linkding-rtr.tls=true"
|
|
- "traefik.http.routers.linkding-rtr.service=linkding-svc"
|
|
- "traefik.http.services.linkding-svc.loadbalancer.server.port=9090"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =restic-hc4= - Automatic backups on Odroid HC4 ([[https://github.com/djmaze/resticker/][link]])
|
|
#+begin_src yaml
|
|
restic-hc4:
|
|
container_name: restic-hc4
|
|
image: mazzolino/restic
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- BACKUP_CRON=0 14 * * * # Backup at 3am every day
|
|
- RESTIC_REPOSITORY=sftp://thomas@pierrick.tdehaeze.xyz:10022//srv/storage/backup
|
|
- RESTIC_PASSWORD=$RESTIC_PASSWORD
|
|
- RESTIC_BACKUP_SOURCES=/source
|
|
- RESTIC_FORGET_ARGS=--group-by tag --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune
|
|
- RESTIC_BACKUP_ARGS=--tag local --exclude-file /exclude.txt --verbose
|
|
- RESTIC_GOTIFY_TOKEN=$RESTIC_GOTIFY_TOKEN
|
|
- SUCCESS_ON_INCOMPLETE_BACKUP="true"
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
- POST_COMMANDS_FAILURE=curl "https://gotify.tdehaeze.xyz/message?token=$RESTIC_GOTIFY_TOKEN" -F "title=Restic HC4" -F "message=Backup failed" -F "priority=5"
|
|
- POST_COMMANDS_EXIT=ssh -p 10022 thomas@pierrick.tdehaeze.xyz "sudo systemctl poweroff"
|
|
volumes:
|
|
- $CONFIGDIR/restic-hc4/exclude.txt:/exclude.txt:ro
|
|
- /srv/storage/Users:/source/Users:ro # User Clouds
|
|
- /srv/storage/Cloud:/source/Cloud:ro # My Own Cloud
|
|
- /srv/storage/Music:/source/Music:ro # Musics
|
|
- /home/thomas:/source/home:ro # Homelab - home directory
|
|
- /home/thomas/.ssh/known_hosts:/root/.ssh/known_hosts:ro
|
|
- /home/thomas/.ssh/id_rsa:/root/.ssh/id_rsa:ro
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
=exclude.txt= - Exclude files
|
|
|
|
#+begin_src conf :tangle /ssh:thomas@homelab:/home/thomas/docker/config/restic-hc4/exclude.txt
|
|
*.db
|
|
*.log
|
|
*.log.*
|
|
#+end_src
|
|
|
|
*** =miniflux= - RSS reader ([[https://hub.docker.com/r/miniflux/miniflux][link]])
|
|
#+begin_src yaml
|
|
miniflux:
|
|
container_name: miniflux
|
|
image: miniflux/miniflux
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
- backend
|
|
depends_on:
|
|
- miniflux_db
|
|
environment:
|
|
- DATABASE_URL=postgres://miniflux:SCJWWXqHwehP7f8g@miniflux_db/miniflux?sslmode=disable
|
|
- RUN_MIGRATIONS=1
|
|
- CREATE_ADMIN=1
|
|
- ADMIN_USERNAME=$MINIFLUX_ADMIN_NAME
|
|
- ADMIN_PASSWORD=$MINIFLUX_ADMIN_PASS
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.miniflux-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.miniflux-rtr.rule=Host(`rss.$DOMAINNAME`)"
|
|
- "traefik.http.routers.miniflux-rtr.tls=true"
|
|
- "traefik.http.routers.miniflux-rtr.service=miniflux-svc"
|
|
- "traefik.http.services.miniflux-svc.loadbalancer.server.port=8080"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
#+begin_src yaml
|
|
miniflux_db:
|
|
container_name: miniflux_db
|
|
image: postgres:12
|
|
restart: unless-stopped
|
|
networks:
|
|
- backend
|
|
user: "${PUID}:${PGID}"
|
|
environment:
|
|
- POSTGRES_USER=miniflux
|
|
- POSTGRES_PASSWORD=$MINIFLUX_POSTGRES_PASSWORD
|
|
volumes:
|
|
- $CONFIGDIR/miniflux_db:/var/lib/postgresql/data
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** Home
|
|
*** =mosquitto= - MQTT broker ([[https://github.com/eclipse/mosquitto/][link]])
|
|
#+begin_src yaml
|
|
mosquitto:
|
|
container_name: mosquitto
|
|
image: eclipse-mosquitto
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
expose:
|
|
- 1883
|
|
- 9001
|
|
ports:
|
|
- 1883:1883
|
|
- 9001:9001
|
|
volumes:
|
|
- $CONFIGDIR/mosquitto/config:/mosquitto/config
|
|
- $CONFIGDIR/mosquitto/log:/mosquitto/log
|
|
- $CONFIGDIR/mosquitto/data:/mosquitto/data
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =zigbee2mqtt= - Zigbee to MQTT bridge ([[https://github.com/Koenkk/zigbee2mqtt/][link]])
|
|
In =/etc/udev/rules.d/99-usb-serial.rules=:
|
|
#+begin_src conf :tangle no
|
|
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="zigbee/slaesh"
|
|
#+end_src
|
|
|
|
#+begin_src yaml
|
|
zigbee2mqtt:
|
|
container_name: zigbee2mqtt
|
|
image: koenkk/zigbee2mqtt
|
|
restart: unless-stopped
|
|
privileged: true
|
|
depends_on:
|
|
- mosquitto
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/zigbee2mqtt:/app/data
|
|
- /run/udev:/run/udev:ro
|
|
- /dev/zigbee:/dev/zigbee:ro
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.zigbee2mqtt-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.zigbee2mqtt-rtr.rule=Host(`zigbee2mqtt.$DOMAINNAME`)"
|
|
- "traefik.http.routers.zigbee2mqtt-rtr.tls=true"
|
|
- "traefik.http.routers.zigbee2mqtt-rtr.service=zigbee2mqtt-svc"
|
|
- "traefik.http.routers.zigbee2mqtt-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.zigbee2mqtt-svc.loadbalancer.server.port=8080"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =node-red= - Automation tool
|
|
#+begin_src yaml
|
|
node-red:
|
|
container_name: node-red
|
|
image: nodered/node-red
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/node-red:/data
|
|
ports:
|
|
- 1880:1880
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.node-red-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.node-red-rtr.rule=Host(`node-red.$DOMAINNAME`)"
|
|
- "traefik.http.routers.node-red-rtr.tls=true"
|
|
- "traefik.http.routers.node-red-rtr.service=node-red-svc"
|
|
- "traefik.http.routers.node-red-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.node-red-svc.loadbalancer.server.port=1880"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =esphome= - Automation tool
|
|
#+begin_src yaml
|
|
esphome:
|
|
container_name: esphome
|
|
image: esphome/esphome
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- ESPHOME_DASHBOARD_USE_PING=true
|
|
volumes:
|
|
- $CONFIGDIR/esphome:/config
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.esphome-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.esphome-rtr.rule=Host(`esphome.$DOMAINNAME`)"
|
|
- "traefik.http.routers.esphome-rtr.tls=true"
|
|
- "traefik.http.routers.esphome-rtr.service=esphome-svc"
|
|
- "traefik.http.routers.esphome-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.esphome-svc.loadbalancer.server.port=6052"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =tina2= - Web interface for 3D printing ([[https://github.com/OctoPrint/OctoPrint][link]])
|
|
In order for the 3D printer to always have the same =/dev/path=, =sudoedit /etc/udev/rules.d/99-usb-serial.rules=:
|
|
#+begin_src conf :tangle no
|
|
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="3d-printer/tina2"
|
|
#+end_src
|
|
|
|
#+begin_src yaml
|
|
tina2:
|
|
container_name: tina2
|
|
image: octoprint/octoprint
|
|
restart: unless-stopped
|
|
privileged: true
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/tina2:/octoprint
|
|
- /run/udev:/run/udev:ro
|
|
- /dev/3d-printer:/dev/3d-printer:ro
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.tina2-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.tina2-rtr.rule=Host(`3d-printer.$DOMAINNAME`)"
|
|
- "traefik.http.routers.tina2-rtr.tls=true"
|
|
- "traefik.http.routers.tina2-rtr.service=tina2-svc"
|
|
- "traefik.http.services.tina2-svc.loadbalancer.server.port=80"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** Photo - Immich
|
|
*** =immich-proxy=
|
|
#+begin_src yaml
|
|
immich-proxy:
|
|
container_name: immich-proxy
|
|
image: ghcr.io/immich-app/immich-proxy:release
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
- immich
|
|
environment:
|
|
# Make sure these values get passed through from the env file
|
|
- IMMICH_SERVER_URL
|
|
- IMMICH_WEB_URL
|
|
depends_on:
|
|
- immich-server
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.immich-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.immich-rtr.rule=Host(`immich.$DOMAINNAME`)"
|
|
- "traefik.http.routers.immich-rtr.tls=true"
|
|
- "traefik.http.routers.immich-rtr.service=immich-svc"
|
|
- "traefik.http.services.immich-svc.loadbalancer.server.port=8080"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =immich-server=
|
|
#+begin_src yaml
|
|
immich-server:
|
|
container_name: immich-server
|
|
image: ghcr.io/immich-app/immich-server:release
|
|
restart: unless-stopped
|
|
entrypoint: ["/bin/sh", "./start-server.sh"]
|
|
networks:
|
|
- immich
|
|
volumes:
|
|
- /srv/storage/immich:/usr/src/app/upload
|
|
env_file:
|
|
- immich.env
|
|
depends_on:
|
|
- immich-redis
|
|
- immich-database
|
|
- immich-typesense
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =immich-microservices=
|
|
#+begin_src yaml
|
|
immich-microservices:
|
|
container_name: immich-microservices
|
|
image: ghcr.io/immich-app/immich-server:release
|
|
restart: unless-stopped
|
|
command: ["start.sh", "microservices"]
|
|
networks:
|
|
- immich
|
|
volumes:
|
|
- /srv/storage/immich:/usr/src/app/upload
|
|
env_file:
|
|
- immich.env
|
|
depends_on:
|
|
- immich-redis
|
|
- immich-database
|
|
- immich-typesense
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =immich-machine-learning=
|
|
#+begin_src yaml
|
|
immich-machine-learning:
|
|
container_name: immich-machine-learning
|
|
image: ghcr.io/immich-app/immich-machine-learning:release
|
|
restart: unless-stopped
|
|
networks:
|
|
- immich
|
|
volumes:
|
|
- /srv/storage/immich:/usr/src/app/upload
|
|
- $CONFIGDIR/immich/machine-learning-cache:/cache
|
|
env_file:
|
|
- immich.env
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =immich-web=
|
|
#+begin_src yaml
|
|
immich-web:
|
|
container_name: immich-web
|
|
image: ghcr.io/immich-app/immich-web:release
|
|
restart: unless-stopped
|
|
networks:
|
|
- immich
|
|
env_file:
|
|
- immich.env
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =immich-typesense=
|
|
#+begin_src yaml
|
|
immich-typesense:
|
|
container_name: immich-typesense
|
|
image: typesense/typesense:0.24.1@sha256:9bcff2b829f12074426ca044b56160ca9d777a0c488303469143dd9f8259d4dd
|
|
restart: unless-stopped
|
|
networks:
|
|
- immich
|
|
env_file:
|
|
- immich.env
|
|
environment:
|
|
- TYPESENSE_DATA_DIR=/data
|
|
volumes:
|
|
- $CONFIGDIR/immich/typesense-data:/data
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =immich-redis=
|
|
#+begin_src yaml
|
|
immich-redis:
|
|
container_name: immich-redis
|
|
image: redis:6.2-alpine@sha256:70a7a5b641117670beae0d80658430853896b5ef269ccf00d1827427e3263fa3
|
|
|
|
restart: unless-stopped
|
|
networks:
|
|
- immich
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =immich-database=
|
|
#+begin_src yaml
|
|
immich-database:
|
|
container_name: immich-database
|
|
image: postgres:14-alpine@sha256:28407a9961e76f2d285dc6991e8e48893503cc3836a4755bbc2d40bcc272a441
|
|
restart: unless-stopped
|
|
networks:
|
|
- immich
|
|
env_file:
|
|
- immich.env
|
|
environment:
|
|
- POSTGRES_PASSWORD=$${DB_PASSWORD}
|
|
- POSTGRES_USER=$${DB_USERNAME}
|
|
- POSTGRES_DB=$${DB_DATABASE_NAME}
|
|
- PG_DATA=/var/lib/postgresql/data
|
|
volumes:
|
|
- $CONFIGDIR/immich/postgresql-data:/var/lib/postgresql/data
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =immich.env=
|
|
:PROPERTIES:
|
|
:header-args: :tangle /ssh:thomas@homelab:~/docker/immich.env
|
|
:header-args+: :comments none :mkdirp yes :noweb yes
|
|
:END:
|
|
|
|
#+begin_src conf
|
|
###################################################################################
|
|
# Database
|
|
###################################################################################
|
|
|
|
DB_HOSTNAME=immich-database
|
|
DB_USERNAME=postgres
|
|
DB_PASSWORD=aC2fdTEHiRcrb0U5
|
|
DB_DATABASE_NAME=immich
|
|
|
|
# Optional Database settings:
|
|
# DB_PORT=5432
|
|
|
|
###################################################################################
|
|
# Redis
|
|
###################################################################################
|
|
|
|
REDIS_HOSTNAME=immich-redis
|
|
|
|
###################################################################################
|
|
# Log message level - [simple|verbose]
|
|
###################################################################################
|
|
|
|
LOG_LEVEL=simple
|
|
|
|
###################################################################################
|
|
# Typesense
|
|
###################################################################################
|
|
TYPESENSE_ENABLED=true
|
|
TYPESENSE_API_KEY=I7kSTDznqhmIcjPB
|
|
TYPESENSE_HOST=immich-typesense
|
|
# TYPESENSE_PORT: 8108
|
|
# TYPESENSE_PROTOCOL: http
|
|
|
|
####################################################################################
|
|
# Alternative Service Addresses - Optional
|
|
#
|
|
# This is an advanced feature for users who may be running their immich services on different hosts.
|
|
# It will not change which address or port that services bind to within their containers, but it will change where other services look for their peers.
|
|
# Note: immich-microservices is bound to 3002, but no references are made
|
|
####################################################################################
|
|
|
|
IMMICH_WEB_URL=http://immich-web:3000
|
|
IMMICH_SERVER_URL=http://immich-server:3001
|
|
IMMICH_MACHINE_LEARNING_URL=http://immich-machine-learning:3003
|
|
|
|
####################################################################################
|
|
# Alternative API's External Address - Optional
|
|
#
|
|
# This is an advanced feature used to control the public server endpoint returned to clients during Well-known discovery.
|
|
# You should only use this if you want mobile apps to access the immich API over a custom URL. Do not include trailing slash.
|
|
# NOTE: At this time, the web app will not be affected by this setting and will continue to use the relative path: /api
|
|
# Examples: http://localhost:3001, http://immich-api.example.com, etc
|
|
####################################################################################
|
|
|
|
#IMMICH_API_URL_EXTERNAL=http://localhost:3001
|
|
#+end_src
|
|
|
|
** Download
|
|
*** =transmission-openvpn= - Torrent server ([[https://hub.docker.com/r/haugene/transmission-openvpn][link]])
|
|
#+begin_src yaml
|
|
transmission:
|
|
container_name: transmission
|
|
image: haugene/transmission-openvpn
|
|
cap_add:
|
|
- NET_ADMIN
|
|
networks:
|
|
- t2_proxy
|
|
sysctls:
|
|
- net.ipv6.conf.all.disable_ipv6=0
|
|
restart: unless-stopped
|
|
ports:
|
|
- 9091:9091
|
|
dns:
|
|
- 8.8.8.8
|
|
- 8.8.4.4
|
|
volumes:
|
|
- /etc/localtime:/etc/localtime:ro
|
|
- $CONFIGDIR/transmission:/config
|
|
- /srv/storage/Downloads:/data
|
|
- /srv/storage/Downloads/watch:/watch
|
|
environment:
|
|
- CREATE_TUN_DEVICE=true
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TRANSMISSION_WEB_UI=flood-for-transmission
|
|
- LOCAL_NETWORK=192.168.0.0/16
|
|
- OPENVPN_PROVIDER=NORDVPN
|
|
- OPENVPN_USERNAME=$NORDVPN_NAME
|
|
- OPENVPN_PASSWORD=$NORDVPN_PASS
|
|
- NORDVPN_COUNTRY=FR
|
|
- NORDVPN_CATEGORY=legacy_p2p
|
|
- NORDVPN_PROTOCOL=udp
|
|
- TRANSMISSION_UTP_ENABLED=false
|
|
- TRANSMISSION_RPC_AUTHENTICATION_REQUIRED=true
|
|
- TRANSMISSION_RPC_USERNAME=$TRANSMISSION_NAME
|
|
- TRANSMISSION_RPC_PASSWORD=$TRANSMISSION_PASS
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.docker.network=t2_proxy"
|
|
- "traefik.http.routers.transmission-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.transmission-rtr.rule=Host(`torrent.$DOMAINNAME`)"
|
|
- "traefik.http.routers.transmission-rtr.tls=true"
|
|
- "traefik.http.routers.transmission-rtr.service=transmission-svc"
|
|
- "traefik.http.services.transmission-svc.loadbalancer.server.port=9091"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =flaresolverr= - Proxy server to bypass Cloudflare protection ([[https://github.com/FlareSolverr/FlareSolverr][link]]) :noexport:
|
|
#+begin_src yaml
|
|
flaresolverr:
|
|
container_name: flaresolverr
|
|
image: ghcr.io/flaresolverr/flaresolverr:latest
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- LOG_LEVEL=info
|
|
- LOG_HTML=false
|
|
- CAPTCHA_SOLVER=none
|
|
- TZ=$TZ
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.flaresolverr-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.flaresolverr-rtr.rule=Host(`flaresolverr.$DOMAINNAME`)"
|
|
- "traefik.http.routers.flaresolverr-rtr.tls=true"
|
|
# - "traefik.http.routers.flaresolverr-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.routers.flaresolverr-rtr.service=flaresolverr-svc"
|
|
- "traefik.http.services.flaresolverr-svc.loadbalancer.server.port=8191"
|
|
#+end_src
|
|
|
|
|
|
*** =prowlarr= - API support for torrents ([[https://github.com/Prowlarr/Prowlarr][link]]) :noexport:
|
|
#+begin_src yaml
|
|
prowlarr:
|
|
container_name: prowlarr
|
|
image: lscr.io/linuxserver/prowlarr:develop
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- AUTO_UPDATE=true
|
|
volumes:
|
|
- $CONFIGDIR/prowlarr:/config
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.prowlarr-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.prowlarr-rtr.rule=Host(`prowlarr.$DOMAINNAME`)"
|
|
- "traefik.http.routers.prowlarr-rtr.tls=true"
|
|
# - "traefik.http.routers.prowlarr-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.routers.prowlarr-rtr.service=prowlarr-svc"
|
|
- "traefik.http.services.prowlarr-svc.loadbalancer.server.port=9696"
|
|
#+end_src
|
|
|
|
*** =jellyseerr= - Managing requests for the media library ([[https://github.com/Fallenbagel/jellyseerr][link]]) :noexport:
|
|
#+begin_src yaml
|
|
jellyseerr:
|
|
container_name: jellyseerr
|
|
image: fallenbagel/jellyseerr
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/jellyseerr:/app/config
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.jellyseerr-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.jellyseerr-rtr.rule=Host(`jellyseerr.$DOMAINNAME`)"
|
|
- "traefik.http.routers.jellyseerr-rtr.tls=true"
|
|
# - "traefik.http.routers.jellyseerr-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.routers.jellyseerr-rtr.service=jellyseerr-svc"
|
|
- "traefik.http.services.jellyseerr-svc.loadbalancer.server.port=5055"
|
|
#+end_src
|
|
|
|
*** =qobuz= - Qobuz Downloader ([[https://github.com/tdehaeze/qobuz-docker][link]]) :noexport:
|
|
#+begin_src yaml
|
|
qobuz:
|
|
container_name: qobuz
|
|
image: tdehaeze/docker-qobuz
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
volumes:
|
|
- /srv/storage/Music:/downloads
|
|
environment:
|
|
- TZ=$TZ
|
|
- QOBUZNAME=$QOBUZNAME
|
|
- QOBUZPASS=$QOBUZPASS
|
|
- DOWNLOADDIR=/downloads
|
|
- JELLYFINURL=https://jellyfin.tdehaeze.xyz/library/refresh
|
|
- JELLYFINTOKEN=$JELLYFINTOKEN
|
|
- NOTIF_TYPE=gotify
|
|
- GOTIFY_URL=$GOTIFY_URL
|
|
- GOTIFY_TOKEN=$QOBUZ_GOTIFY_TOKEN
|
|
user: "${PUID}:${PGID}"
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.qobuz-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.qobuz-rtr.rule=Host(`qobuz.$DOMAINNAME`)"
|
|
- "traefik.http.routers.qobuz-rtr.tls=true"
|
|
- "traefik.http.routers.qobuz-rtr.service=qobuz-svc"
|
|
- "traefik.http.routers.qobuz-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.qobuz-svc.loadbalancer.server.port=8080"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =sonarr= - Automatically download TVshows ([[https://github.com/Sonarr/Sonarr][link]]) :noexport:
|
|
#+begin_src yaml
|
|
sonarr:
|
|
container_name: sonarr
|
|
image: lscr.io/linuxserver/sonarr
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- UMASK_SET=022
|
|
volumes:
|
|
- $CONFIGDIR/sonarr:/config
|
|
- /srv/storage/TVShows:/data/tv
|
|
- /srv/storage/Animes:/data/animes
|
|
- /srv/storage/Downloads:/data/downloads
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.sonarr-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.sonarr-rtr.rule=Host(`sonarr.$DOMAINNAME`)"
|
|
- "traefik.http.routers.sonarr-rtr.tls=true"
|
|
- "traefik.http.routers.sonarr-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.routers.sonarr-rtr.service=sonarr-svc"
|
|
- "traefik.http.services.sonarr-svc.loadbalancer.server.port=8989"
|
|
#+end_src
|
|
|
|
*** =radarr= - Automatically download Movies ([[https://github.com/Radarr/Radarr][link]]) :noexport:
|
|
#+begin_src yaml
|
|
radarr:
|
|
container_name: radarr
|
|
image: lscr.io/linuxserver/radarr
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- UMASK_SET=022
|
|
volumes:
|
|
- $CONFIGDIR/radarr:/config
|
|
- /srv/storage/Movies:/movies
|
|
- /srv/storage/Downloads:/downloads
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.radarr-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.radarr-rtr.rule=Host(`radarr.$DOMAINNAME`)"
|
|
- "traefik.http.routers.radarr-rtr.tls=true"
|
|
- "traefik.http.routers.radarr-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.routers.radarr-rtr.service=radarr-svc"
|
|
- "traefik.http.services.radarr-svc.loadbalancer.server.port=7878"
|
|
#+end_src
|
|
|
|
* Docker-Compose OLD :noexport:
|
|
** =metube= - Download Youtube Videos ([[https://github.com/alexta69/metube][link]])
|
|
#+begin_src yaml
|
|
metube:
|
|
container_name: metube
|
|
image: alexta69/metube
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- STATE_DIR=/statedir
|
|
user: "1000:1000"
|
|
volumes:
|
|
- /srv/storage/Downloads/youtube:/downloads
|
|
- $CONFIGDIR/metube:/statedir
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.metube-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.metube-rtr.rule=Host(`metube.$DOMAINNAME`)"
|
|
- "traefik.http.routers.metube-rtr.tls=true"
|
|
# - "traefik.http.routers.metube-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.routers.metube-rtr.service=metube-svc"
|
|
- "traefik.http.services.metube-svc.loadbalancer.server.port=8081"
|
|
#+end_src
|
|
|
|
** =navidrome= - Music server
|
|
#+begin_src yaml
|
|
navidrome:
|
|
container_name: navidrome
|
|
image: deluan/navidrome
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
volumes:
|
|
- $CONFIGDIR/navidrome:/data
|
|
- /srv/storage/Music:/music:ro
|
|
environment:
|
|
- ND_MUSICFOLDER=/music
|
|
- ND_DATAFOLDER=/data
|
|
- ND_SCANINTERVAL=10m
|
|
- ND_LOGLEVEL=info
|
|
- ND_PORT=4533
|
|
- ND_TRANSCODINGCACHESIZE=100MB
|
|
- ND_SESSIONTIMEOUT=24h
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.navidrome-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.navidrome-rtr.rule=Host(`navidrome.$DOMAINNAME`)"
|
|
- "traefik.http.routers.navidrome-rtr.tls=true"
|
|
- "traefik.http.routers.navidrome-rtr.service=navidrome-svc"
|
|
- "traefik.http.services.navidrome-svc.loadbalancer.server.port=4533"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** Affichtoo
|
|
*** =japonais= - Affichtoo
|
|
#+begin_src yaml
|
|
affichtoo-japonais:
|
|
container_name: affichtoo-japonais
|
|
image: tdehaeze/affichtoo
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/affichtoo/japonais:/app/static/conf
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.japonais-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.japonais-rtr.rule=Host(`japonais.$DOMAINNAME`)"
|
|
- "traefik.http.routers.japonais-rtr.tls=true"
|
|
- "traefik.http.routers.japonais-rtr.service=japonais-svc"
|
|
- "traefik.http.services.japonais-svc.loadbalancer.server.port=8000"
|
|
# - "traefik.http.routers.japonais-rtr.middlewares=japonais-auth"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =creperie= - Affichtoo
|
|
#+begin_src yaml
|
|
affichtoo-creperie:
|
|
container_name: affichtoo-creperie
|
|
image: tdehaeze/affichtoo
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/affichtoo/creperie:/app/static/conf
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.creperie-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.creperie-rtr.rule=Host(`creperie.$DOMAINNAME`)"
|
|
- "traefik.http.routers.creperie-rtr.tls=true"
|
|
- "traefik.http.routers.creperie-rtr.service=creperie-svc"
|
|
- "traefik.http.services.creperie-svc.loadbalancer.server.port=8000"
|
|
# - "traefik.http.routers.creperie-rtr.middlewares=creperie-auth"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =burger= - Affichtoo
|
|
#+begin_src yaml
|
|
affichtoo-burger:
|
|
container_name: affichtoo-burger
|
|
image: tdehaeze/affichtoo
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/affichtoo/burger:/app/static/conf
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.burger-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.burger-rtr.rule=Host(`burger.$DOMAINNAME`)"
|
|
- "traefik.http.routers.burger-rtr.tls=true"
|
|
- "traefik.http.routers.burger-rtr.service=burger-svc"
|
|
- "traefik.http.services.burger-svc.loadbalancer.server.port=8000"
|
|
# - "traefik.http.routers.burger-rtr.middlewares=burger-auth"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =indien= - Affichtoo
|
|
#+begin_src yaml
|
|
affichtoo-indien:
|
|
container_name: affichtoo-indien
|
|
image: tdehaeze/affichtoo
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/affichtoo/indien:/app/static/conf
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.indien-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.indien-rtr.rule=Host(`indien.$DOMAINNAME`)"
|
|
- "traefik.http.routers.indien-rtr.tls=true"
|
|
- "traefik.http.routers.indien-rtr.service=indien-svc"
|
|
- "traefik.http.services.indien-svc.loadbalancer.server.port=8000"
|
|
# - "traefik.http.routers.indien-rtr.middlewares=indien-auth"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =italien= - Affichtoo
|
|
#+begin_src yaml
|
|
affichtoo-italien:
|
|
container_name: affichtoo-italien
|
|
image: tdehaeze/affichtoo
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/affichtoo/italien:/app/static/conf
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.italien-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.italien-rtr.rule=Host(`italien.$DOMAINNAME`)"
|
|
- "traefik.http.routers.italien-rtr.tls=true"
|
|
- "traefik.http.routers.italien-rtr.service=italien-svc"
|
|
- "traefik.http.services.italien-svc.loadbalancer.server.port=8000"
|
|
# - "traefik.http.routers.italien-rtr.middlewares=italien-auth"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =libanais= - Affichtoo
|
|
#+begin_src yaml
|
|
affichtoo-libanais:
|
|
container_name: affichtoo-libanais
|
|
image: tdehaeze/affichtoo
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/affichtoo/libanais:/app/static/conf
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.libanais-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.libanais-rtr.rule=Host(`libanais.$DOMAINNAME`)"
|
|
- "traefik.http.routers.libanais-rtr.tls=true"
|
|
- "traefik.http.routers.libanais-rtr.service=libanais-svc"
|
|
- "traefik.http.services.libanais-svc.loadbalancer.server.port=8000"
|
|
# - "traefik.http.routers.libanais-rtr.middlewares=libanais-auth"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =wishlist=
|
|
#+begin_src yaml
|
|
wishlist:
|
|
container_name: wishlist
|
|
image: wingysam/christmas-community
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
- SITE_TITLE=Ma Liste d'Envies
|
|
- SHORT_TITLE=Wishlist
|
|
- BULMASWATCH=Minty
|
|
- PFP=false
|
|
- LANGUAGE=fr-FR
|
|
- SINGLE_LIST=false
|
|
- LISTS_PUBLIC=true
|
|
- SMILE=false
|
|
- TABLE=true
|
|
volumes:
|
|
- $CONFIGDIR/wishlist:/data
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.wishlist-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.wishlist-rtr.rule=Host(`wishlist.$DOMAINNAME`)"
|
|
- "traefik.http.routers.wishlist-rtr.tls=true"
|
|
- "traefik.http.routers.wishlist-rtr.service=wishlist-svc"
|
|
- "traefik.http.services.wishlist-svc.loadbalancer.server.port=80"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =ihatemoney=
|
|
#+begin_src yaml
|
|
ihatemoney:
|
|
image: ihatemoney/ihatemoney:6.1.0
|
|
container_name: ihatemoney
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- PORT=8000
|
|
- ACTIVATE_DEMO_PROJECT=False
|
|
volumes:
|
|
- $CONFIGDIR/ihatemoney:/database
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.ihatemoney-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.ihatemoney-rtr.rule=Host(`ihatemoney.$DOMAINNAME`)"
|
|
- "traefik.http.routers.ihatemoney-rtr.tls=true"
|
|
- "traefik.http.routers.ihatemoney-rtr.service=ihatemoney-svc"
|
|
- "traefik.http.services.ihatemoney-svc.loadbalancer.server.port=8000"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =adguardhome= - Network-wide ads & trackers blocking DNS server ([[https://github.com/AdguardTeam/AdGuardHome][link]])
|
|
#+begin_src yaml :tangle no
|
|
adguardhome:
|
|
container_name: adguardhome
|
|
image: adguard/adguardhome
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/adguardhome/work:/opt/adguardhome/work
|
|
- $CONFIGDIR/adguardhome/conf:/opt/adguardhome/conf
|
|
ports:
|
|
- 53:53/tcp
|
|
- 53:53/udp
|
|
# - 853:853
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.adguardhome-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.adguardhome-rtr.rule=Host(`adguardhome.$DOMAINNAME`)"
|
|
- "traefik.http.routers.adguardhome-rtr.tls=true"
|
|
- "traefik.http.routers.adguardhome-rtr.service=adguardhome-svc"
|
|
- "traefik.http.routers.adguardhome-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.adguardhome-svc.loadbalancer.server.port=3000"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =joal= - Seeding Torrents ([[https://github.com/anthonyraymond/joal][link]]) :noexport:
|
|
#+begin_src yaml :tangle no
|
|
joal:
|
|
image: anthonyraymond/joal
|
|
container_name: joal
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
volumes:
|
|
- $CONFIGDIR/joal:/data
|
|
command: ["--joal-conf=/data", "--spring.main.web-environment=true", "--server.port=80", "--joal.ui.path.prefix=joal", "--joal.ui.secret-token=$JOALTOKEN"]
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.joal-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.joal-rtr.rule=Host(`joal.$DOMAINNAME`)"
|
|
- "traefik.http.routers.joal-rtr.tls=true"
|
|
- "traefik.http.routers.joal-rtr.service=joal-svc"
|
|
- "traefik.http.routers.joal-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.joal-svc.loadbalancer.server.port=80"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =jackett= - API support for torrents ([[https://github.com/Jackett/Jackett][link]])
|
|
#+begin_src yaml :tangle no
|
|
jackett:
|
|
container_name: jackett
|
|
image: lscr.io/linuxserver/jackett
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- AUTO_UPDATE=true
|
|
volumes:
|
|
- $CONFIGDIR/jackett:/config
|
|
- /srv/storage/Downloads:/downloads
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.jackett-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.jackett-rtr.rule=Host(`jackett.$DOMAINNAME`)"
|
|
- "traefik.http.routers.jackett-rtr.tls=true"
|
|
- "traefik.http.routers.jackett-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.routers.jackett-rtr.service=jackett-svc"
|
|
- "traefik.http.services.jackett-svc.loadbalancer.server.port=9117"
|
|
#+end_src
|
|
|
|
** =portainer= - Manage docker ([[https://github.com/portainer/portainer][link]])
|
|
#+begin_src yaml :tangle no
|
|
portainer:
|
|
container_name: portainer
|
|
image: portainer/portainer
|
|
restart: unless-stopped
|
|
command: -H unix:///var/run/docker.sock
|
|
networks:
|
|
- t2_proxy
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
- $CONFIGDIR/portainer:/data
|
|
environment:
|
|
- TZ=$TZ
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.portainer-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.portainer-rtr.rule=Host(`portainer.$DOMAINNAME`)"
|
|
- "traefik.http.routers.portainer-rtr.tls=true"
|
|
- "traefik.http.routers.portainer-rtr.service=portainer-svc"
|
|
- "traefik.http.routers.portainer-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.portainer-svc.loadbalancer.server.port=9000"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =ddns= - Dynamic DNS Server
|
|
#+begin_src yaml :tangle no
|
|
ddns:
|
|
container_name: ddns
|
|
image: davd/docker-ddns
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- RECORD_TTL=60
|
|
- ZONE=example.org
|
|
- SHARED_SECRET=9Kzd9vSyPQuO4CPO
|
|
# volumes:
|
|
# - ./bind-data:/var/cache/bind
|
|
ports:
|
|
- "53:53"
|
|
- "53:53/udp"
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.ddns-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.ddns-rtr.rule=Host(`ddns.$DOMAINNAME`)"
|
|
- "traefik.http.routers.ddns-rtr.tls=true"
|
|
- "traefik.http.routers.ddns-rtr.service=ddns-svc"
|
|
- "traefik.http.services.ddns-svc.loadbalancer.server.port=8080"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =docker-torrent= - Download Torrents from YGG ([[https://github.com/tdehaeze/qobuz-docker][link]])
|
|
#+begin_src yaml
|
|
down:
|
|
container_name: down
|
|
image: tdehaeze/docker-torrent
|
|
restart: always
|
|
networks:
|
|
- t2_proxy
|
|
volumes:
|
|
- /srv/storage/Downloads/watch:/watch
|
|
- /srv/storage/Cloud/org/asked-list.org:/list.org
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- YGGTORRENTNAME=$YGGTORRENTNAME
|
|
- YGGTORRENTPASS=$YGGTORRENTPASS
|
|
- NOTIF_TYPE=gotify
|
|
- GOTIFY_URL=$GOTIFY_URL
|
|
- GOTIFY_TOKEN=$DOWN_GOTIFY_TOKEN
|
|
user: "${PUID}:${PGID}"
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.down-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.down-rtr.rule=Host(`down.$DOMAINNAME`)"
|
|
- "traefik.http.routers.down-rtr.tls=true"
|
|
- "traefik.http.routers.down-rtr.service=down-svc"
|
|
- "traefik.http.services.down-svc.loadbalancer.server.port=3000"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =snapraid= - Manage local backup with parity disk ([[https://github.com/amadvance/snapraid][link]])
|
|
#+begin_src yaml
|
|
snapraid:
|
|
container_name: snapraid
|
|
image: xagaba/snapraid
|
|
restart: unless-stopped
|
|
privileged: true
|
|
volumes:
|
|
- /mnt:/mnt
|
|
- $CONFIGDIR/snapraid:/config
|
|
- type: "bind"
|
|
source: /dev/disk
|
|
target: /dev/disk
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
=snapraid.conf=
|
|
#+begin_src conf :tangle /ssh:thomas@homelab:/home/thomas/docker/config/snapraid/snapraid.conf
|
|
# Defines the file to use as parity storage
|
|
# It must NOT be in a data disk
|
|
# Format: "parity FILE_PATH"
|
|
parity /mnt/parity/snapraid.parity
|
|
|
|
# Defines the files to use as content list
|
|
# You can use multiple specification to store more copies
|
|
# You must have least one copy for each parity file plus one. Some more don't
|
|
# hurt
|
|
# They can be in the disks used for data, parity or boot,
|
|
# but each file must be in a different disk
|
|
# Format: "content FILE_PATH"
|
|
# content /var/snapraid.content
|
|
content /mnt/disk0/.snapraid.content
|
|
content /mnt/disk1/.snapraid.content
|
|
|
|
# Defines the data disks to use
|
|
# The order is relevant for parity, do not change it
|
|
# Format: "disk DISK_NAME DISK_MOUNT_POINT"
|
|
disk disk0 /mnt/disk0
|
|
disk disk1 /mnt/disk1
|
|
|
|
# Excludes hidden files and directories (uncomment to enable).
|
|
#nohidden
|
|
|
|
# Defines files and directories to exclude
|
|
# Remember that all the paths are relative at the mount points
|
|
# Format: "exclude FILE"
|
|
# Format: "exclude DIR/"
|
|
# Format: "exclude /PATH/FILE"
|
|
# Format: "exclude /PATH/DIR/"
|
|
exclude /tmp/
|
|
exclude /lost+found/
|
|
exclude *.!sync
|
|
exclude .DS_Store
|
|
exclude ._.DS_Store
|
|
exclude .Thumbs.db
|
|
exclude .fseventsd
|
|
exclude .Spotlight-V100
|
|
exclude .TemporaryItems
|
|
exclude .Trashes
|
|
#+end_src
|
|
|
|
=snapraid-runner.conf=
|
|
#+begin_src conf :tangle /ssh:thomas@homelab:/home/thomas/docker/config/snapraid/snapraid-runner.conf
|
|
[snapraid]
|
|
; path to the snapraid executable (e.g. /bin/snapraid)
|
|
executable = /usr/bin/snapraid
|
|
; path to the snapraid config to be used
|
|
config = /config/snapraid.conf
|
|
; abort operation if there are more deletes than this, set to -1 to disable
|
|
deletethreshold = -1
|
|
; if you want touch to be ran each time
|
|
touch = false
|
|
|
|
[logging]
|
|
; logfile to write to, leave empty to disable
|
|
file = /config/snapraid.log
|
|
; maximum logfile size in KiB, leave empty for infinite
|
|
maxsize = 5000
|
|
|
|
; [email]
|
|
; ; when to send an email, comma-separated list of [success, error]
|
|
; sendon = success,error
|
|
; ; set to false to get full programm output via email
|
|
; short = true
|
|
; subject = [SnapRAID] Status Report:
|
|
; from =
|
|
; to =
|
|
; ; maximum email size in KiB
|
|
; maxsize = 500
|
|
;
|
|
; [smtp]
|
|
; host =
|
|
; ; leave empty for default port
|
|
; port =
|
|
; ; set to "true" to activate
|
|
; ssl = false
|
|
; tls = false
|
|
; user =
|
|
; password =
|
|
|
|
[scrub]
|
|
; set to true to run scrub after sync
|
|
enabled = false
|
|
percentage = 12
|
|
older-than = 10
|
|
#+end_src
|
|
|
|
|
|
** =gluetun= - Provide VPN connection to other containers ([[https://github.com/bubuntux/nordvpn][link]])
|
|
#+begin_src yaml
|
|
gluetun:
|
|
image: qmcgaw/gluetun:v3.28.2
|
|
container_name: gluetun
|
|
restart: unless-stopped
|
|
cap_add:
|
|
- NET_ADMIN
|
|
network_mode: bridge
|
|
ports:
|
|
- 8065:8065 # For transmission
|
|
- 9091:9091 # For transmission
|
|
- 51413:51413 # For transmission
|
|
- 51413:51413/udp # For transmission
|
|
environment:
|
|
- OPENVPN_USER=$NORDVPN_NAME
|
|
- OPENVPN_PASSWORD=$NORDVPN_PASS
|
|
- VPNSP=nordvpn
|
|
- REGION=France
|
|
- SERVER_NUMBER=822
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/gluetun:/config
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =transmission= - Torrent client ([[https://hub.docker.com/r/linuxserver/transmission][link]])
|
|
#+begin_src yaml
|
|
transmission:
|
|
container_name: transmission
|
|
image: lscr.io/linuxserver/transmission
|
|
restart: unless-stopped
|
|
network_mode: container:gluetun
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- USER=$TRANSMISSION_NAME
|
|
- PASS=$TRANSMISSION_PASS
|
|
- TRANSMISSION_WEB_HOME=/flood-for-transmission/
|
|
volumes:
|
|
- $CONFIGDIR/transmission:/config
|
|
- /srv/storage/Downloads:/downloads
|
|
- /srv/storage/Downloads/watch:/watch
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =ihatemoney= - Tricount Alternative ([[https://github.com/spiral-project/ihatemoney][link]])
|
|
#+begin_src yaml
|
|
tricount:
|
|
container_name: tricount
|
|
image: ihatemoney/ihatemoney
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/tricount:/database
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.tricount-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.tricount-rtr.rule=Host(`tricount.$DOMAINNAME`)"
|
|
- "traefik.http.routers.tricount-rtr.tls=true"
|
|
- "traefik.http.routers.tricount-rtr.service=tricount-svc"
|
|
# - "traefik.http.routers.tricount-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.tricount-svc.loadbalancer.server.port=8000"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =homeassistant= - Home Automation ([[https://hub.docker.com/r/homeassistant/home-assistant][link]])
|
|
#+begin_src yaml
|
|
homeassistant:
|
|
container_name: homeassistant
|
|
image: homeassistant/home-assistant
|
|
restart: unless-stopped
|
|
#networks:
|
|
# - t2_proxy
|
|
#ports:
|
|
# - target: 8123
|
|
# published: 8123
|
|
# protocol: tcp
|
|
# mode: host
|
|
privileged: true
|
|
ports:
|
|
- 8123:8123
|
|
# network_mode: host
|
|
volumes:
|
|
- $CONFIGDIR/homeassistant:/config
|
|
- /etc/localtime:/etc/localtime:ro
|
|
- /dev/bus/usb:/dev/bus/usb
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.homeassistant-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.homeassistant-rtr.rule=Host(`home.$DOMAINNAME`)"
|
|
- "traefik.http.routers.homeassistant-rtr.tls=true"
|
|
- "traefik.http.routers.homeassistant-rtr.service=homeassistant-svc"
|
|
- "traefik.http.services.homeassistant-svc.loadbalancer.server.port=8123"
|
|
# - "traefik.http.services.homeassistant-svc.loadbalancer.servers.url=http://172.17.0.1:8123"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =photoprism= ([[https://github.com/photoprism/photoprism][link]])
|
|
#+begin_src yaml
|
|
photoprism:
|
|
container_name: photoprism
|
|
image: photoprism/photoprism:latest
|
|
depends_on:
|
|
- photoprism_db
|
|
networks:
|
|
- t2_proxy
|
|
- backend
|
|
security_opt:
|
|
- seccomp:unconfined
|
|
- apparmor:unconfined
|
|
user: "${PUID}:${PGID}"
|
|
environment:
|
|
PHOTOPRISM_ADMIN_PASSWORD: "pi3DnacevhCQ"
|
|
PHOTOPRISM_SITE_URL: "https://photos.tdehaeze.xyz/"
|
|
PHOTOPRISM_ORIGINALS_LIMIT: 500
|
|
PHOTOPRISM_READONLY: "false"
|
|
PHOTOPRISM_DISABLE_WEBDAV: "true"
|
|
PHOTOPRISM_DISABLE_TENSORFLOW: "true"
|
|
PHOTOPRISM_DISABLE_FACES: "true"
|
|
PHOTOPRISM_DISABLE_CLASSIFICATION: "true"
|
|
PHOTOPRISM_DARKTABLE_PRESETS: "false" # Enables Darktable presets and disables concurrent RAW conversion
|
|
PHOTOPRISM_DATABASE_DRIVER: "mysql"
|
|
PHOTOPRISM_DATABASE_SERVER: "photoprism_db:3306"
|
|
PHOTOPRISM_DATABASE_NAME: "photoprism"
|
|
PHOTOPRISM_DATABASE_USER: "photoprism"
|
|
PHOTOPRISM_DATABASE_PASSWORD: "PMsLF5577UagH08c"
|
|
PHOTOPRISM_UID: $PUID
|
|
PHOTOPRISM_GID: $PGID
|
|
HOME: "/photoprism"
|
|
working_dir: "/photoprism"
|
|
volumes:
|
|
- "/srv/storage/Cloud/pictures:/photoprism/originals" # original media files (photos and videos)
|
|
- "$CONFIGDIR/photoprism/storage:/photoprism/storage" # *writable* storage folder for cache, database, and sidecar files (never remove)
|
|
# - "$CONFIGDIR/photoprism/originals:/photoprism/originals" # original media files (photos and videos)
|
|
# - "/example/family:/photoprism/originals/family" # *additional* media folders can be mounted like this
|
|
# - "~/Import:/photoprism/import" # *optional* base folder from which files can be imported to originals
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.photos-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.photos-rtr.rule=Host(`photos.$DOMAINNAME`)"
|
|
- "traefik.http.routers.photos-rtr.tls=true"
|
|
- "traefik.http.routers.photos-rtr.service=photos-svc"
|
|
- "traefik.http.services.photos-svc.loadbalancer.server.port=2342"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
#+begin_src yaml :tangle no
|
|
photoprism_db:
|
|
container_name: photoprism_db
|
|
restart: unless-stopped
|
|
image: mariadb:10.6
|
|
networks:
|
|
- backend
|
|
security_opt:
|
|
- seccomp:unconfined
|
|
- apparmor:unconfined
|
|
command: mysqld --innodb-buffer-pool-size=128M --transaction-isolation=READ-COMMITTED --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max-connections=512 --innodb-rollback-on-timeout=OFF --innodb-lock-wait-timeout=120
|
|
volumes:
|
|
- "$CONFIGDIR/photoprism_db/database:/var/lib/mysql"
|
|
environment:
|
|
MYSQL_ROOT_PASSWORD: ZyZ4vhBmnERp5Amt
|
|
MYSQL_DATABASE: photoprism
|
|
MYSQL_USER: photoprism
|
|
MYSQL_PASSWORD: PMsLF5577UagH08c
|
|
#+end_src
|
|
|
|
** =diun= - Notification for Docker image updates ([[https://github.com/crazy-max/diun/][link]])
|
|
#+begin_src yaml
|
|
diun:
|
|
container_name: diun
|
|
image: crazymax/diun
|
|
restart: unless-stopped
|
|
networks:
|
|
- backend
|
|
environment:
|
|
- TZ=$TZ
|
|
- LOG_LEVEL=info
|
|
- LOG_JSON=false
|
|
- DIUN_WATCH_WORKERS=20
|
|
- DIUN_WATCH_SCHEDULE=0 7 * * 6
|
|
- DIUN_PROVIDERS_DOCKER=true
|
|
- DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT=true
|
|
- DIUN_NOTIF_GOTIFY_ENDPOINT=$GOTIFY_URL
|
|
- DIUN_NOTIF_GOTIFY_TOKEN=$DIUN_GOTIFY_TOKEN
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
- $CONFIGDIR/diun:/data
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =audioserve= - Audiobook server ([[https://github.com/izderadicka/audioserve][link]])
|
|
#+begin_src yaml
|
|
audioserve:
|
|
container_name: audioserve
|
|
image: izderadicka/audioserve
|
|
restart: unless-stopped
|
|
command: /audiobooks
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- AUDIOSERVE_SHARED_SECRET=$AUDIOSERVE_SHARED_SECRET
|
|
volumes:
|
|
- /srv/storage/AudioBooks:/audiobooks
|
|
- /etc/localtime:/etc/localtime:ro
|
|
- $CONFIGDIR/audioserve:/home/audioserve/.audioserve
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.audioserve-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.audioserve-rtr.rule=Host(`audiobook.$DOMAINNAME`)"
|
|
- "traefik.http.routers.audioserve-rtr.tls=true"
|
|
- "traefik.http.routers.audioserve-rtr.service=audioserve-svc"
|
|
- "traefik.http.services.audioserve-svc.loadbalancer.server.port=3000"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =kavita= - Reading server ([[https://github.com/Kareadita/Kavita][link]])
|
|
#+begin_src yaml
|
|
kavita:
|
|
container_name: kavita
|
|
image: kizaing/kavita:latest
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- TZ=$TZ
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
volumes:
|
|
- $CONFIGDIR/kavita:/kavita/config
|
|
- /srv/storage/Books:/books
|
|
- /srv/storage/Scans:/scans
|
|
- /srv/storage/Comics:/comics
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.kavita-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.kavita-rtr.rule=Host(`kavita.$DOMAINNAME`)"
|
|
- "traefik.http.routers.kavita-rtr.tls=true"
|
|
- "traefik.http.routers.kavita-rtr.service=kavita-svc"
|
|
- "traefik.http.services.kavita-svc.loadbalancer.server.port=5000"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =wikijs= - Wiki App ([[https://github.com/Requarks/wiki][link]])
|
|
#+begin_src yaml
|
|
wikijs:
|
|
image: ghcr.io/linuxserver/wikijs:version-2.5.201
|
|
container_name: wikijs
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/wikijs/config:/config
|
|
- $CONFIGDIR/wikijs/data:/data
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.wikijs-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.wikijs-rtr.rule=Host(`wiki.$DOMAINNAME`)"
|
|
- "traefik.http.routers.wikijs-rtr.tls=true"
|
|
- "traefik.http.routers.wikijs-rtr.service=wikijs-svc"
|
|
- "traefik.http.services.wikijs-svc.loadbalancer.server.port=3000"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =lldap= - LDAP Server ([[https://github.com/nitnelave/lldap][link]])
|
|
#+begin_src yaml :tangle no
|
|
lldap:
|
|
image: nitnelave/lldap
|
|
container_name: lldap
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
- backend
|
|
ports:
|
|
- 3890:3890
|
|
volumes:
|
|
- $CONFIGDIR/lldap:/data
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.lldap-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.lldap-rtr.rule=Host(`lldap.$DOMAINNAME`)"
|
|
- "traefik.http.routers.lldap-rtr.tls=true"
|
|
- "traefik.http.routers.lldap-rtr.service=lldap-svc"
|
|
- "traefik.http.routers.lldap-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.lldap-svc.loadbalancer.server.port=17170"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =acoustic= - Acoustic Pages
|
|
#+begin_src yaml
|
|
acoustic:
|
|
container_name: acoustic
|
|
image: abiosoft/caddy:1.0.3-no-stats
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- PLUGINS=git
|
|
volumes:
|
|
- $CONFIGDIR/acoustic/Caddyfile:/etc/Caddyfile
|
|
- $CONFIGDIR/acoustic/web:/srv
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.acoustic-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.acoustic-rtr.rule=Host(`acoustic.$DOMAINNAME`)"
|
|
- "traefik.http.routers.acoustic-rtr.tls=true"
|
|
- "traefik.http.routers.acoustic-rtr.service=acoustic-svc"
|
|
- "traefik.http.services.acoustic-svc.loadbalancer.server.port=2015"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =Caddyfile=
|
|
#+begin_src conf :tangle /ssh:thomas@homelab:/home/thomas/docker/config/acoustic/Caddyfile
|
|
0.0.0.0:2015 {
|
|
root /srv/www/
|
|
|
|
git {
|
|
repo https://git.tdehaeze.xyz/tdehaeze/acoustic-home-page
|
|
path /srv/www/
|
|
interval -1
|
|
hook /acoustic-home-page/webhook 9a2CMCD5CucbnVQr
|
|
then git submodule update --init --recursive --merge
|
|
}
|
|
}
|
|
#+end_src
|
|
|
|
** =pyload= - Download manager (link)
|
|
#+begin_src yaml
|
|
pyload:
|
|
container_name: pyload
|
|
image: ghcr.io/linuxserver/pyload
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
volumes:
|
|
- $CONFIGDIR/pyload/config:/config
|
|
- /srv/storage/Downloads:/downloads
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.pyload-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.pyload-rtr.rule=Host(`pyload.$DOMAINNAME`)"
|
|
- "traefik.http.routers.pyload-rtr.tls=true"
|
|
- "traefik.http.routers.pyload-rtr.service=pyload-svc"
|
|
- "traefik.http.services.pyload-svc.loadbalancer.server.port=8000"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =aria2= - Download daemon ([[https://hub.docker.com/r/opengg/aria2][link]])
|
|
Backend ([[https://hub.docker.com/r/opengg/aria2][link]]):
|
|
#+begin_src yaml
|
|
aria2:
|
|
container_name: aria2
|
|
image: opengg/aria2
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
user: "${PUID}:${PGID}"
|
|
volumes:
|
|
- $CONFIGDIR/aria2:/config
|
|
- /srv/storage/Downloads:/downloads
|
|
ports:
|
|
- 6800:6800
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
Web-UI ([[https://hub.docker.com/r/p3terx/ariang][link]]):
|
|
#+begin_src yaml
|
|
aria2-ui:
|
|
container_name: aria2-ui
|
|
image: p3terx/ariang
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
depends_on:
|
|
- aria2
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.aria2-rtr.entrypoints=http"
|
|
- "traefik.http.routers.aria2-rtr.rule=Host(`dl.$DOMAINNAME`)"
|
|
- "traefik.http.routers.aria2-rtr.tls=false"
|
|
- "traefik.http.routers.aria2-rtr.service=aria2-svc"
|
|
- "traefik.http.services.aria2-svc.loadbalancer.server.port=6880"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =aria2.conf=
|
|
#+begin_src conf :tangle /ssh:thomas@homelab:/home/thomas/docker/config/aria2/aria2.conf :noweb yes
|
|
save-session=/config/aria2.session
|
|
input-file=/config/aria2.session
|
|
save-session-interval=60
|
|
|
|
dir=/downloads
|
|
|
|
file-allocation=prealloc
|
|
disk-cache=128M
|
|
|
|
enable-rpc=true
|
|
rpc-listen-port=6800
|
|
rpc-allow-origin-all=true
|
|
rpc-listen-all=true
|
|
|
|
rpc-secret=<<get-password(passname="nas/aria2")>>
|
|
|
|
auto-file-renaming=false
|
|
|
|
max-connection-per-server=16
|
|
min-split-size=1M
|
|
split=16
|
|
#+end_src
|
|
|
|
** =deemix= - Music Download ([[https://gitlab.com/Bockiii/deemix-docker][link]]) :noexport:
|
|
#+begin_src yaml
|
|
deemix:
|
|
container_name: deemix
|
|
image: registry.gitlab.com/bockiii/deemix-docker
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
volumes:
|
|
- /srv/storage/Music:/downloads
|
|
- $CONFIGDIR/deemix:/config
|
|
environment:
|
|
- TZ=$TZ
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- ARL=$DEEMIX_ARL
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.deemix-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.deemix-rtr.rule=Host(`deemix.$DOMAINNAME`)"
|
|
- "traefik.http.routers.deemix-rtr.tls=true"
|
|
- "traefik.http.routers.deemix-rtr.service=deemix-svc"
|
|
- "traefik.http.routers.deemix-rtr.middlewares=authelia@docker"
|
|
- "traefik.http.services.deemix-svc.loadbalancer.server.port=6595"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
*** =.arl=
|
|
#+begin_src conf :tangle /ssh:thomas@homelab:/home/thomas/docker/config/deemix/.arl :noweb yes
|
|
<<get-password(passname="nas/deemix_arl")>>
|
|
#+end_src
|
|
|
|
** =vaultwarden= - Password Manager ([[https://github.com/dani-garcia/vaultwarden][link]])
|
|
#+begin_src yaml
|
|
vaultwarden:
|
|
container_name: vaultwarden
|
|
image: vaultwarden/server
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/vaultwarden:/data
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.vaultwarden-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.vaultwarden-rtr.rule=Host(`pass.$DOMAINNAME`)"
|
|
- "traefik.http.routers.vaultwarden-rtr.tls=true"
|
|
- "traefik.http.routers.vaultwarden-rtr.service=vaultwarden-svc"
|
|
- "traefik.http.services.vaultwarden-svc.loadbalancer.server.port=80"
|
|
#+end_src
|
|
|
|
** =gonic= - Subsonic Server
|
|
#+begin_src yaml
|
|
gonic:
|
|
container_name: gonic
|
|
image: sentriz/gonic
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/gonic:/data
|
|
- /srv/storage/Music:/music:ro
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.gonic-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.gonic-rtr.rule=Host(`gonic.$DOMAINNAME`)"
|
|
- "traefik.http.routers.gonic-rtr.tls=true"
|
|
- "traefik.http.routers.gonic-rtr.service=gonic-svc"
|
|
- "traefik.http.services.gonic-svc.loadbalancer.server.port=80"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =watchtower= - Automatic Update Docker images
|
|
#+begin_src yaml
|
|
watchtower:
|
|
container_name: watchtower
|
|
image: containrrr/watchtower
|
|
restart: unless-stopped
|
|
networks:
|
|
- backend
|
|
environment:
|
|
- TZ=$TZ
|
|
- WATCHTOWER_SCHEDULE=0 0 4 * * MON
|
|
- WATCHTOWER_CLEANUP=true
|
|
- WATCHTOWER_TIMEOUT=30s
|
|
- WATCHTOWER_DEBUG=false
|
|
- WATCHTOWER_MONITOR_ONLY=true
|
|
- WATCHTOWER_NOTIFICATIONS=email
|
|
- WATCHTOWER_NOTIFICATION_EMAIL_FROM=tdehaeze.xyz@gmail.com
|
|
- WATCHTOWER_NOTIFICATION_EMAIL_TO=dehaeze.thomas@gmail.com
|
|
- WATCHTOWER_NOTIFICATION_EMAIL_SERVER=smtp.gmail.com
|
|
- WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=587
|
|
- WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=tdehaeze.xyz@gmail.com
|
|
- WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=$GOOGLE_WATCHTOWER_PASS
|
|
- WATCHTOWER_NOTIFICATION_EMAIL_DELAY=2
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
#+end_src
|
|
|
|
** =guacamole= - Remote connection
|
|
#+begin_src yaml
|
|
guacamole:
|
|
image: oznu/guacamole
|
|
container_name: guacamole
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
- backend
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
volumes:
|
|
- $CONFIGDIR/guacamole:/config
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.guacamole-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.guacamole-rtr.rule=Host(`guacamole.$DOMAINNAME`)"
|
|
- "traefik.http.routers.guacamole-rtr.tls=true"
|
|
- "traefik.http.routers.guacamole-rtr.service=guacamole-svc"
|
|
- "traefik.http.services.guacamole-svc.loadbalancer.server.port=8080"
|
|
logging: *default-logging
|
|
#+end_src
|
|
|
|
** =transfer= - Transfer.sh
|
|
#+begin_src yaml
|
|
transfer:
|
|
container_name: transfer
|
|
image: dutchcoders/transfer.sh
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- UMASK_SET=022
|
|
- BASEDIR=/tmp/
|
|
- PROVIDER=local
|
|
volumes:
|
|
- /srv/storage/Uploads:/tmp/
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.transfer-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.transfer-rtr.rule=Host(`file.$DOMAINNAME`)"
|
|
- "traefik.http.routers.transfer-rtr.tls=true"
|
|
- "traefik.http.routers.transfer-rtr.service=transfer-svc"
|
|
- "traefik.http.services.transfer-svc.loadbalancer.server.port=8080"
|
|
#+end_src
|
|
|
|
** =bazarr= - Automatically download Music
|
|
#+begin_src yaml
|
|
bazarr:
|
|
container_name: bazarr
|
|
image: linuxserver/bazarr
|
|
restart: unless-stopped
|
|
networks:
|
|
- backend
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- UMASK_SET=022 #optional
|
|
volumes:
|
|
- $CONFIGDIR/bazarr:/config
|
|
- /srv/storage/TVShows:/tv
|
|
- /srv/storage/Movies:/movies
|
|
ports:
|
|
- 6767:6767
|
|
#+end_src
|
|
|
|
** =mail-cli= - CLI mail client
|
|
#+begin_src yaml
|
|
mail-cli:
|
|
image: tdehaeze/docker-mail-cli
|
|
container_name: mail-cli
|
|
restart: unless-stopped
|
|
volumes:
|
|
- $CONFIGDIR/mail-cli:/config
|
|
- /srv/storage/mail:/mail
|
|
- /srv/storage/Downloads:/data
|
|
environment:
|
|
- TZ=$TZ
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
tty: true
|
|
#+end_src
|
|
|
|
** =cloudcmd= - Minimalist file manager
|
|
#+begin_src yaml
|
|
cloudcmd:
|
|
container_name: cloudcmd
|
|
image: coderaiser/cloudcmd
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
- TZ=$TZ
|
|
- CLOUDCMD_ROOT=/mnt/fs
|
|
- CLOUDCMD_VIM=true
|
|
- CLOUDCMD_ONE_FILE_PANEL=true
|
|
volumes:
|
|
- /srv/storage/Downloads:/mnt/fs/Downloads
|
|
- /srv/storage/Cloud:/mnt/fs/Cloud
|
|
- /srv/storage/TVShows:/mnt/fs/TVShows
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.cloudcmd-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.cloudcmd-rtr.rule=Host(`cloud.$DOMAINNAME`)"
|
|
- "traefik.http.routers.cloudcmd-rtr.tls=true"
|
|
- "traefik.http.routers.cloudcmd-rtr.service=cloudcmd-svc"
|
|
- "traefik.http.routers.cloudcmd-rtr.middlewares=private-auth"
|
|
- "traefik.http.services.cloudcmd-svc.loadbalancer.server.port=8000"
|
|
#+end_src
|
|
|
|
** =wallabag= - Bookmark Manager
|
|
#+begin_src yaml
|
|
wallabag:
|
|
container_name: wallabag
|
|
image: wallabag/wallabag
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- wallabag_db
|
|
networks:
|
|
- t2_proxy
|
|
- backend
|
|
environment:
|
|
- MYSQL_ROOT_PASSWORD=$WALLABAG_MYSQL_ROOT_PASSWORD
|
|
- SYMFONY__ENV__DATABASE_DRIVER=pdo_mysql
|
|
- SYMFONY__ENV__DATABASE_HOST=wallabag_db
|
|
- SYMFONY__ENV__DATABASE_PORT=3308
|
|
- SYMFONY__ENV__DATABASE_NAME=symfony
|
|
- SYMFONY__ENV__DATABASE_USER=root
|
|
- SYMFONY__ENV__DATABASE_PASSWORD=$WALLABAG_MYSQL_PASSWORD
|
|
- SYMFONY__ENV__DATABASE_CHARSET=utf8mb4
|
|
- SYMFONY__ENV__DOMAIN_NAME=https://wallabag.tdehaeze.xyz
|
|
volumes:
|
|
- $CONFIGDIR/wallabag/images:/var/www/wallabag/web/assets/images
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.wallabag-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.wallabag-rtr.rule=Host(`wallabag.$DOMAINNAME`)"
|
|
- "traefik.http.routers.wallabag-rtr.tls=true"
|
|
- "traefik.http.routers.wallabag-rtr.service=wallabag-svc"
|
|
- "traefik.http.services.wallabag-svc.loadbalancer.server.port=80"
|
|
|
|
wallabag_db:
|
|
container_name: wallabag_db
|
|
image: mariadb
|
|
restart: unless-stopped
|
|
networks:
|
|
- backend
|
|
ports:
|
|
- 3308:3306
|
|
environment:
|
|
- MYSQL_ROOT_PASSWORD=$WALLABAG_MYSQL_ROOT_PASSWORD
|
|
- MYSQL_DATABASE=wallabag
|
|
- MYSQL_USER=wallabag
|
|
- MYSQL_PASSWORD=$WALLABAG_MYSQL_PASSWORD
|
|
volumes:
|
|
- $CONFIGDIR/wallabag/data:/var/lib/mysql
|
|
#+end_src
|
|
|
|
** =buku= - Bookmark manager
|
|
#+begin_src yaml
|
|
buku:
|
|
container_name: buku
|
|
image: bukuserver/bukuserver
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
- BUKUSERVER_PER_PAGE=100
|
|
- BUKUSERVER_OPEN_IN_NEW_TAB=true
|
|
# - BUKUSERVER_SECRET_KEY=123456789012345678901234
|
|
# - BUKUSERVER_URL_RENDER_MODE=full
|
|
# - BUKUSERVER_DISABLE_FAVICON=false
|
|
volumes:
|
|
- $CONFIGDIR/buku:/root/.local/share/buku
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.buku-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.buku-rtr.rule=Host(`bookmarks.$DOMAINNAME`)"
|
|
- "traefik.http.routers.buku-rtr.tls=true"
|
|
- "traefik.http.routers.buku-rtr.service=buku-svc"
|
|
- "traefik.http.routers.buku-rtr.middlewares=private-auth"
|
|
- "traefik.http.services.buku-svc.loadbalancer.server.port=5001"
|
|
#+end_src
|
|
|
|
** =duplicati= - Backup system
|
|
#+begin_src yaml
|
|
duplicati:
|
|
container_name: duplicati
|
|
image: linuxserver/duplicati
|
|
restart: unless-stopped
|
|
networks:
|
|
- t2_proxy
|
|
environment:
|
|
- UID=$PUID
|
|
- GID=$PGID
|
|
- TZ=$TZ
|
|
# - CLI_ARGS= #optional
|
|
volumes:
|
|
- $CONFIGDIR/duplicati:/config
|
|
- /srv/storage/Backups:/backups
|
|
- /srv/storage/Cloud/thesis:/source
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.duplicati-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.duplicati-rtr.rule=Host(`backup.$DOMAINNAME`)"
|
|
- "traefik.http.routers.duplicati-rtr.tls=true"
|
|
- "traefik.http.routers.duplicati-rtr.service=duplicati-svc"
|
|
- "traefik.http.routers.duplicati-rtr.middlewares=private-auth"
|
|
- "traefik.http.services.duplicati-svc.loadbalancer.server.port=8200"
|
|
#+end_src
|
|
|
|
** =netdata= - Performance Monitoring
|
|
#+begin_src yaml
|
|
netdata:
|
|
image: netdata/netdata
|
|
container_name: netdata
|
|
restart: unless-stopped
|
|
hostname: netdata.tdehaeze.xyz
|
|
networks:
|
|
- t2_proxy
|
|
- backend
|
|
environment:
|
|
- PUID=$PUID
|
|
- PGID=998
|
|
- TZ=$TZ
|
|
cap_add:
|
|
- SYS_PTRACE
|
|
security_opt:
|
|
- apparmor:unconfined
|
|
volumes:
|
|
- /proc:/host/proc:ro
|
|
- /sys:/host/sys:ro
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
- $CONFIGDIR/netdata:/etc/netdata
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.netdata-rtr.entrypoints=web-secure"
|
|
- "traefik.http.routers.netdata-rtr.rule=Host(`netdata.$DOMAINNAME`)"
|
|
- "traefik.http.routers.netdata-rtr.tls=true"
|
|
- "traefik.http.routers.netdata-rtr.service=netdata-svc"
|
|
- "traefik.http.services.netdata-svc.loadbalancer.server.port=19999"
|
|
#+end_src
|
|
|
|
** =fail2ban= - Ban hosts that cause multiple authentication errors
|
|
#+begin_src yaml
|
|
fail2ban:
|
|
image: crazymax/fail2ban:latest
|
|
container_name: fail2ban
|
|
restart: unless-stopped
|
|
network_mode: "host"
|
|
cap_add:
|
|
- NET_ADMIN
|
|
- NET_RAW
|
|
volumes:
|
|
- $CONFIGDIR/fail2ban:/data
|
|
- /var/log:/var/log:ro
|
|
environment:
|
|
- TZ=$TZ
|
|
- PUID=$PUID
|
|
- PGID=$PGID
|
|
#+end_src
|
|
|
|
* =.env= - Variable used for Docker Compose :noexport:
|
|
:PROPERTIES:
|
|
:header-args: :tangle /ssh:thomas@homelab:~/docker/.env
|
|
:header-args+: :comments none :mkdirp yes :noweb yes
|
|
:END:
|
|
|
|
#+begin_src conf
|
|
PUID=1000
|
|
PGID=1000
|
|
TZ=Europe/Paris
|
|
#+end_src
|
|
|
|
#+begin_src conf
|
|
CONFIGDIR=/home/thomas/docker/config
|
|
DOMAINNAME=tdehaeze.xyz
|
|
#+end_src
|
|
|
|
#+begin_src conf
|
|
CLOUDFLARE_EMAIL=dehaeze.thomas@gmail.com
|
|
CLOUDFLARE_API_KEY=<<get-password(passname="nas/cloudflare_api_key")>>
|
|
#+end_src
|
|
|
|
#+begin_src conf
|
|
MINIFLUX_ADMIN_NAME=tdehaeze
|
|
MINIFLUX_ADMIN_PASS=<<get-password(passname="nas/miniflux_admin_pass")>>
|
|
MINIFLUX_POSTGRES_PASSWORD=<<get-password(passname="nas/miniflux_postgres_pass")>>
|
|
#+end_src
|
|
|
|
#+begin_src conf
|
|
RESTIC_PASSWORD=<<get-password(passname="nas/restic_pass")>>
|
|
#+end_src
|
|
|
|
#+begin_src conf
|
|
WINGAUDIO_DB_MYSQL_ROOT_PASSWORD=<<get-password(passname="nas/wingaudio_mysql_root_pass")>>
|
|
WINGAUDIO_DB_MYSQL_PASSWORD=<<get-password(passname="nas/wingaudio_mysql_pass")>>
|
|
#+end_src
|
|
|
|
#+begin_src conf
|
|
GITEA_DB_MYSQL_ROOT_PASSWORD=<<get-password(passname="nas/gitea_mysql_root_pass")>>
|
|
GITEA_DB_MYSQL_PASSWORD=<<get-password(passname="nas/gitea_mysql_pass")>>
|
|
GITEA_SSH_PORT=2222
|
|
#+end_src
|
|
|
|
#+begin_src conf
|
|
NORDVPN_NAME=AacP7CV8mjAkBtk5Bk6eGr1q
|
|
NORDVPN_PASS=<<get-password(passname="nas/nordvpn")>>
|
|
#+end_src
|
|
|
|
#+begin_src conf
|
|
TRANSMISSION_NAME=tdehaeze
|
|
TRANSMISSION_PASS=<<get-password(passname="nas/transmission")>>
|
|
#+end_src
|
|
|
|
#+begin_src conf
|
|
WIREGUARD_PASS=<<get-password(passname="nas/wireguard")>>
|
|
#+end_src
|
|
|
|
#+begin_src conf
|
|
GOTIFY_URL=https://gotify.tdehaeze.xyz/
|
|
GOTIFY_DEFAULTUSER_NAME=tdehaeze
|
|
GOTIFY_DEFAULTUSER_PASS=<<get-password(passname="nas/gotify")>>
|
|
#+end_src
|
|
|
|
Gotify Tokken:
|
|
#+begin_src conf
|
|
QOBUZ_GOTIFY_TOKEN=<<get-password(passname="nas/gotify_qobuz_token")>>
|
|
RESTIC_GOTIFY_TOKEN=<<get-password(passname="nas/gotify_restic_token")>>
|
|
#+end_src
|
|
|
|
#+begin_src conf
|
|
QOBUZNAME=dehaeze.thomas@gmail.com
|
|
QOBUZPASS=<<get-password(passname="qobuz.com/dehaeze.thomas@gmail.com")>>
|
|
JELLYFINTOKEN=<<get-password(passname="nas/jellyfin_token")>>
|
|
#+end_src
|
|
|
|
#+begin_src conf
|
|
AUTHELIA_NOTIFIER_SMTP_PASSWORD=<<get-password(passname="nas/google_authelia_pass")>>
|
|
AUTHELIA_JWT_SECRET=<<get-password(passname="nas/authelia_jwt_secret")>>
|
|
#+end_src
|
|
|
|
#+begin_src conf
|
|
JOALTOKEN=<<get-password(passname="joal.tdehaeze.xyz/secret-token")>>
|
|
#+end_src
|
|
|
|
#+begin_src conf
|
|
GOOGLE_COMMENTO_PASS=<<get-password(passname="nas/google_commento_pass")>>
|
|
GOOGLE_AUTHELIA_PASS=<<get-password(passname="nas/google_authelia_pass")>>
|
|
#+end_src
|
|
|
|
#+begin_src conf
|
|
COMMENTO_DB_PASSWORD=<<get-password(passname="nas/commento_db_pass")>>
|
|
#+end_src
|
|
|
|
* TODO Matrix
|
|
** Matrix server
|
|
Use Ansible https://github.com/spantaleev/matrix-docker-ansible-deploy
|
|
|
|
Must install newer version of ansible:
|
|
- https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-ansible-on-ubuntu
|
|
|
|
** Basic Config
|
|
#+begin_src yaml
|
|
matrix_domain: tdehaeze.xyz
|
|
matrix_ssl_lets_encrypt_support_email: 'dehaeze.thomas@gmail.com'
|
|
matrix_coturn_turn_static_auth_secret: 'nxSdNOonPYXHmpog8j6dC1EciAmdYPNgpre1SZw1yc8VybtJcAQrzArVLAjzDR2z'
|
|
matrix_synapse_macaroon_secret_key: 'exz3Wv7eWBDGYpnp5x3o3qGg6oalG04teu2eNlzMv6H7HxhW5U8Dr1HXZhMHafhl'
|
|
matrix_postgres_connection_password: '4WmtV4utoNMKMOY1TxfJ9EsgCV8dTIV8hyB8YrCpZqd33bsursGKEP6BA1gY4YZJ'
|
|
matrix_client_element_enabled: false
|
|
matrix_homeserver_generic_secret_key: "{{ matrix_synapse_macaroon_secret_key }}"
|
|
#+end_src
|
|
|
|
#+begin_src yaml
|
|
# =================================================================================================
|
|
# Setting up the Shared Secret Auth password provider module
|
|
matrix_synapse_ext_password_provider_shared_secret_auth_enabled: true
|
|
matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret: Ru1kRNNyj8k7cVx2q2aAZCZL3R3Ph79Pq762W17CfExhmnAfxb9BI7zOktsBK32O
|
|
#+end_src
|
|
|
|
** Use Traefik as reverse proxy
|
|
#+begin_src yaml
|
|
# =================================================================================================
|
|
# Disable Nginx and use Traefik instead
|
|
# =================================================================================================
|
|
|
|
# Disable generation and retrieval of SSL certs
|
|
matrix_ssl_retrieval_method: none
|
|
|
|
# Configure Nginx to only use plain HTTP
|
|
matrix_nginx_proxy_https_enabled: false
|
|
|
|
# Don't bind any HTTP or federation port to the host
|
|
# (Traefik will proxy directly into the containers)
|
|
matrix_nginx_proxy_container_http_host_bind_port: ''
|
|
matrix_nginx_proxy_container_federation_host_bind_port: ''
|
|
|
|
# Disable Coturn because it needs SSL certs
|
|
# (Clients can, though exposing IP address, use Matrix.org TURN)
|
|
matrix_coturn_enabled: false
|
|
|
|
# All containers need to be on the same Docker network as Traefik
|
|
# (This network should already exist and Traefik should be using this network)
|
|
matrix_docker_network: 't2_proxy'
|
|
|
|
matrix_nginx_proxy_container_extra_arguments:
|
|
- '--label "traefik.enable=true"'
|
|
- '--label "traefik.http.routers.matrix-nginx-proxy.entrypoints=https"'
|
|
- '--label "traefik.http.routers.matrix-nginx-proxy.rule=Host(`{{ matrix_server_fqn_matrix }}`,`{{ matrix_server_fqn_element }}`,`{{ matrix_server_fqn_dimension }}`,`{{ matrix_server_fqn_jitsi }}`)"'
|
|
- '--label "traefik.http.routers.matrix-nginx-proxy.tls=true"'
|
|
- '--label "traefik.http.services.matrix-nginx-proxy.loadbalancer.server.port=8080"'
|
|
# - '--label "traefik.http.routers.matrix-nginx-proxy.middlewares=matrix-regex"'
|
|
# - '--label "traefik.http.middlewares.matrix-regex.redirectregex.regex=https://matrix.tdehaeze.xyz/.well-known/matrix/(client|server)"'
|
|
# - '--label "traefik.http.middlewares.matrix-regex.redirectregex.replacement=https://matrix.tdehaeze.xyz/"'
|
|
|
|
matrix_synapse_container_extra_arguments:
|
|
- '--label "traefik.enable=true"'
|
|
- '--label "traefik.http.routers.matrix-synapse.entrypoints=synapse"'
|
|
- '--label "traefik.http.routers.matrix-synapse.rule=Host(`{{ matrix_server_fqn_matrix }}`)"'
|
|
- '--label "traefik.http.routers.matrix-synapse.tls=true"'
|
|
- '--label "traefik.http.routers.matrix-synapse.service=matrix-synapse"'
|
|
- '--label "traefik.http.services.matrix-synapse.loadbalancer.server.port=8048"'
|
|
#+end_src
|
|
|
|
** Bridges
|
|
*** Slack
|
|
#+begin_src yaml
|
|
# Slack
|
|
matrix_mx_puppet_slack_enabled: true
|
|
matrix_mx_puppet_slack_client_id: "299050134212.1969032215654"
|
|
matrix_mx_puppet_slack_client_secret: "9a3240e570997645d4961d3cb595e798"
|
|
#+end_src
|
|
|
|
*** WhatsApp
|
|
#+begin_src yaml
|
|
# WhatsApp
|
|
matrix_mautrix_whatsapp_enabled: true
|
|
#+end_src
|
|
|
|
*** Signal
|
|
#+begin_src yaml
|
|
# Signal
|
|
matrix_mautrix_signal_enabled: true
|
|
#+end_src
|
|
|
|
*** Facebook
|
|
#+begin_src yaml
|
|
# Facebook
|
|
matrix_mautrix_facebook_enabled: true
|
|
#+end_src
|
|
|
|
*** Telegram
|
|
#+begin_src yaml
|
|
# Telegram
|
|
matrix_mautrix_telegram_enabled: true
|
|
matrix_mautrix_telegram_api_id: 5596434
|
|
matrix_mautrix_telegram_api_hash: 29d6742e35799b88b9a7b5a46fe05ff2
|
|
#+end_src
|
|
|
|
* Backup server
|
|
** Hardware
|
|
[[https://www.hardkernel.com/shop/odroid-hc4-oled/][Odroid HC4]]
|
|
|
|
** Install
|
|
*** Install MicroSD
|
|
Ubuntu 20.04 minimal
|
|
|
|
https://github.com/snakajim/odroidhc4-install
|
|
|
|
*** First boot
|
|
#+begin_quote
|
|
Choose "Exit to shell"
|
|
(switch to console then)
|
|
# netboot_default
|
|
# exit
|
|
(back to petiboot menu)
|
|
#+end_quote
|
|
|
|
*** Setup SSH and Drive
|
|
- create =thomas= user
|
|
- add user to sudo group
|
|
- add SSH key (use =ssh-copy-id=)
|
|
- disable root ssh and password authentication
|
|
- format disk drive
|
|
- edit =/etc/fstab= to add the disk drive and mount it to =/srv/storage=.
|
|
|
|
*** Install packages
|
|
#+begin_src bash
|
|
sudo apt install neovim tmux fd-find ripgrep fzf apache2-utils unrar ranger man git
|
|
#+end_src
|
|
|
|
*** Install docker
|
|
https://blog.rylander.io/2020/12/23/setting-up-docker-on-ubuntu-20-04-focal-arm64/
|
|
|
|
|
|
** Poweroff without =sudo=
|
|
add the following at the end of =/etc/sudoers=:
|
|
|
|
#+begin_src bash
|
|
thomas backup =NOPASSWD: /usr/bin/systemctl poweroff,/usr/bin/systemctl halt,/usr/bin/systemctl reboot
|
|
#+end_src
|
|
|
|
* Cron Jobs
|
|
** Caddy Update
|
|
Create a script =~/cron/caddy_update.sh= with:
|
|
#+begin_src bash :tangle /ssh:thomas@homelab:~/cron/caddy_update.sh :shebang "#!/usr/bin/env bash"
|
|
docker exec caddy /bin/sh -c "cd /srv/www && echo -e \"Update repo $(date)\" && git submodule update --recursive --remote --merge"
|
|
#+end_src
|
|
|
|
Type =crontab -e= and add this line:
|
|
#+begin_src conf
|
|
*/5 * * * * /home/thomas/cron/caddy_update.sh >> /home/thomas/cron/caddy_update.log 2>&1
|
|
#+end_src
|
|
|
|
|
|
** Back OpenWRT Config
|
|
Create a script =~/cron/backup_openwrt_conf.sh= with:
|
|
#+begin_src bash :tangle /ssh:thomas@homelab:~/cron/backup_openwrt_conf.sh :shebang "#!/usr/bin/env bash"
|
|
ssh root@192.168.1.1 "umask go=; sysupgrade -b /tmp/backup-${HOSTNAME}-$(date +%F).tar.gz" && \
|
|
scp root@192.168.1.1:/tmp/backup-*.tar.gz /srv/storage/Backups/openWRT/
|
|
#+end_src
|
|
|
|
Type =crontab -e= and add this line:
|
|
#+begin_src conf
|
|
*/5 * * * * /home/thomas/cron/backup_openwrt_conf.sh >> /home/thomas/cron/backup_openwrt_conf.log 2>&1
|
|
#+end_src
|