Home Server
Table of Contents
- Hardware
- Installation
- Ubuntu
- Install Important software
- Terminal Problem
- Minor Modifications of
~/.inputrc
- Partition and Format Disk Drives
- MergerFS and FStab
- Automating with SnapRAID Runner
- 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
- Run
docker-compose
- Docker config
~/.docker/config.json
- Matrix server
- Maintenance - How To
- Docker-Compose
- Basic Config
- Docker Config and Tools
traefik
- Application proxy (link)authelia
- Single Sign-On Multi-Factor portal (link)portainer
- Manage docker (link)uptime-kuma
- Monitoring Tool (link)gotify
- Notification service (link)snapraid
- Manage local backup with parity disk (link)scrutiny
- Hard drive monitoring (link)wireguard
- VPN (link)nginx
- Root (used for Matrix)diun
- Notification for Docker image updates (link)
- Websites
wasabi
- Affichtoopotaupho
- Affichtoohomer
- Home page (link)hugo
- Wiki + Blog (link)research
- Research Pages (link)dotfiles
- Dotfiles (link)family-page
- Dotfiles (link)wikijs
- Wiki App (link)commento
- Commenting system (link)mealie
- Recipe Manager (link)gitea
- Git server (link)changedetection
- Detect change in websites (link)
- Multimedia
- Cloud
syncthing
- File Synchronization (link)sync-anne
- File Synchronization (link)sync-jm
- File Synchronization (link)sync-ju
- File Synchronization (link)filebrowser
- Web file browser (link)photoprism
(link)radicale
- CalDAV/CardDAV server (link)linkding
- Bookmark manager (link)restic-b2
- Automatic backups on BackBlaze (link)restic-aouste
- Automatic backups on Raspberry (link)miniflux
- RSS reader (link)
- Home
homeassistant
- Home Automation (link)mosquitto
- MQTT broker (link)zigbee2mqtt
- Zigbee to MQTT bridge (link)node-red
- Automation toolesphome
- Automation toolalfawiseu20
- Web interface for 3D printing (link)tina2
- Web interface for 3D printing (link)ihatemoney
- Tricount Alternative (link)
- Download
- Cron Jobs
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 (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 "partitionname" ext4 0% 100%
sudo mkfs.ext4 -L partitionname /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/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/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
Automating with SnapRAID Runner
Install Docker
The procedure is well explained here.
If docker is already installed, remove it:
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
no in/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.
Run docker-compose
cd ~/docker && docker-compose up -d
Docker config ~/.docker/config.json
{ "psFormat": "table {{ .ID }}\\t{{ .Names }}\t{{ .Status }}" }
Matrix server
Use Ansible https://github.com/spantaleev/matrix-docker-ansible-deploy
Must install newer version of ansible:
Maintenance - How To
Update System/Packages
sudo -- sh -c 'apt-get update; apt-get upgrade -y; apt-get dist-upgrade -y; apt-get autoremove -y; apt-get autoclean -y'
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
snapraid
To see all files “backed up” by snapraid, use:
docker exec -ti snapraid snapraid list | fzf
In reality, snapraid is ran from the docker container:
docker exec -ti snapraid snapraid fix -f <path_to_file>
The path to file should be relative: /srv/storage/Cloud/org/file.org
-> Cloud/org/file.org
Restore Online backup with restic
To list backups:
docker exec restic restic snapshots
ID Time Host Tags Paths -------------------------------------------------------------------------------- a7b98408 2020-09-03 21:18:00 4803c2af7d4e /data/documents/manuals 088e31a4 2020-09-03 21:50:26 4803c2af7d4e /data/documents/manuals 9cf0b480 2020-09-03 22:05:47 4803c2af7d4e /data/documents/manuals -------------------------------------------------------------------------------- 3 snapshots
Force backup of folder:
docker exec restic restic backup /data/documents/manuals
Files: 0 new, 2 changed, 8475 unmodified Dirs: 0 new, 2 changed, 0 unmodified Added to the repo: 1.010 KiB processed 8477 files, 589.800 MiB in 0:02 snapshot 9cf0b480 saved
Find the path to the file within the snapshot:
docker exec restic restic find file_name
Find files only for a specific snapshot:
docker exec restic restic find -s latest file_name
Restore files/folders (replace file/folders):
docker exec restic restic restore --include /data/documents/manuals --target / 088e31a4
You can use latest
instead of the ID.
If indeed, we want to make a copy of the file, we can use the backup folder
docker exec restic restic restore --include /data/documents/manuals --target /backup 088e31a4
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.conf
sudo chown root:root /etc/wireguard/interfacename.conf
Then, start the tunnel with:
wg-quick up interfacename
Docker-Compose
Basic Config
version: "3.4"
networks: t2_proxy: external: name: t2_proxy 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:2.2.1 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=http" - "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=https" - "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.domains[0].main=$DOMAINNAME" - "traefik.http.routers.traefik-rtr.tls.domains[0].sans=*.$DOMAINNAME" - "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=https" - "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=https" - "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" # Basic Auth - "traefik.http.middlewares.wasabi-auth.basicauth.users=wasabi:$$2y$$05$$GWMXPYbVPtIbnKR8nJBUseTfuLn4vgMzMXtIqs.3.0Je9eUGbRiwG" - "traefik.http.middlewares.potaupho-auth.basicauth.users=potaupho:$$2y$$05$$0.hcoM36J1bhooHg6w/PBeP.HyxUpZwU7eFurq5RCrpaYNMVq1f4y" logging: *default-logging
traefik.yaml
global: checkNewVersion: true sendAnonymousUsage: false entryPoints: http: address: :80 https: 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 synapse: address: :8448 api: dashboard: true log: level: ERROR 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 watch: true certificatesResolvers: dns-cloudflare: acme: email: $CLOUDFLARE_EMAIL storage: /acme.json dnsChallenge: provider: cloudflare resolvers: 1.1.1.1:53,1.0.0.1:53
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/"
authelia
- Single Sign-On Multi-Factor portal (link)
authelia: image: authelia/authelia:4.30 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=$AUTHELIA_NOTIFIER_SMTP_PASSWORD - AUTHELIA_JWT_SECRET=$AUTHELIA_JWT_SECRET labels: - "traefik.enable=true" - "traefik.http.routers.authelia-rtr.entrypoints=https" - "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: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: portainer.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: octoprint.tdehaeze.xyz policy: one_factor subject: - ["group:admins"] - ["group:family"] - domain: tina2.tdehaeze.xyz policy: one_factor subject: - ["group:admins"] - ["group:family"] - 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: 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"] session: name: authelia_session expiration: 3600 inactivity: 300 domain: tdehaeze.xyz regulation: max_retries: 3 find_time: 120 ban_time: 300 storage: local: path: /config/db.sqlite3 notifier: smtp: username: tdehaeze.xyz@gmail.com host: smtp.gmail.com port: 587 sender: tdehaeze.xyz@gmail.com
portainer
- Manage docker (link)
portainer: container_name: portainer image: portainer/portainer restart: unless-stopped command: -H unix:///var/run/docker.sock command: --no-auth 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=https" - "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
uptime-kuma
- Monitoring Tool (link)
uptime-kuma: container_name: uptime-kuma image: louislam/uptime-kuma restart: unless-stopped networks: - t2_proxy volumes: environment: - TZ=$TZ - UID=$PUID - GID=$PGID volumes: - $CONFIGDIR/uptime-kuma:/app/data labels: - "traefik.enable=true" - "traefik.http.routers.uptime-rtr.entrypoints=https" - "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=https" - "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"
snapraid
- Manage local backup with parity disk (link)
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
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 d0 /mnt/disk0 disk d1 /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 *.unrecoverable exclude /tmp/ exclude /lost+found/ exclude *.!sync exclude .AppleDouble exclude ._AppleDouble exclude .DS_Store exclude ._.DS_Store exclude .Thumbs.db exclude .fseventsd exclude .Spotlight-V100 exclude .TemporaryItems exclude .Trashes exclude .AppleDB
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
scrutiny
- Hard drive monitoring (link)
scrutiny: container_name: scrutiny image: linuxserver/scrutiny restart: unless-stopped networks: - t2_proxy cap_add: - SYS_RAWIO - SYS_ADMIN environment: - PUID=$PUID - PGID=$PGID - TZ=$TZ - SCRUTINY_WEB=true - SCRUTINY_COLLECTOR=false volumes: - $CONFIGDIR/scrutiny:/config - /run/udev:/run/udev:ro devices: - /dev/sda:/dev/sda - /dev/sdb:/dev/sdb - /dev/sdc:/dev/sdc - /dev/sdd:/dev/sdd - /dev/nvme0n1:/dev/nvme0n1 labels: - "traefik.enable=true" - "traefik.http.routers.scrutiny-rtr.entrypoints=https" - "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
wireguard
- VPN (link)
wireguard: container_name: wireguard image: linuxserver/wireguard restart: unless-stopped networks: - t2_proxy cap_add: - NET_ADMIN - SYS_MODULE environment: - PUID=$PUID - PGID=$PGID - TZ=$TZ - SERVERURL=wireguard.tdehaeze.xyz - SERVERPORT=51820 - PEERS=4 - PEERDNS=8.8.8.8 volumes: - $CONFIGDIR/wireguard:/config - /lib/modules:/lib/modules ports: - 51820:51820/udp logging: *default-logging
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=wireguard.tdehaeze.xyz - PASSWORD=$WIREGUARD_PASS volumes: - $CONFIGDIR/wg-easy:/etc/wireguard - /lib/modules:/lib/modules ports: - 51820:51820/udp labels: - "traefik.enable=true" - "traefik.http.routers.wireguard-rtr.entrypoints=https" - "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=https" - "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; } location /.well-known/matrix/server { proxy_pass https://matrix.tdehaeze.xyz/.well-known/matrix/server; proxy_set_header X-Forwarded-For $remote_addr; } } }
diun
- Notification for Docker image updates (link)
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
Websites
wasabi
- Affichtoo
wasabi: container_name: wasabi image: tdehaeze/affichtoo restart: unless-stopped networks: - t2_proxy environment: - UID=$PUID - GID=$PGID - TZ=$TZ volumes: - $CONFIGDIR/wasabi/config:/app/config labels: - "traefik.enable=true" - "traefik.http.routers.wasabi-rtr.entrypoints=https" - "traefik.http.routers.wasabi-rtr.rule=Host(`wasabi.$DOMAINNAME`)" - "traefik.http.routers.wasabi-rtr.tls=true" - "traefik.http.routers.wasabi-rtr.service=wasabi-svc" - "traefik.http.services.wasabi-svc.loadbalancer.server.port=8000" - "traefik.http.routers.wasabi-rtr.middlewares=wasabi-auth" logging: *default-logging
potaupho
- Affichtoo
potaupho: container_name: potaupho image: tdehaeze/affichtoo restart: unless-stopped networks: - t2_proxy environment: - UID=$PUID - GID=$PGID - TZ=$TZ volumes: - $CONFIGDIR/potaupho/config:/app/config labels: - "traefik.enable=true" - "traefik.http.routers.potaupho-rtr.entrypoints=https" - "traefik.http.routers.potaupho-rtr.rule=Host(`potaupho.$DOMAINNAME`)" - "traefik.http.routers.potaupho-rtr.tls=true" - "traefik.http.routers.potaupho-rtr.service=potaupho-svc" - "traefik.http.services.potaupho-svc.loadbalancer.server.port=8000" - "traefik.http.routers.potaupho-rtr.middlewares=potaupho-auth" logging: *default-logging
homer
- Home page (link)
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=https" - "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
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: "Wiki" logo: "/assets/tools/wikijs.png" subtitle: "Shared Wiki" url: "https://wiki.tdehaeze.xyz" - name: "Research" logo: "/assets/tools/orgmode.png" subtitle: "Research Pages" url: "https://research.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: "Multimedia" icon: "fas fa-photo-video" items: - name: "Jellyfin" logo: "/assets/tools/jellyfin.png" subtitle: "Media Library" url: "https://jellyfin.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: "File Browser" logo: "/assets/tools/cloud.png" subtitle: "Simple Personnal Could" url: "https://cloud.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: "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: "Gitea" logo: "/assets/tools/gitea.png" subtitle: "Git Server" url: "https://git.tdehaeze.xyz" - name: "Download" icon: "fas fa-download" items: - 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: "Transmission" logo: "/assets/tools/transmission.png" subtitle: "Torrent Client" url: "http://torrent.tdehaeze.xyz:9091/transmission/web/" - name: "Joal" logo: "/assets/tools/joal.png" subtitle: "Increase Ratio" url: "https://joal.tdehaeze.xyz/joal/ui/#/" - 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: "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: "JFA-Go" logo: "/assets/tools/jellyfin.png" subtitle: "Manage Jellyfin Users" url: "http://jfa.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: "Home Assistant" logo: "/assets/tools/homeassistant.png" subtitle: "Home Assistant" url: "http://home.tdehaeze.xyz:8123" - 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: "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: "3D-Printing" url: "https://octoprint.tdehaeze.xyz/"
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=https" - "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)
caddy: container_name: caddy 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/caddy/Caddyfile:/etc/Caddyfile - $CONFIGDIR/web:/srv # - ~/.ssh:/root/.ssh labels: - "traefik.enable=true" - "traefik.http.routers.caddy-rtr.entrypoints=https" - "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 } }
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=https" - "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 } }
family-page
- Dotfiles (link)
family-page: container_name: family-page 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/family-page/Caddyfile:/etc/Caddyfile - $CONFIGDIR/family-page/www:/srv/www labels: - "traefik.enable=true" - "traefik.http.routers.family-page-rtr.entrypoints=https" - "traefik.http.routers.family-page-rtr.rule=Host(`help.$DOMAINNAME`)" - "traefik.http.routers.family-page-rtr.tls=true" - "traefik.http.routers.family-page-rtr.service=family-page-svc" - "traefik.http.services.family-page-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 /family-page/webhook 0fdVzNShbcmw } }
wikijs
- Wiki App (link)
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=https" - "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
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=$GMAIL_PASS - COMMENTO_SMTP_FROM_ADDRESS=tdehaeze.xyz@gmail.com depends_on: - commento_db labels: - "traefik.enable=true" - "traefik.http.routers.commento-rtr.entrypoints=https" - "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: container_name: commento_db image: postgres:13 restart: unless-stopped networks: - backend environment: - POSTGRES_DB=commento - POSTGRES_USER=postgres - POSTGRES_PASSWORD=$COMMENTO_DB_PASSWORD volumes: - $CONFIGDIR/commento_db:/var/lib/postgresql/data logging: *default-logging
mealie
- Recipe Manager (link)
miam: container_name: miam image: hkotel/mealie restart: unless-stopped networks: - t2_proxy environment: - db_type=sqlite - UID=$PUID - GID=$PGID - TZ=$TZ volumes: - $CONFIGDIR/mealie:/app/data labels: - "traefik.enable=true" - "traefik.http.routers.miam-rtr.entrypoints=https" - "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
gitea
- Git server (link)
gitea: container_name: git image: gitea/gitea:1.13.2 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=https" - "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 environment: - MYSQL_ROOT_PASSWORD=$GITEA_DB_MYSQL_ROOT_PASSWORD - MYSQL_DATABASE=gitea - MYSQL_USER=gitea - MYSQL_PASSWORD=$GITEA_DB_MYSQL_PASSWORD volumes: - $CONFIGDIR/mariadb:/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: - UID=$PUID - GID=$PGID - TZ=$TZ - BASE_URL=https://change.tdehaeze.xyz volumes: - $CONFIGDIR/changedetection:/datastore labels: - "traefik.enable=true" - "traefik.http.routers.changedetection-rtr.entrypoints=https" - "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
Multimedia
jellyfin
- Media server (link)
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=https" - "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
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=https" - "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
audioserve
- Audiobook server (link)
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=https" - "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
kavita
- Reading server (link)
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=https" - "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
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=https" - "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=https" - "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=https" - "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
sync-ju
- File Synchronization (link)
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 ports: - 22003:22003 - 21030:21030/udp labels: - "traefik.enable=true" - "traefik.http.routers.sync-ju-rtr.entrypoints=https" - "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
filebrowser
- Web file browser (link)
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=https" - "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
.filebrowser.json
{ "port": 80, "baseURL": "", "address": "", "log": "stdout", "database": "/database.db", "root": "/srv/storage" }
photoprism
(link)
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=https" - "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
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
radicale
- CalDAV/CardDAV server (link)
radicale: container_name: radicale image: tomsquest/docker-radicale:latest 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=https" - "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:latest restart: unless-stopped networks: - t2_proxy volumes: - $CONFIGDIR/linkding:/etc/linkding/data environment: - TZ=$TZ - PUID=$PUID - PGID=$PGID labels: - "traefik.enable=true" - "traefik.http.routers.linkding-rtr.entrypoints=https" - "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
restic-b2
- Automatic backups on BackBlaze (link)
restic-b2: container_name: restic-b2 image: mazzolino/restic restart: unless-stopped networks: - t2_proxy environment: - BACKUP_CRON=0 30 0 * * * - RESTIC_REPOSITORY=b2:tdehaeze:/restic - 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 - B2_ACCOUNT_ID=$RESTIC_B2_ACCOUNT_ID - B2_ACCOUNT_KEY=$RESTIC_B2_ACCOUNT_KEY - UID=$PUID - GID=$PGID - TZ=$TZ - POST_COMMANDS_FAILURE=curl "https://gotify.tdehaeze.xyz/message?token=$RESTIC_GOTIFY_TOKEN" -F "title=Restic B2" -F "message=Backup failed" -F "priority=5" volumes: - $CONFIGDIR/restic-b2/exclude.txt:/exclude.txt:ro - /srv/storage/Cloud/thesis:/source/Cloud/thesis:ro - /home/thomas/docker:/source/docker:ro logging: *default-logging
exclude.txt
- Exclude files
*.db *.log *.log.* /source/docker/config/gitea/git/ /source/docker/config/guacamole/ /source/docker/config/guacamole_db/ /source/docker/config/mariadb/ /source/docker/config/miniflux_db/ /source/docker/config/jellyfin/data/ /source/docker/config/dotfiles/www/ /source/docker/config/web/www/
restic-aouste
- Automatic backups on Raspberry (link)
restic-aouste: container_name: restic-aouste image: mazzolino/restic restart: unless-stopped networks: - t2_proxy environment: - BACKUP_CRON=0 30 3 * * * - RESTIC_REPOSITORY=sftp:thomas@192.168.1.22:/hdd/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 - UID=$PUID - GID=$PGID - TZ=$TZ - POST_COMMANDS_FAILURE=curl "https://gotify.tdehaeze.xyz/message?token=AoWn1nAMGoCE0om" -F "title=Restic Aouste" -F "message=Backup failed" -F "priority=5" volumes: - $CONFIGDIR/restic-aouste/exclude.txt:/exclude.txt:ro - /srv/storage/Users:/source/Users:ro - /home/thomas/.ssh/known_hosts:/root/.ssh/known_hosts:ro - /home/thomas/.ssh/id_rsa:/root/.ssh/id_rsa:ro logging: *default-logging
exclude.txt
- Exclude files
*.db *.log *.log.*
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=https" - "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 restart: unless-stopped networks: - backend environment: - POSTGRES_USER=miniflux - POSTGRES_PASSWORD=$MINIFLUX_POSTGRES_PASSWORD volumes: - $CONFIGDIR/miniflux_db:/var/lib/postgresql/data logging: *default-logging
Home
homeassistant
- Home Automation (link)
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=https" - "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
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 devices: - /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:/dev/ttyUSB0 labels: - "traefik.enable=true" - "traefik.http.routers.zigbee2mqtt-rtr.entrypoints=https" - "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
node-red: container_name: node-red image: nodered/node-red:latest restart: unless-stopped networks: - t2_proxy environment: - PUID=$PUID - PGID=$PGID - TZ=$TZ volumes: - $CONFIGDIR/node-red:/data labels: - "traefik.enable=true" - "traefik.http.routers.node-red-rtr.entrypoints=https" - "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
- Automation tool
esphome: container_name: esphome image: esphome/esphome:latest 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=https" - "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
alfawiseu20
- Web interface for 3D printing (link)
octoprint: container_name: alfawiseu20 image: octoprint/octoprint restart: unless-stopped networks: - t2_proxy environment: - UID=$PUID - GID=$PGID - TZ=$TZ privileged: true volumes: - $CONFIGDIR/alfawiseu20:/octoprint - /dev/bus/usb:/dev/bus/usb labels: - "traefik.enable=true" - "traefik.http.routers.alfawiseu20-rtr.entrypoints=https" - "traefik.http.routers.alfawiseu20-rtr.rule=Host(`alfawiseu20.$DOMAINNAME`)" - "traefik.http.routers.alfawiseu20-rtr.tls=true" - "traefik.http.routers.alfawiseu20-rtr.service=alfawiseu20-svc" - "traefik.http.routers.alfawiseu20-rtr.middlewares=authelia@docker" - "traefik.http.services.alfawiseu20-svc.loadbalancer.server.port=80" logging: *default-logging
tina2
- Web interface for 3D printing (link)
tina2: container_name: tina2 image: octoprint/octoprint restart: unless-stopped networks: - t2_proxy environment: - UID=$PUID - GID=$PGID - TZ=$TZ privileged: true volumes: - $CONFIGDIR/tina2:/octoprint - /dev/bus/usb:/dev/bus/usb labels: - "traefik.enable=true" - "traefik.http.routers.tina2-rtr.entrypoints=https" - "traefik.http.routers.tina2-rtr.rule=Host(`tina2.$DOMAINNAME`)" - "traefik.http.routers.tina2-rtr.tls=true" - "traefik.http.routers.tina2-rtr.service=tina2-svc" - "traefik.http.routers.tina2-rtr.middlewares=authelia@docker" - "traefik.http.services.tina2-svc.loadbalancer.server.port=80" logging: *default-logging
ihatemoney
- Tricount Alternative (link)
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=https" - "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
Download
gluetun
- Provide VPN connection to other containers (link)
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
transmission
- Torrent client (link)
transmission: container_name: transmission image: lscr.io/linuxserver/transmission restart: unless-stopped network_mode: container:gluetun depends_on: - 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
Cron Jobs
Caddy Update
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