150 KiB
Home Server
- Hardware
- Installation
- Ubuntu
- Install Important software
- Terminal Problem
- Minor Modifications of
~/.inputrc - Partition and Format Disk Drives
- MergerFS and FStab
- SnapRAID (link) and SnapRAID Runner (link)
- Install Docker
- Executing the Docker Command Without Sudo
- Install Docker-Compose
- Setup Docker Networks
- Change Timezone
- Secure the Web Server
- Automatic Security Updates
- Setup cronjobs
- Setup Traefik proxy
- Run
docker-compose - Docker config
~/.docker/config.json - Install
earlyoomfor better memory management
- Maintenance - How To
- Docker-Compose
- USB config
- Basic Config
- Docker Config and Tools
traefik- Application proxy (link)authelia- Single Sign-On Multi-Factor portal (link)uptime-kuma- Monitoring Tool (link)gotify- Notification service (link)scrutiny- Hard drive monitoring (link)wireguard- VPN (link)nginx- Root (used for Matrix)commento- Commenting system (link)rustdesk- Remote desktop application (link)unifi-controller- Software for Unifi devices (link)
- Websites
homepage- A highly customizable homepage (link)hugo- Wiki + Blog (link)research- Research Pages (link)dotfiles- Dotfiles (link)help- Help page for Jellyfin (link)mealie- Recipe Manager (link)gitea- Git server (link)changedetection- Detect change in websites (link)wingaudio- With Wordpress
- Multimedia
- Cloud
syncthing- File Synchronization (link)sync-anne- File Synchronization (link)sync-jm- File Synchronization (link)filebrowser-quantum- Web file browser (link)radicale- CalDAV/CardDAV server (link)linkding- Bookmark manager (link)backrest- Automatic Backups (link)miniflux- RSS reader (link)
- Home
- Immich
- Affichtoo
- Matrix
- Backup server
- Cron Jobs
Hardware
| Part | Model |
|---|---|
| Case | Fractal Design Node 804 |
| Motherboard | ASUS PRIME B450M-A |
| CPU | AMD Ryzen 7 5700G |
| RAM | Corsair Vengeance LPX 32Go (4x8Go) DDR4 3200MHz |
| Cooler | ARCTIC Freezer 34 eSports DUO |
| PSU | Corsair RM750x |
| SSD M.2 | Samsung 970 EVO Plus 1Tb |
| Data Drives | 4x 8Tb |
| Parity Drive | 1x 10Tb |
Note regarding the ASUS PRIME B450M-A 2*The M.2 Socket shares bandwidth with the SATA_5/6 ports, and therefore the SATA_5/6 ports cannot be used when an M.2 device is installed.
But it seems that it is a NVME (and not M.2 SATA), and therefore I can use the last 2 SATA ports.
Installation
Ubuntu
- Download Ubuntu Server 24.04 LTS (link).
- Activate OpenSSH and add SSH Keys
- Account:
thomas, hostname:homelab
Install Important software
sudo apt install neovim tmux fd-find ripgrep fzf apache2-utils unrar ranger
Terminal Problem
On the local host, using Termite:
infocmp > termite.terminfo # export Termite's Terminfo
scp termite.terminfo user@remote-host:~/ # or any other method to copy to the remote host
On the remote host, in the directory where you copied termite.terminfo:
tic -x termite.terminfo # import Terminfo for current user
rm termite.terminfo # optional: remove Terminfo file
Minor Modifications of ~/.inputrc
Modify ~/.inputrc, like so:
"\e[A": history-search-backward # arrow up
"\e[B": history-search-forward # arrow down
Partition and Format Disk Drives
A nice tutorial is available here.
lsblk
sudo parted /dev/sda mklabel gpt
sudo parted -a opt /dev/sda mkpart primary ext4 0% 100%
sudo mkfs.ext4 -L primary /dev/sda1
MergerFS and FStab
MergerFS is a transparent layer that sits on top of the data drives providing a single mount point for reads / writes (link).
sudo apt install mergerfs
Create mount points
sudo mkdir /mnt/disk0
sudo mkdir /mnt/disk1
sudo mkdir /mnt/disk2
sudo mkdir /mnt/parity
Create folder where disks will be merged.
sudo mkdir /srv/storage
Edit /etc/fstab.
/dev/disk/by-uuid/7fb7873c-83bd-4805-98ab-506e6c7b56fa /mnt/disk0 ext4 defaults 0 0
/dev/disk/by-uuid/d9e7cc6b-5054-4eb9-bcb2-7e29480e0c6e /mnt/disk1 ext4 defaults 0 0
/dev/disk/by-uuid/6fcd38b9-0886-46bd-900d-cb1f170dbcee /mnt/disk2 ext4 defaults 0 0
/dev/disk/by-uuid/736bf432-baa8-465e-bf8e-c2bbad1cb7dd /mnt/parity ext4 defaults 0 0
/mnt/disk* /srv/storage fuse.mergerfs allow_other,use_ino,cache.files=partial,dropcacheonclose=true,category.create=mfs,fsname=mergerfs 0 0
SnapRAID (link) and SnapRAID Runner (link)
<<sec:snapraid>>
SnapRAID is a snapshot parity calculation tool which acts at the block level independent of filesystem (link).
sudo apt install snapraid
The configuration file is located in /etc/snapraid.conf:
# Defines the file to use as parity storage
# It must NOT be in a data disk
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
content /var/snapraid.content
content /mnt/disk0/.snapraid.content
content /mnt/disk1/.snapraid.content
content /mnt/disk2/.snapraid.content
# Defines the data disks to use
# The order is relevant for parity, do not change it
disk disk0 /mnt/disk0
disk disk1 /mnt/disk1
disk disk2 /mnt/disk2
# Defines files and directories to exclude
exclude /tmp/
exclude /lost+found/
exclude /Downloads/ # This changes a lot, not necessary to backup
exclude *.!sync
exclude .DS_Store
exclude ._.DS_Store
exclude .Thumbs.db
exclude .fseventsd
exclude .Spotlight-V100
exclude .TemporaryItems
exclude .Trashes
exclude .part
Go in the /home/thomas/.local/soft/ directory and clone the snapraid-runner repository.
Then, create the snapraid-runner.conf file:
[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
And finally, create a cronjob with sudo crontab -e and add the following line:
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
Install Docker
The procedure is well explained here.
If docker is already installed, remove it with:
sudo apt remove docker
Executing the Docker Command Without Sudo
sudo usermod -aG docker ${USER}
To apply the new group membership, log out of the server and back in, or type the following:
su - ${USER}
Install Docker-Compose
sudo apt install docker-compose
Setup Docker Networks
docker network create --gateway 192.168.90.1 --subnet 192.168.90.0/24 t2_proxy
docker network create docker_default
Change Timezone
sudo timedatectl set-timezone Europe/Paris
Secure the Web Server
Most of it comes from here.
- Set
PasswordAuthentication noin/etc/ssh/sshd_config
Automatic Security Updates
The procedure is well explained here.
sudo apt install unattended-upgrades update-notifier-common
Edit /etc/apt/apt.conf.d/50unattended-upgrades, and change the following lines:
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "04:00";
Edit /etc/apt/apt.conf.d/20auto-upgrades:
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
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:
*/5 * * * * /home/thomas/cron/caddy_update.sh >> /home/thomas/cron/caddy_update.log 2>&1
That will run every 5 minutes. To check how the first part of the crontab works, check this website.
Setup Traefik proxy
Follow this guide.
Run docker-compose
cd ~/docker && docker-compose up -d
Docker config ~/.docker/config.json
{
"psFormat": "table {{ .ID }}\\t{{ .Names }}\t{{ .Status }}"
}
Install earlyoom for better memory management
https://github.com/rfjakob/earlyoom
sudo apt install earlyoom
Check the status with systemctl status earlyoom.
Maintenance - How To
Update System/Packages
To show possible update:
apt list --upgradable
sudo -- sh -c 'apt-get update; apt-get upgrade -y; apt-get dist-upgrade -y; apt-get autoremove -y; apt-get autoclean -y'
Snapraid errors
If there are errors, you can check what is going on with:
sudo snapraid status
To fix the errors:
sudo snapraid -e fix
You can check again if everything is fixed using the scrub command:
sudo snapraid scrub
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
cd ~/docker/ && docker compose pull --ignore-pull-failures && docker compose up -d
Clean up Docker environment This will delete all unused images, volumes and networks.
docker system prune -f && docker image prune -f && docker volume prune -f
Add wireguard client
With an Android client
Show the QRcode corresponding the a specific peer with:
docker exec -it wireguard /app/show-peer 1
Then, simply scan the QRcode with the Wireguard application.
With a Linux client
Copy the file $CONFIGDIR/wireguard/peeri/peeri.conf, e.g.:
[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
Then, paste the file to /etc/wireguard/interfacename.conf.
And then:
sudo chmod 600 /etc/wireguard/interfacename.confsudo chown root:root /etc/wireguard/interfacename.conf
Then, start the tunnel with:
wg-quick up interfacename
Add new user to authelia
Modify the user database file:
nvim ~/docker/config/authelia/users_database.yml
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
USB config
https://hackaday.io/page/13294-solved-docker-udev-usb-naming
/etc/udev/rules.d/99-usb-serial.rules
# SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", ACTION=="add", RUN+="/home/thomas/docker/mount-usb-device.sh tina2"
# SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", ACTION=="remove", RUN+="/bin/rm -f /dev/ttyUSB-tina2"
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", ACTION=="add", RUN+="/home/thomas/docker/mount-usb-device.sh zigbee"
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", ACTION=="remove", RUN+="/bin/rm -f /dev/ttyUSB-zigbee"
/home/thomas/docker/mount-usb-device.sh
p=""
# if [ "$1" == "tina2" ]
# then
# p=`realpath /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0`
# fi
if [ "$1" == "zigbee" ]
then
p=`realpath /dev/serial/by-id/usb-Silicon_Labs_slae.sh_cc2652rb_stick_-_slaesh_s_iot_stuff_00_12_4B_00_23_93_39_57-if00-port0`
fi
if [ "x$p" != "x" ]
then
rm -f /dev/ttyUSB-$1
ln $p /dev/ttyUSB-$1
fi
Basic Config
networks:
t2_proxy:
external: true
name: t2_proxy
immich:
external: false
backend:
external: false
default:
driver: bridge
x-logging:
&default-logging
driver: "json-file"
options:
max-size: "200k"
max-file: "10"
services:
Docker Config and Tools
traefik - Application proxy (link)
traefik:
container_name: traefik
image: traefik:v3.6
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
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
matrix-internal-matrix-client-api:
address: :8008
api:
dashboard: true
core:
defaultRuleSyntax: v2
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
file:
filename: /etc/traefik/services.yaml
serversTransport:
insecureSkipVerify: true # Necessary for Unifi (but not recommended)
# respondingTimeouts:
# readTimeout: "5s"
# writeTimeout: "5s"
# idleTimeout: "360s"
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
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
basic-auth:
basicAuth:
users:
- "tdehaeze:$2y$05$SSzSMIUEGrfQgZMas1ROYeLzqfuqnQG6hJRgxGWV2It5yv7YzN3Ay"
authelia - Single Sign-On Multi-Factor portal (link)
authelia:
container_name: authelia
image: authelia/authelia:4.35
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"
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:colloc"]
- 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-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: homepage.tdehaeze.xyz
policy: one_factor
subject:
- ["group:admins"]
- domain: wireguard.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:colloc"]
- domain: mqttui.tdehaeze.xyz
policy: one_factor
subject:
- ["group:admins"]
- domain: zigbee2mqtt.tdehaeze.xyz
policy: one_factor
subject:
- ["group:admins"]
- domain: restic.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
networks:
- 172.18.0.0/16
- domain: sonarr.tdehaeze.xyz
policy: one_factor
subject:
- ["group:admins"]
- domain: prowlarr.tdehaeze.xyz
policy: bypass
networks:
- 172.18.0.0/16
- domain: prowlarr.tdehaeze.xyz
policy: one_factor
subject:
- ["group:admins"]
- domain: radarr.tdehaeze.xyz
policy: bypass
networks:
- 172.18.0.0/16
- domain: radarr.tdehaeze.xyz
policy: one_factor
subject:
- ["group:admins"]
- domain: unifi.tdehaeze.xyz
policy: one_factor
subject:
- ["group:admins"]
- domain: joal.tdehaeze.xyz
policy: one_factor
subject:
- ["group:admins"]
- domain: owasabi.tdehaeze.xyz
policy: one_factor
resources:
- "^/control.*$"
subject:
- ["group:admins"]
- ["user:owasabi"]
- domain: owasabi.tdehaeze.xyz
policy: bypass
- domain: owasabi-mountains.tdehaeze.xyz
policy: one_factor
resources:
- "^/control.*$"
subject:
- ["group:admins"]
- ["user:owasabi"]
- domain: owasabi-mountains.tdehaeze.xyz
policy: bypass
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
uptime-kuma - Monitoring Tool (link)
uptime-kuma:
container_name: uptime-kuma
image: louislam/uptime-kuma:2
restart: unless-stopped
networks:
- t2_proxy
environment:
- TZ=$TZ
- PUID=$PUID
- PGID=$PGID
volumes:
- /docker/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
gotify - Notification service (link)
In order to have notifications on Linux desktop use gotify-dunst.
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"
scrutiny - Hard drive monitoring (link)
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
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/sdd:/dev/sdd
- /dev/nvme0:/dev/nvme0
logging: *default-logging
wireguard - VPN (link)
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_HASH='$$2a$$12$$kVt.q4N25VD/n5bXjk9yGubmHlPjGtXKGcDa2c3qYzfse4U502mzm'
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
nginx - Root (used for Matrix)
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
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;
proxy_ssl_server_name on;
}
location /.well-known/matrix/server {
proxy_pass https://matrix.tdehaeze.xyz/.well-known/matrix/server;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_ssl_server_name on;
}
}
}
commento - Commenting system (link)
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
commento_db:
image: postgres:13
shm_size: 512mb
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
rustdesk - Remote desktop application (link)
hbbs:
container_name: hbbs
image: rustdesk/rustdesk-server:latest
restart: unless-stopped
command: hbbs -r rustdesk.tdehaeze.xyz:21117
volumes:
- $CONFIGDIR/rustdesk:/root
ports:
- 21115:21115
- 21116:21116
- 21116:21116/udp
- 21118:21118
depends_on:
- hbbr
hbbr:
container_name: hbbr
image: rustdesk/rustdesk-server:latest
restart: unless-stopped
command: hbbr
volumes:
- $CONFIGDIR/rustdesk:/root
ports:
- 21117:21117
- 21119:21119
labels:
- "traefik.enable=true"
- "traefik.http.routers.rustdesk-rtr.entrypoints=web-secure"
- "traefik.http.routers.rustdesk-rtr.rule=Host(`rustdesk.$DOMAINNAME`)"
- "traefik.http.routers.rustdesk-rtr.tls=true"
- "traefik.http.routers.rustdesk-rtr.service=rustdesk-svc"
- "traefik.http.services.rustdesk-svc.loadbalancer.server.port=21117"
unifi-controller - Software for Unifi devices (link)
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
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
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
Websites
homepage - A highly customizable homepage (link)
homepage:
container_name: homepage
image: ghcr.io/gethomepage/homepage:latest
restart: unless-stopped
networks:
- t2_proxy
environment:
- HOMEPAGE_ALLOWED_HOSTS=* # TODO - Not recommanded See gethomepage.dev/installation/#homepage_allowed_hosts
- UID=$PUID
- GID=$PGID
- TZ=$TZ
volumes:
- $CONFIGDIR/homepage/:/app/config
- /var/run/docker.sock:/var/run/docker.sock:ro # optional, for docker integrations
- /mnt/disk0:/mnt/disk0:ro
- /mnt/disk1:/mnt/disk1:ro
- /mnt/disk2:/mnt/disk2:ro
labels:
- "traefik.enable=true"
- "traefik.http.routers.homepage-rtr.entrypoints=web-secure"
- "traefik.http.routers.homepage-rtr.rule=Host(`homepage.$DOMAINNAME`)"
- "traefik.http.routers.homepage-rtr.tls=true"
- "traefik.http.routers.homepage-rtr.service=homepage-svc"
- "traefik.http.routers.homepage-rtr.middlewares=authelia@docker"
- "traefik.http.services.homepage-svc.loadbalancer.server.port=3000"
logging: *default-logging
hugo - Wiki + Blog (link)
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
research - Research Pages (link)
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
- /docker/research:/srv
# - ~/.ssh:/root/.ssh
labels:
- "homepage.group=Blog"
- "homepage.href=`research.$DOMAINNAME`"
- "homepage.description=Research blog"
- "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
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
}
}
dotfiles - Dotfiles (link)
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
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
}
}
help - Help page for Jellyfin (link)
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
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
}
}
mealie - Recipe Manager (link)
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=9000"
logging: *default-logging
gitea - Git server (link)
gitea:
container_name: gitea
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
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
changedetection - Detect change in websites (link)
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
wingaudio - With Wordpress
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
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
Multimedia
jellyfin - Media server (link)
jellyfin:
container_name: jellyfin
image: linuxserver/jellyfin
restart: unless-stopped
networks:
- t2_proxy
volumes:
- $CONFIGDIR/jellyfin:/config
- /docker/jellyfin-cache:/cache
- /docker/jellyfin-metadata:/metadata
- /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/card1:/dev/dri/card1
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
jellystat - Statistics App for Jellyfin (link)
jellystat:
container_name: jellystat
image: cyfershepard/jellystat:latest
restart: unless-stopped
networks:
- backend
- t2_proxy
environment:
- PUID=$PUID
- PGID=$PGID
- TZ=$TZ
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=fmxi0iS3TSGVigvZ
- POSTGRES_IP=jellystat_db
- POSTGRES_PORT=5432
- JWT_SECRET='k36isYXNuQT7Kk9S'
volumes:
- $CONFIGDIR/jellystat:/app/backend/backup-data
depends_on:
- jellystat_db
labels:
- "traefik.enable=true"
- "traefik.http.routers.jellystat-rtr.entrypoints=web-secure"
- "traefik.http.routers.jellystat-rtr.rule=Host(`jellystat.$DOMAINNAME`)"
- "traefik.http.routers.jellystat-rtr.tls=true"
- "traefik.http.routers.jellystat-rtr.service=jellystat-svc"
- "traefik.http.services.jellystat-svc.loadbalancer.server.port=3000"
logging: *default-logging
jellystat_db:
image: postgres:15.2
shm_size: 512mb
restart: unless-stopped
networks:
- backend
volumes:
- $CONFIGDIR/jellystat_db:/var/lib/postgresql/data
environment:
- PUID=$PUID
- PGID=$PGID
- TZ=$TZ
- POSTGRES_DB='jfstat'
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=fmxi0iS3TSGVigvZ
jfa-go - Manage Jellyfin Users (link)
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
lms - Server for Squeezebox and compatible players (link)
lms:
container_name: lms
image: lmscommunity/lyrionmusicserver
restart: unless-stopped
networks:
- t2_proxy
volumes:
- $CONFIGDIR/lms/config:/config:rw
- $CONFIGDIR/lms/playlist:/playlist:rw
- /srv/storage/Music:/music:ro
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
ports:
- 9000:9000/tcp
- 9090:9090/tcp
- 3483:3483/tcp
environment:
- HTTP_PORT=9000
labels:
- "traefik.enable=true"
# - "traefik.http.routers.lms-rtr.entrypoints=web-secure"
# - "traefik.http.routers.lms-rtr.rule=Host(`lms.$DOMAINNAME`)"
# - "traefik.http.routers.lms-rtr.tls=true"
# - "traefik.http.routers.lms-rtr.service=lms-svc"
# - "traefik.http.services.lms-svc.loadbalancer.server.port=9000"
logging: *default-logging
Cloud
syncthing - File Synchronization (link)
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
sync-anne - File Synchronization (link)
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
sync-jm - File Synchronization (link)
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
filebrowser-quantum - Web file browser (link)
filebrowser:
container_name: filebrowser
image: gtstef/filebrowser:stable
restart: unless-stopped
networks:
- t2_proxy
volumes:
- /srv/storage:/srv/storage
- $CONFIGDIR/filebrowser-quantum:/home/filebrowser/data
- /docker/filebrowser-tmp:/home/filebrowser/tmp # Required if uid other than 1000
user: "${PUID}:${PGID}"
environment:
- FILEBROWSER_CONFIG=data/config.yaml
- FILEBROWSER_DATABASE=data/database.db
- PUID=$PUID
- PGID=$PGID
- TZ=$TZ
labels:
- "traefik.enable=true"
- "traefik.http.routers.cloud-rtr.entrypoints=web-secure"
- "traefik.http.routers.cloud-rtr.rule=Host(`cloud.$DOMAINNAME`)"
- "traefik.http.routers.cloud-rtr.tls=true"
- "traefik.http.routers.cloud-rtr.service=cloud-svc"
- "traefik.http.services.cloud-svc.loadbalancer.server.port=80"
- "traefik.http.middlewares.filebrowser-buffering.buffering.maxRequestBodyBytes=10737418240" # Upload Configuration
logging: *default-logging
radicale - CalDAV/CardDAV server (link)
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
config
[server]
hosts = 0.0.0.0:5232
[auth]
type = htpasswd
htpasswd_filename = /config/users
htpasswd_encryption = md5
[storage]
filesystem_folder = /data/collections
linkding - Bookmark manager (link)
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
backrest - Automatic Backups (link)
restic:
container_name: restic
image: garethgeorge/backrest:latest-alpine
restart: unless-stopped
networks:
- t2_proxy
environment:
- UID=$PUID
- GID=$PGID
- TZ=$TZ
- BACKREST_DATA=/data # path for backrest data. restic binary and the database are placed here.
- BACKREST_CONFIG=/config/config.json # path for the backrest config file.
- XDG_CACHE_HOME=/cache # path for the restic cache which greatly improves performance.
volumes:
- $CONFIGDIR/restic/config:/config
- $CONFIGDIR/restic/data:/data
- /docker/restic-cache:/cache
- /srv/storage/Backups:/srv/Backups # Local Restic Backups
- /srv/storage/Users:/source/Users:ro # User Clouds
- /srv/storage/Cloud:/source/Cloud:ro # My Own Cloud
# - /srv/storage/Music:/source/Music:ro # Musics
- /srv/storage/immich:/source/immich:ro # Musics
- /home/thomas:/source/home:ro # Homelab - Home directory
- /home/thomas/.ssh/known_hosts:/root/.ssh/known_hosts:ro # Used to SSH to backup machine
- /home/thomas/.ssh/id_rsa:/root/.ssh/id_rsa:ro # Used to SSH to backup machine
labels:
- "traefik.enable=true"
- "traefik.http.routers.restic-rtr.entrypoints=web-secure"
- "traefik.http.routers.restic-rtr.rule=Host(`restic.$DOMAINNAME`)"
- "traefik.http.routers.restic-rtr.tls=true"
- "traefik.http.routers.restic-rtr.service=restic-svc"
- "traefik.http.routers.restic-rtr.middlewares=authelia@docker"
- "traefik.http.services.restic-svc.loadbalancer.server.port=9898"
logging: *default-logging
miniflux - RSS reader (link)
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
miniflux_db:
container_name: miniflux_db
image: postgres:12
shm_size: 512mb
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
Home
mosquitto - MQTT broker (link)
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
zigbee2mqtt - Zigbee to MQTT bridge (link)
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/ttyUSB-zigbee:/dev/ttyUSB0: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
node-red - Automation tool (link)
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
esphome - System to control ESP8266/ESP32 devices (link)
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
- /docker/.esphome:/config/.esphome
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
mqttui - MQTT Web Interface (link)
mqttui:
container_name: mqttui
image: terdia07/mqttui
restart: unless-stopped
networks:
- t2_proxy
environment:
- PUID=$PUID
- PGID=$PGID
- TZ=$TZ
- MQTT_BROKER=192.168.1.21
- MQTT_PORT=1883
labels:
- "traefik.enable=true"
- "traefik.http.routers.mqttui-rtr.entrypoints=web-secure"
- "traefik.http.routers.mqttui-rtr.rule=Host(`mqttui.$DOMAINNAME`)"
- "traefik.http.routers.mqttui-rtr.tls=true"
- "traefik.http.routers.mqttui-rtr.service=mqttui-svc"
- "traefik.http.routers.mqttui-rtr.middlewares=authelia@docker"
- "traefik.http.services.mqttui-svc.loadbalancer.server.port=5000"
logging: *default-logging
influxdb - Scalable datastore for metrics, events, and real-time analytics (link)
influxdb:
container_name: influxdb
image: influxdb
restart: unless-stopped
networks:
- t2_proxy
- backend
environment:
- PUID=$PUID
- PGID=$PGID
- TZ=$TZ
volumes:
- /docker/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
Immich
immich-server
immich-server:
container_name: immich-server
image: ghcr.io/immich-app/immich-server:release
restart: unless-stopped
networks:
- t2_proxy
- immich
volumes:
- /srv/storage/immich:/usr/src/app/upload
- /etc/localtime:/etc/localtime:ro
env_file:
- immich.env
depends_on:
- immich-redis
- immich-database
user: "${PUID}:${PGID}"
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=2283"
logging: *default-logging
immich-machine-learning
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
- /docker/immich-machine-learning-cache:/cache
env_file:
- immich.env
user: "${PUID}:${PGID}"
logging: *default-logging
immich-redis
immich-redis:
container_name: immich-redis
image: redis:6.2-alpine@sha256:70a7a5b641117670beae0d80658430853896b5ef269ccf00d1827427e3263fa3
restart: unless-stopped
networks:
- immich
logging: *default-logging
immich-database
immich-database:
container_name: immich-database
image: ghcr.io/immich-app/postgres:14-vectorchord0.3.0-pgvectors0.2.0
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
# Uncomment the DB_STORAGE_TYPE: 'HDD' var if your database isn't stored on SSDs
# - DB_STORAGE_TYPE: 'HDD'
volumes:
- $CONFIGDIR/immich/postgresql-data:/var/lib/postgresql/data
logging: *default-logging
immich.env
###################################################################################
# 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=log
####################################################################################
# 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-server: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
Affichtoo
affichtoo-owasabi - Affichtoo
affichtoo-owasabi:
container_name: affichtoo-owasabi
image: tdehaeze/affichtoo
restart: unless-stopped
networks:
- t2_proxy
environment:
- UID=$PUID
- GID=$PGID
- TZ=$TZ
volumes:
- $CONFIGDIR/affichtoo/owasabi:/app/static/conf
labels:
- "traefik.enable=true"
- "traefik.http.routers.owasabi-rtr.entrypoints=web-secure"
- "traefik.http.routers.owasabi-rtr.rule=Host(`owasabi.$DOMAINNAME`)"
- "traefik.http.routers.owasabi-rtr.tls=true"
- "traefik.http.routers.owasabi-rtr.service=owasabi-svc"
- "traefik.http.routers.owasabi-rtr.middlewares=authelia@docker"
- "traefik.http.services.owasabi-svc.loadbalancer.server.port=8000"
logging: *default-logging
affichtoo-owasabi-mountains - Affichtoo
affichtoo-owasabi-mountins:
container_name: affichtoo-owasabi-mountins
image: tdehaeze/affichtoo
restart: unless-stopped
networks:
- t2_proxy
environment:
- UID=$PUID
- GID=$PGID
- TZ=$TZ
volumes:
- $CONFIGDIR/affichtoo/owasabi-mountains:/app/static/conf
labels:
- "traefik.enable=true"
- "traefik.http.routers.owasabi-mountains-rtr.entrypoints=web-secure"
- "traefik.http.routers.owasabi-mountains-rtr.rule=Host(`owasabi-mountains.$DOMAINNAME`)"
- "traefik.http.routers.owasabi-mountains-rtr.tls=true"
- "traefik.http.routers.owasabi-mountains-rtr.service=owasabi-mountains-svc"
- "traefik.http.routers.owasabi-mountains-rtr.middlewares=authelia@docker"
- "traefik.http.services.owasabi-mountains-svc.loadbalancer.server.port=8000"
logging: *default-logging
TODO Matrix
Matrix server
Use Ansible https://github.com/spantaleev/matrix-docker-ansible-deploy
Must install newer version of ansible:
Basic Config
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 }}"
# =================================================================================================
# 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
Use Traefik as reverse proxy
# =================================================================================================
# 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"'
Bridges
Slack
# Slack
matrix_mx_puppet_slack_enabled: true
matrix_mx_puppet_slack_client_id: "299050134212.1969032215654"
matrix_mx_puppet_slack_client_secret: "9a3240e570997645d4961d3cb595e798"
# WhatsApp
matrix_mautrix_whatsapp_enabled: true
Signal
# Signal
matrix_mautrix_signal_enabled: true
# Facebook
matrix_mautrix_facebook_enabled: true
Telegram
# Telegram
matrix_mautrix_telegram_enabled: true
matrix_mautrix_telegram_api_id: 5596434
matrix_mautrix_telegram_api_hash: 29d6742e35799b88b9a7b5a46fe05ff2
Backup server
Hardware
Install
Install MicroSD
Ubuntu 20.04 minimal
First boot
Choose "Exit to shell" (switch to console then)
(back to petiboot menu)
Setup SSH and Drive
- create
thomasuser - add user to sudo group
- add SSH key (use
ssh-copy-id) - disable root ssh and password authentication
- format disk drive
- edit
/etc/fstabto add the disk drive and mount it to/srv/storage.
Install packages
sudo apt install neovim tmux fd-find ripgrep fzf apache2-utils unrar ranger man git
Update
sudo apt update
sudo apt upgrade
Poweroff without sudo
add the following at the end of /etc/sudoers:
thomas backup =NOPASSWD: /usr/bin/systemctl poweroff,/usr/bin/systemctl halt,/usr/bin/systemctl reboot
Install Restic
Restic is used for Backup.
The binary is installed directly from Github (for instance restic_0.16.2_linux_arm64.bz2).
Then, the binary is copied in /usr/local/bin.
To update restic, use the command restic self-update.
Cron Jobs
Snapraid
A snapraid Cron job is run with the Root user (use sudo crontab -e to edit). (See Section ref:sec:snapraid).
Restic Backup Restart Container
Sometimes the restic container fails and keeps restarting as it fails to reach the backup server (which is off).
Music Multi-CD
Create a script ~/cron/music-multi-cd.sh with:
shopt -s extglob globstar
find /srv/storage/Music/ -maxdepth 2 -type d -name "Disc\ 1" -print0 | while read -d $'\0' file
do
echo $file
cd_dir=$(dirname "$file")
cd_name=$(basename "$cd_dir")
mkdir "$cd_dir/$cd_name" && \
mv "$cd_dir"/Disc* "$cd_dir/$cd_name/"
mv "$cd_dir/cover.jpg" "$cd_dir/$cd_name/"
done
Type crontab -e and add this line:
1 2 * * * /home/thomas/cron/music-multi-cd.sh >> /home/thomas/cron/music-multi-cd.log 2>&1
TODO Caddy Update
- Is this even still in use?
Create a script ~/cron/caddy_update.sh with:
docker exec caddy /bin/sh -c "cd /srv/www && echo -e \"Update repo $(date)\" && git submodule update --recursive --remote --merge"
Type crontab -e and add this line:
*/5 * * * * /home/thomas/cron/caddy_update.sh >> /home/thomas/cron/caddy_update.log 2>&1
Back OpenWRT Config
Create a script ~/cron/backup_openwrt_conf.sh with:
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/
Type crontab -e and add this line:
*/5 * * * * /home/thomas/cron/backup_openwrt_conf.sh >> /home/thomas/cron/backup_openwrt_conf.log 2>&1