diff --git a/pi1/bin/armbian-tx-stats-html.nu b/bin/armbian-tx-stats-html.nu
similarity index 100%
rename from pi1/bin/armbian-tx-stats-html.nu
rename to bin/armbian-tx-stats-html.nu
diff --git a/pi0/bin/mastodon-db-backup b/bin/mastodon-db-backup
similarity index 100%
rename from pi0/bin/mastodon-db-backup
rename to bin/mastodon-db-backup
diff --git a/pi1/bin/qbth b/bin/qbth
similarity index 100%
rename from pi1/bin/qbth
rename to bin/qbth
diff --git a/pi1/bin/qbtlist b/bin/qbtlist
similarity index 100%
rename from pi1/bin/qbtlist
rename to bin/qbtlist
diff --git a/pi1/bin/seed-armbian-tx.nu b/bin/seed-armbian-tx.nu
similarity index 100%
rename from pi1/bin/seed-armbian-tx.nu
rename to bin/seed-armbian-tx.nu
diff --git a/pi1/bin/tx-stats-html.nu b/bin/tx-stats-html.nu
similarity index 100%
rename from pi1/bin/tx-stats-html.nu
rename to bin/tx-stats-html.nu
diff --git a/pi0/gmcapsulerc b/gmcapsulerc
similarity index 100%
rename from pi0/gmcapsulerc
rename to gmcapsulerc
diff --git a/justfile b/justfile
new file mode 100644
index 0000000..1fb1bbc
--- /dev/null
+++ b/justfile
@@ -0,0 +1,158 @@
+## Justfile (https://github.com/casey/justfile)
+##
+## Orange Pi 5+ x 3
+##
+## Services:
+## - ArchiveBox
+## - Caddy web server
+## - gmcapsuled
+## - Mastodon auxiliary scripts
+## - qBittorrent + WireGuard
+## - Tailscale
+## - The Lounge IRC
+
+debian_codename := `grep "VERSION_CODENAME" /etc/os-release | awk -F= '{print $2}'`
+run_user := env_var("USER")
+archivebox_data := "/nfs/archivebox"
+archivebox_nfs := "10.0.0.6:/mnt/coffeeNAS/archivebox"
+
+default: common
+
+common:
+ sudo apt update
+ sudo apt dist-upgrade -y
+ sudo apt install -y \
+ apt-file \
+ apt-listchanges \
+ apt-utils \
+ atop \
+ autoconf \
+ automake \
+ build-essential \
+ byobu \
+ cmake \
+ curl \
+ firewalld \
+ git \
+ glances \
+ htop \
+ httpie \
+ ifplugd \
+ iotop \
+ less \
+ libpam-systemd \
+ lynis \
+ man-db \
+ manpages \
+ nfs-common \
+ nmon \
+ pipx \
+ python3-dev \
+ python3-pip \
+ rsync \
+ unattended-upgrades \
+ vim \
+ wget \
+ zsh
+ sudo systemctl unmask systemd-logind
+ sudo systemctl enable systemd-logind
+ sudo sed -i 's/INTERFACES=\"\"/INTERFACES=\"eth0\"' /etc/default/ifplugd
+ sudo systemctl enable ifplugd
+ sudo systemctl enable systemd-networkd
+ sudo systemctl enable man-db.timer
+ sudo cp -v "${PWD}/systemd/network/eth0.network" /etc/systemd/network/
+ sudo chown root:root /etc/systemd/network/eth0.network
+ sudo usermod -s /usr/bin/zsh {{run_user}}
+
+caddy-install:
+ sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
+ curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
+ | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
+ curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
+ | sudo tee /etc/apt/sources.list.d/caddy-stable.list
+ sudo apt update
+ sudo apt install caddy
+ sudo rsync -aAXP "${PWD}/caddy/" /etc/caddy
+
+archivebox-mnt-nfs:
+ sudo mkdir -p {{archivebox_data}}
+ if ! df -h | grep "archivebox"; then \
+ sudo chown -R {{run_user}}:{{run_user}} {{archivebox_data}}; \
+ fi
+ if ! grep "archivebox" /etc/fstab; then \
+ echo "{{archivebox_nfs}} {{archivebox_data}} nfs4 soft,intr,rsize=8192,wsize=8192" \
+ | sudo tee -a /etc/fstab; \
+ fi
+ sudo systemctl daemon-reload
+ sudo mount -av
+
+archivebox-install:
+ sudo apt install -y pipx python3-dev python3-pip nodejs npm curl wget git ripgrep
+ pipx install archivebox
+ pipx install yt-dlp
+ pipx install playwright
+ playwright install --with-deps chromium
+
+archivebox-init:
+ cd {{archivebox_data}} && archivebox init --setup
+
+archivebox-setup:
+ cd {{archivebox_data}} && archivebox setup
+
+gmcapsuled-install:
+ pipx install gmcapsule
+ mkdir -p ~/.config/systemd/user
+ cp -v "${PWD}/systemd/user/gmcapsuled.service" ~/.config/systemd/user/
+ cp -v "${PWD}/gmcapsulerc" ~/.gmcapsulerc
+
+mastodon-aux-setup:
+ sudo apt install -y rclone
+ sudo cp -v "${PWD}/systemd/system/mastodon"* /etc/systemd/system/
+ sudo cp -v "${PWD}/bin/mastodon-db-backup" /usr/local/bin
+ sudo chown -R root:root /usr/local/bin/mastodon-db-backup
+ sudo chmod 755 /usr/local/bin/mastodon-db-backup
+ sudo systemctl enable --now mastodon-db-backup.timer
+ sudo systemctl enable --now mastodon-to-minio.timer
+
+thelounge-install:
+ curl -s https://api.github.com/repos/thelounge/thelounge-deb/releases/latest \
+ | grep "browser_download_url.*deb" \
+ | cut -d : -f 2,3 \
+ | tr -d \" \
+ | wget -qi -
+ sudo apt install -y ./thelounge*.deb
+
+tailscale-install:
+ curl -fsSL https://pkgs.tailscale.com/stable/debian/{{debian_codename}}.noarmor.gpg \
+ | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
+ curl -fsSL https://pkgs.tailscale.com/stable/debian/{{debian_codename}}.tailscale-keyring.list \
+ | sudo tee /etc/apt/sources.list.d/tailscale.list
+ sudo apt update
+ sudo apt install -y tailscale
+ sudo systemctl enable --now tailscaled
+ sudo tailscale up
+
+qbt-install:
+ curl -1sLf 'https://dl.cloudsmith.io/public/qbittorrent-cli/qbittorrent-cli/gpg.F8756541ADDA2B7D.key' \
+ | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/qbittorrent-cli.gpg
+ sudo wget https://repos.fedorovich.com/debian/{{ debian_codename }}/qbittorrent-cli.list \
+ -O /etc/apt/sources.list.d/qbittorrent-cli.list
+ sudo apt update
+ sudo apt install -y qbittorrent-cli
+ mkdir ~/bin
+ cp -v "${PWD}/bin/qbth" ~/bin/
+ cp -v "${PWD}/bin/qbtlist" ~/bin/
+
+qbittorrent-install:
+ sudo apt install -y qbittorrent-nox wireguard-tools lynx parallel wget curl httpie
+
+qbittorrent-enable:
+ sudo systemctl enable --now qbittorrent-nox@{{run_user}}.service
+
+scihub-setup:
+ mkdir ~/scihub-torrent-urls
+ lynx -dump -nonumbers -listonly=on https://libgen.rs/repository_torrent/ \
+ | grep "\.torrent" \
+ | tee scihub-torrent-urls/urls.txt
+ cd scihub-torrent-urls && split -l 60 urls.txt torrent-
+ rm -fv scihub-torrent-urls/urls.txt
diff --git a/pi0/justfile b/pi0/justfile
deleted file mode 100644
index d8bd4a3..0000000
--- a/pi0/justfile
+++ /dev/null
@@ -1,42 +0,0 @@
-## Justfile (https://github.com/casey/justfile)
-##
-## pi0 - Orange Pi 5+
-##
-## Services:
-## - gmcapsuled
-## - Mastodon
-## - Tailscale
-## - The Lounge IRC
-
-debian_codename := `grep "VERSION_CODENAME" /etc/os-release | awk -F= '{print $2}'`
-
-gmcapsuled:
- pipx install gmcapsule
- mkdir -p ~/.config/systemd/user
- cp -v "${PWD}/systemd/user/gmcapsuled.service" ~/.config/systemd/user/
- cp -v "${PWD}/gmcapsulerc" ~/.gmcapsulerc
-
-mastodon:
- sudo apt install -y rclone
- sudo cp -v "${PWD}/systemd/system/mastodon"* /etc/systemd/system/
- sudo cp -v "${PWD}/bin/mastodon-db-backup" /usr/local/bin
- sudo chown -R root:root /usr/local/bin/mastodon-db-backup
- sudo chmod 755 /usr/local/bin/mastodon-db-backup
- sudo systemctl enable --now mastodon-db-backup.timer
- sudo systemctl enable --now mastodon-to-minio.timer
-
-thelounge:
- curl -s https://api.github.com/repos/thelounge/thelounge-deb/releases/latest \
- | grep "browser_download_url.*deb" \
- | cut -d : -f 2,3 \
- | tr -d \" \
- | wget -qi -
- sudo apt install -y ./thelounge*.deb
-
-tailscale:
- curl -fsSL https://pkgs.tailscale.com/stable/debian/{{ debian_codename }}.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
- curl -fsSL https://pkgs.tailscale.com/stable/debian/{{ debian_codename }}.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
- sudo apt update
- sudo apt install -y tailscale
- sudo systemctl enable --now tailscaled
- sudo tailscale up
diff --git a/pi1/justfile b/pi1/justfile
deleted file mode 100644
index 98faa42..0000000
--- a/pi1/justfile
+++ /dev/null
@@ -1,31 +0,0 @@
-## Justfile (https://github.com/casey/justfile)
-##
-## pi1 - Orange Pi 5+
-##
-## Services:
-## - qBittorrent
-## - ProtonVPN via Wireguard
-
-debian_codename := `grep "VERSION_CODENAME" /etc/os-release | awk -F= '{print $2}'`
-run_user := env_var("USER")
-
-qbt:
- curl -1sLf 'https://dl.cloudsmith.io/public/qbittorrent-cli/qbittorrent-cli/gpg.F8756541ADDA2B7D.key' | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/qbittorrent-cli.gpg
- sudo wget https://repos.fedorovich.com/debian/{{ debian_codename }}/qbittorrent-cli.list -O /etc/apt/sources.list.d/qbittorrent-cli.list
- sudo apt update
- sudo apt install -y qbittorrent-cli
- mkdir ~/bin
- cp -v "${PWD}/bin/qbth" ~/bin/
- cp -v "${PWD}/bin/qbtlist" ~/bin/
-
-install:
- sudo apt install -y qbittorrent-nox wireguard-tools lynx parallel wget curl
-
-enable:
- sudo systemctl enable --now qbittorrent-nox@{{ run_user }}.service
-
-scihub:
- mkdir ~/scihub-torrent-urls
- lynx -dump -nonumbers -listonly=on https://libgen.rs/repository_torrent/ | grep "\.torrent" | tee scihub-torrent-urls/urls.txt
- cd scihub-torrent-urls && split -l 60 urls.txt torrent-
- rm -fv scihub-torrent-urls/urls.txt
diff --git a/pi2/justfile b/pi2/justfile
deleted file mode 100644
index fb78560..0000000
--- a/pi2/justfile
+++ /dev/null
@@ -1,30 +0,0 @@
-## Justfile (https://github.com/casey/just)
-##
-## Services:
-## - archivebox
-
-data_dir := "/nfs/archivebox"
-nfs_mnt := "10.0.0.6:/mnt/coffeeNAS/archivebox"
-run_user := env_var("USER")
-
-default: env install
-
-env:
- sudo mkdir -p {{ data_dir }}
- sudo chown -R {{ run_user }}:{{ run_user }} {{ data_dir }}
- echo "{{ nfs_mnt }} {{ data_dir }} nfs4 soft,intr,rsize=8192,wsize=8192" | sudo tee -a /etc/fstab
- sudo systemctl daemon-reload
- sudo mount -av
-
-install:
- sudo apt install -y pipx python3-dev python3-pip nodejs npm curl wget git ripgrep
- pipx install archivebox
- pipx install yt-dlp
- pipx install playwright
- playwright install --with-deps chromium
-
-init:
- cd {{ data_dir }} && archivebox init --setup
-
-setup:
- cd {{ data_dir }} && archivebox setup
diff --git a/systemd/network/eth0.network b/systemd/network/eth0.network
new file mode 100644
index 0000000..e871c69
--- /dev/null
+++ b/systemd/network/eth0.network
@@ -0,0 +1,5 @@
+[Match]
+Name=eth0
+
+[Network]
+DHCP=yes
diff --git a/pi0/systemd/system/mastodon-db-backup.service b/systemd/system/mastodon-db-backup.service
similarity index 100%
rename from pi0/systemd/system/mastodon-db-backup.service
rename to systemd/system/mastodon-db-backup.service
diff --git a/pi0/systemd/system/mastodon-db-backup.timer b/systemd/system/mastodon-db-backup.timer
similarity index 100%
rename from pi0/systemd/system/mastodon-db-backup.timer
rename to systemd/system/mastodon-db-backup.timer
diff --git a/pi0/systemd/system/mastodon-to-minio.service b/systemd/system/mastodon-to-minio.service
similarity index 100%
rename from pi0/systemd/system/mastodon-to-minio.service
rename to systemd/system/mastodon-to-minio.service
diff --git a/pi0/systemd/system/mastodon-to-minio.timer b/systemd/system/mastodon-to-minio.timer
similarity index 100%
rename from pi0/systemd/system/mastodon-to-minio.timer
rename to systemd/system/mastodon-to-minio.timer
diff --git a/pi0/systemd/user/gmcapsuled.service b/systemd/user/gmcapsuled.service
similarity index 100%
rename from pi0/systemd/user/gmcapsuled.service
rename to systemd/user/gmcapsuled.service
diff --git a/pi1/systemd/user/seed-armbian-tx.service b/systemd/user/seed-armbian-tx.service
similarity index 100%
rename from pi1/systemd/user/seed-armbian-tx.service
rename to systemd/user/seed-armbian-tx.service
diff --git a/pi1/systemd/user/seed-armbian-tx.timer b/systemd/user/seed-armbian-tx.timer
similarity index 100%
rename from pi1/systemd/user/seed-armbian-tx.timer
rename to systemd/user/seed-armbian-tx.timer
diff --git a/pi1/systemd/user/transmission-trackers.service b/systemd/user/transmission-trackers.service
similarity index 100%
rename from pi1/systemd/user/transmission-trackers.service
rename to systemd/user/transmission-trackers.service
diff --git a/pi1/systemd/user/transmission-trackers.timer b/systemd/user/transmission-trackers.timer
similarity index 100%
rename from pi1/systemd/user/transmission-trackers.timer
rename to systemd/user/transmission-trackers.timer
diff --git a/pi1/systemd/user/tx-stats-html.service b/systemd/user/tx-stats-html.service
similarity index 100%
rename from pi1/systemd/user/tx-stats-html.service
rename to systemd/user/tx-stats-html.service
diff --git a/pi1/systemd/user/tx-stats-html.timer b/systemd/user/tx-stats-html.timer
similarity index 100%
rename from pi1/systemd/user/tx-stats-html.timer
rename to systemd/user/tx-stats-html.timer