Move homelab to runit

This commit is contained in:
Neale Pickett 2023-12-28 10:07:43 -07:00
parent c2f2fcc38b
commit 5400171298
80 changed files with 523 additions and 1435 deletions

3
homelab/.gitignore vendored
View File

@ -1,3 +0,0 @@
password
samba-users.env
secrets

View File

@ -1,19 +1,3 @@
# Neale's Homelab
My homelab now uses runit-managed podman containers.
This is the stuff I run on my little Raspberry Pi.
I guess I fiddle around with it pretty frequently.
## Portal
In the [www](www) directory is a static HTML/JavaScript portal thing I wrote.
It doesn't need any server configuration,
you just edit the HTML to manage what apps it serves.
Other things like this exist,
but they all require ridiculous things like relational databases or weird config files.
I should probably package this up or something,
but then I'd have to put effort into publicizing it,
and run a ticketing system or something,
so meh.
runit essentially runs `*/run` in an endless loop.

View File

@ -1,9 +0,0 @@
* Single Sign-On
* [x] Replace simpleauth with somebody else's project
* [x] Set up Forgejo OIDC to Authelia (there's a guide on Authelia's site)
* [x] Persist "remember me" across reboots
* LDAP restrictions
* [x] People can only r/w their own storage
* [x] Public storage
* [x] Per-Group storage
* [x] Media-Sucker secure setup (bind to 0.0.0.0 opens to internet)

19
homelab/atlas/run Executable file
View File

@ -0,0 +1,19 @@
#! /bin/sh
me=$(basename $(pwd))
image=jamesits/ripe-atlas:latest
podman pull $image
podman rm $me
podman run \
--name $me \
--cpu-shares 128 \
--cap-drop ALL \
--cap-add CHOWN \
--cap-add SETUID \
--cap-add SETGID \
--cap-add DAC_OVERRIDE \
--cap-add NET_RAW \
--volume /srv/sys/atlas/etc:/var/atlas-probe/etc \
--volume /srv/sys/atlas/status:/var/atlas-probe/status \
$image

View File

@ -0,0 +1,3 @@
melville.woozle.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC6fMdw0m8wvh5+9IUcNgjxk0TgjoTT1anESnsYWIcnmS8l7PzkB/WfCEZEU0QzKvKXSp37jd30iR5U9jM7zTjYrjCJZvK0dxShC9iIgR5akAThXvlH0KkHVAvhmQda6nvMWQugp359Usp4zH90/J7G//+3HEQ9zfXW+p29bwBOdyDHfjDSIz95ysy8ivwMFKuPgAsNK4FDfBsGVHCM5xu5bn0dSaHeqGn7bneY00zwQqQot6rOw1Pao2tEY04Vu4KC1VKVWKU38dNBEFTOQBxYhiVMsxY3CIwDbEQLA5gjRnYog2KvsDP9XK4W2k1Yc9PvwoinqzcgmDS7isQ8HAoZiY06CChg3hHYXRre+TcO/UrjhzrWbxdCo7XFKBiC74ZU/+t2IkBmmHEnaTpmaLazxZD75wUH9rrWwgPVFEWNp41nj0VfQfR032MwJ2iNbvkCW/2kUWe++r56TlYQjxL8FVICVBbt6pZprMbEkQm3/iPR6ibfNNa620Kz3QRUsxM=
melville.woozle.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBE1D4QQxjnNgmI7wteSAnAqArKQ6UTnTKmTitnU40ISizAK1j8OqXxEv0hbssNrTVyqlmLUoIeRuHd5bHGC8dEE=
melville.woozle.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEQKIumG2Wl3papG4lcIB9+ZEe76uMbfpP+XSlUBjR0E

View File

@ -0,0 +1,86 @@
# Example configuration file, it's safe to copy this as the default config file without any modification.
# You don't have to copy this file to your instance,
# just run `./act_runner generate-config > config.yaml` to generate a config file.
log:
# The level of logging, can be trace, debug, info, warn, error, fatal
level: info
runner:
# Where to store the registration result.
file: .runner
# Execute how many tasks concurrently at the same time.
capacity: 1
# Extra environment variables to run jobs.
envs:
A_TEST_ENV_NAME_1: a_test_env_value_1
A_TEST_ENV_NAME_2: a_test_env_value_2
# Extra environment variables to run jobs from a file.
# It will be ignored if it's empty or the file doesn't exist.
env_file: .env
# The timeout for a job to be finished.
# Please note that the Gitea instance also has a timeout (3h by default) for the job.
# So the job could be stopped by the Gitea instance if it's timeout is shorter than this.
timeout: 30m
# Whether skip verifying the TLS certificate of the Gitea instance.
insecure: false
# The timeout for fetching the job from the Gitea instance.
fetch_timeout: 5s
# The interval for fetching the job from the Gitea instance.
fetch_interval: 28s
# The labels of a runner are used to determine which jobs the runner can run, and how to run them.
labels: ["aarch64", "big-builder", "hugo", "python3", "go"]
cache:
# Enable cache server to use actions/cache.
enabled: true
# The directory to store the cache data.
# If it's empty, the cache data will be stored in $HOME/.cache/actcache.
dir: ""
# The host of the cache server.
# It's not for the address to listen, but the address to connect from job containers.
# So 0.0.0.0 is a bad choice, leave it empty to detect automatically.
host: ""
# The port of the cache server.
# 0 means to use a random available port.
port: 0
# The external cache server URL. Valid only when enable is true.
# If it's specified, act_runner will use this URL as the ACTIONS_CACHE_URL rather than start a server by itself.
# The URL should generally end with "/".
external_server: ""
container:
# Specifies the network to which the container will connect.
# Could be host, bridge or the name of a custom network.
# If it's empty, act_runner will create a network automatically.
network: ""
# Whether to use privileged mode or not when launching task containers (privileged mode is required for Docker-in-Docker).
privileged: false
# And other options to be used when the container is started (eg, --add-host=my.gitea.url:host-gateway).
options:
# The parent directory of a job's working directory.
# If it's empty, /workspace will be used.
workdir_parent:
# Volumes (including bind mounts) can be mounted to containers. Glob syntax is supported, see https://github.com/gobwas/glob
# You can specify multiple volumes. If the sequence is empty, no volumes can be mounted.
# For example, if you only allow containers to mount the `data` volume and all the json files in `/src`, you should change the config to:
# valid_volumes:
# - data
# - /src/*.json
# If you want to allow any volume, please use the following configuration:
# valid_volumes:
# - '**'
valid_volumes: []
# overrides the docker client host with the specified one.
# If it's empty, act_runner will find an available docker host automatically.
# If it's "-", act_runner will find an available docker host automatically, but the docker host won't be mounted to the job containers and service containers.
# If it's not empty or "-", the specified docker host will be used. An error will be returned if it doesn't work.
docker_host: ""
# Pull docker image(s) even if already present
force_pull: false
host:
# The parent directory of a job's working directory.
# If it's empty, $HOME/.cache/act/ will be used.
workdir_parent:

3
homelab/builder-betty/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

9
homelab/builder-betty/run Executable file
View File

@ -0,0 +1,9 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--volume ./app/config.yaml:/app/config.yaml:ro \
--volume ./app/.ssh:/app/.ssh:ro \
--volume /srv/secrets/builder-betty/.runner:/app/.runner:ro \
git.woozle.org/neale/big-builder:1.0 -c config.yaml daemon

View File

@ -1,5 +1,5 @@
{
email neale@woozle.org
email neale@woozle.org
#debug
}
@ -21,10 +21,6 @@ drive.woozle.org {
#reverse_proxy filebrowser:80
}
media.woozle.org {
reverse_proxy jellyfin:8096
}
# XXX: have this use caddy auth
ancestry.woozle.org {
reverse_proxy geneweb:2317
@ -77,7 +73,7 @@ deergrove.woozle.org {
}
handle_path /sucker/* {
reverse_proxy host.lan:5801
reverse_proxy sucker:8080
}
handle_path /netdata/* {

3
homelab/caddy/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

13
homelab/caddy/run Executable file
View File

@ -0,0 +1,13 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network homelab \
--publish 80:80 \
--publish 443:443 \
--volume /srv:/srv:ro \
--volume /srv/sys/caddy:/data/caddy \
--volume ./Caddyfile:/etc/caddy/Caddyfile:ro \
--add-host host.lan:192.168.86.2 \
caddy:2-alpine

View File

@ -4,5 +4,5 @@
192.168.86.2 sweetums.woozle.org deergrove.woozle.org drive.woozle.org git.woozle.org ancestry.woozle.org media.woozle.org photos.woozle.org auth.woozle.org xfer.woozle.org
fallthrough
}
forward . 8.8.8.8
forward . 1.1.1.1 1.0.0.1 8.8.8.8
}

3
homelab/coredns/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

8
homelab/coredns/run Executable file
View File

@ -0,0 +1,8 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network host \
--mount type=bind,src=$(pwd)/Corefile,dst=/home/nonroot/Corefile,readonly=true \
coredns/coredns

View File

@ -1,4 +0,0 @@
address: "0.0.0.0"
port: "8000"
dir: "/data"
prefix: "/"

3
homelab/ddns/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

9
homelab/ddns/run Executable file
View File

@ -0,0 +1,9 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network homelab \
--dns 1.1.1.1 \
--volume /srv/sys/ddns-updater:/updater/data \
qmcgaw/ddns-updater

View File

@ -1,12 +0,0 @@
#! /bin/sh
stack=$(basename $(pwd))
extra="--resolve-image changed"
if [ "$1" = "--slow" ]; then
extra=
shift
fi
docker --context deergrove stack deploy -c docker-compose.yaml --prune $extra "$@" $stack
#docker --context deergrove compose up --detach

View File

@ -1,406 +0,0 @@
version: "3.8"
services:
coredns:
image: coredns/coredns
networks:
- hostnet
command:
- -conf
- /Corefile
configs:
- source: Corefile
target: /Corefile
caddy:
image: caddy:2-alpine
ports:
- target: 443
published: 443
mode: host
- target: 80
published: 80
mode: host
volumes:
- type: bind
source: /srv
target: /srv
read_only: true
- type: bind
source: /srv/sys/caddy
target: /data/caddy
configs:
- source: Caddyfile
target: /etc/caddy/Caddyfile
extra_hosts:
- host.docker.internal:host-gateway
- host.lan:192.168.86.2
simpleauth:
image: git.woozle.org/neale/simpleauth
secrets:
- passwd
- simpleauth.key
portal:
image: git.woozle.org/neale/portal
configs:
- source: portal.json
target: /web/portal.json
- source: deergrove.png
target: /web/portal.png
jellyfin:
image: jellyfin/jellyfin
deploy:
replicas: 0
environment:
TZ: US/Mountain
volumes:
- type: bind
source: /srv/sys/jellyfin/config
target: /config
- type: bind
source: /srv/sys/jellyfin/cache
target: /cache
- type: bind
source: /srv/media/
target: /srv/media/
read_only: true
plex:
image: lscr.io/linuxserver/plex:latest
networks:
- hostnet
environment:
TZ: US/Mountain
VERSION: public
volumes:
- type: bind
source: /srv/sys/plex
target: /config
- type: bind
source: /srv/media/
target: /srv/media/
read_only: true
pigallery2:
image: bpatrik/pigallery2:latest
volumes:
- type: bind
source: /srv/sys/pigallery2/config
target: /app/data/config
- type: bind
source: /srv/sys/pigallery2/db
target: /app/data/db
- type: bind
source: /srv/sys/pigallery2/cache
target: /app/data/cache
- type: bind
source: /srv/storage/fam/Photos
target: /photos/fam
read_only: true
- type: bind
source: /srv/storage/ginnie/Photos
target: /photos/ginnie
read_only: true
transmission:
image: lscr.io/linuxserver/transmission:latest
volumes:
- type: bind
source: /srv/sys/transmission
target: /config
- type: bind
source: /srv/incoming
target: /srv/incoming
environment:
PEERPORT: "51413"
ports:
- 51413:51413
- 51413:51413/udp
sonarr:
image: lscr.io/linuxserver/sonarr
extra_hosts:
- host.docker.internal:host-gateway
volumes:
- type: bind
source: /srv/sys/sonarr
target: /config
- type: bind
source: /srv/media/tv
target: /srv/media/tv
- type: bind
source: /srv/incoming
target: /srv/incoming
radarr:
image: lscr.io/linuxserver/radarr
extra_hosts:
- host.docker.internal:host-gateway
volumes:
- type: bind
source: /srv/sys/radarr
target: /config
- type: bind
source: /srv/media/movies
target: /srv/media/movies
- type: bind
source: /srv/incoming
target: /srv/incoming
lidarr:
image: lscr.io/linuxserver/lidarr
extra_hosts:
- host.docker.internal:host-gateway
volumes:
- type: bind
source: /srv/sys/lidarr
target: /config
- type: bind
source: /srv/media/music
target: /srv/media/music
- type: bind
source: /srv/incoming
target: /srv/incoming
readarr:
image: lscr.io/linuxserver/readarr:develop
extra_hosts:
- host.docker.internal:host-gateway
volumes:
- type: bind
source: /srv/sys/readarr
target: /config
- type: bind
source: /srv/media/books
target: /srv/media/books
- type: bind
source: /srv/media/audiobooks
target: /srv/media/audiobooks
- type: bind
source: /srv/incoming
target: /srv/incoming
prowlarr:
image: lscr.io/linuxserver/prowlarr:latest
extra_hosts:
- host.docker.internal:host-gateway
volumes:
- type: bind
source: /srv/sys/prowlarr
target: /config
nzbget:
image: lscr.io/linuxserver/nzbget
volumes:
- type: bind
source: /srv/sys/nzbget
target: /config
- type: bind
source: /srv/incoming
target: /srv/incoming
gitea:
image: codeberg.org/forgejo/forgejo:1.20.5-0-rootless
configs:
- source: gitea-robots.txt
target: /var/lib/gitea/custom/robots.txt
- source: timezone
target: /etc/timezone
- source: localtime
target: /etc/localtime
volumes:
- type: bind
source: /srv/sys/gitea/app.ini
target: /etc/gitea/app.ini
- type: bind
source: /srv/sys/gitea
target: /data
atlas:
image: ctassisf/ripe-atlas-alpine:arm64v8
volumes:
- type: bind
source: /srv/sys/atlas/etc
target: /var/atlas-probe/etc
- type: bind
source: /srv/sys/atlas/status
target: /var/atlas-probe/status
netdata:
image: netdata/netdata
hostname: "{{.Node.Hostname}}"
deploy:
replicas: 0
environment:
NETDATA_DISABLE_CLOUD: "1"
cap_add:
- SYS_PTRACE
volumes:
- type: bind
source: /
target: /host
read_only: true
- type: bind
source: /srv/sys/netdata/lib
target: /var/lib/netdata
- type: bind
source: /srv/sys/netdata/cache
target: /var/cache/netdata
configs:
- source: netdata.conf
target: /etc/netdata/netdata.conf
geneweb:
image: ravermeister/geneweb
volumes:
- type: bind
source: /srv/sys/geneweb/
target: /usr/local/share/geneweb/share/data
samba:
image: dperson/samba
volumes:
- type: bind
source: /srv
target: /srv
environment:
NMBD: enable
RECYCLE: disable
USERID: 911
GROUPID: 911
# name;path;browse;readonly;guest
SHARE1: drive;/srv;yes;no;no
SHARE2: retropie;/srv/media/games/retropie;yes;yes;yes
env_file:
- secrets/samba-users.env
ports:
- published: 139
target: 139
- published: 445
target: 445
webfs:
image: sigoden/dufs
volumes:
- type: bind
source: /srv/storage
target: /srv/storage
- type: bind
source: /srv/incoming
target: /srv/incoming
- type: bind
source: /srv/media
target: /srv/media
command:
- -A
- /srv
user: "911:911"
picoshare:
image: git.woozle.org/neale/picoshare
volumes:
- type: bind
source: /srv/sys/picoshare
target: /data
environment:
PS_SHARED_SECRET_FILE: /run/secrets/picoshare
secrets:
- picoshare
ddns:
image: qmcgaw/ddns-updater
dns:
- 1.1.1.1
volumes:
- type: bind
source: /srv/sys/ddns-updater
target: /updater/data
filebrowser:
image: filebrowser/filebrowser
volumes:
- type: bind
source: /srv/sys/filebrowser/database
target: /database
- type: bind
source: /srv/storage
target: /srv/storage
- type: bind
source: /srv/media
target: /srv/media
- type: bind
source: /srv/incoming
target: /srv/incoming
user: "911:911"
configs:
- source: filebrowser.json
target: /.filebrowser.json
configs:
dave.yaml:
file: dave.yaml
name: dave.yaml-v3
Corefile:
file: Corefile
name: Corefile-v11
Caddyfile:
file: Caddyfile
name: Caddyfile-v153
portal.json:
file: portal.json
name: portal.json-v7
deergrove.png:
file: www/deergrove.png
name: deergrove.png-v1
netdata.conf:
file: netdata.conf
name: netdata.conf-v1
gitea-robots.txt:
file: gitea-robots.txt
name: gitea-robots.txt-v1
filebrowser.json:
file: filebrowser.json
name: filebrowser.json-v2
localtime:
file: localtime
name: localtime-v1
timezone:
file: timezone
name: timezone-v1
secrets:
passwd:
file: secrets/passwd
name: passwd-v2
simpleauth.key:
file: secrets/simpleauth.key
name: simpleauth.key-v1
tunnel:
file: secrets/tunnel
name: tunnel-v1
known_hosts:
file: secrets/known_hosts
name: known_hosts-v1
jwt.secret:
file: secrets/jwt.secret
name: jwt.secret-v1
storage.secret:
file: secrets/storage.secret
name: storage.secret-v1
session.secret:
file: secrets/session.secret
name: session.secret-v1
users.yaml:
file: secrets/users.yaml
name: users.yaml-v9
authelia.oidc.yaml:
file: secrets/authelia.oidc.yaml
name: authelia.oidc.yaml-v2
picoshare:
file: secrets/picoshare
name: picoshare-v1
networks:
hostnet:
external: true
name: host

View File

@ -1,8 +0,0 @@
{
"port": 80,
"baseURL": "/",
"address": "",
"log": "stdout",
"database": "/database/filebrowser.db",
"root": "/srv"
}

3
homelab/geneweb/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

8
homelab/geneweb/run Executable file
View File

@ -0,0 +1,8 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network homelab \
--volume /srv/sys/geneweb:/usr/local/share/geneweb/share/data \
ravermeister/geneweb

3
homelab/gitea/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

12
homelab/gitea/run Executable file
View File

@ -0,0 +1,12 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network homelab \
--volume ./gitea-robots.txt:/var/lib/gitea/custom/robots.txt:ro \
--volume ./timezone:/etc/timezone:ro \
--volume /etc/localtime:/etc/localtime:ro \
--volume /srv/sys/gitea/app.ini:/etc/gitea/app.ini \
--volume /srv/sys/gitea:/data \
codeberg.org/forgejo/forgejo:1.20.5-0-rootless

3
homelab/lidarr/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

10
homelab/lidarr/run Executable file
View File

@ -0,0 +1,10 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network homelab \
--volume /srv/sys/lidarr:/config \
--volume /srv/media/music:/srv/media/music \
--volume /srv/incoming:/srv/incoming \
lscr.io/linuxserver/lidarr

Binary file not shown.

View File

@ -1,5 +0,0 @@
[global]
update every = 10
[plugin:proc:/proc/net/dev]
disable by default interfaces matching = lo veth* docker*

3
homelab/nzbget/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

9
homelab/nzbget/run Executable file
View File

@ -0,0 +1,9 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network homelab \
--volume /srv/sys/nzbget:/config \
--volume /srv/incoming:/srv/incoming \
lscr.io/linuxserver/nzbget

3
homelab/oscar/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

20
homelab/oscar/run Executable file
View File

@ -0,0 +1,20 @@
#! /bin/sh
me=$(basename $(pwd))
image=git.woozle.org/neale/toolbox
podman pull $image
podman rm $me
podman run \
--name $me \
--hostname oscar \
--security-opt label=disable \
--privileged \
--network host \
--pid host \
--volume /srv/sys/oscar:/mnt/toolbox \
--volume /srv:/srv \
--volume /media:/media \
--volume /home:/home \
--volume /dev:/dev \
--volume /:/host \
$image

3
homelab/picoshare/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

10
homelab/picoshare/run Executable file
View File

@ -0,0 +1,10 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network homelab \
--env PS_SHARED_SECRET_FILE=/run/secrets/picoshare \
--volume /srv/sys/picoshare:/data \
--volume /srv/secrets/picoshare:/run/secrets/picoshare \
git.woozle.org/neale/picoshare

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

3
homelab/pigallery2/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

12
homelab/pigallery2/run Executable file
View File

@ -0,0 +1,12 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network homelab \
--volume /srv/sys/pigallery2/config:/app/data/config \
--volume /srv/sys/pigallery2/db:/app/data/db \
--volume /srv/sys/pigallery2/cache:/app/data/cache \
--volume /srv/storage/fam/Photos:/photos/fam:ro \
--volume /srv/storage/ginnie/Photos:/photos/ginnie:ro \
bpatrik/pigallery2:latest

3
homelab/plex/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

11
homelab/plex/run Executable file
View File

@ -0,0 +1,11 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network host \
--tz US/Mountain \
--env VERSION=public \
--mount type=bind,src=/srv/sys/plex,dst=/config \
--mount type=bind,src=/srv/media,dst=/srv/media,readonly=true \
lscr.io/linuxserver/plex:latest

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

3
homelab/portal/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

View File

@ -0,0 +1,76 @@
[
{
"title": "Storage",
"href": "https://drive.woozle.org/",
"icon": "https://drive.woozle.org/storage/public/icons/cloud-folder.png",
"target": "_blank"
},
{
"title": "Photos",
"href": "https://photos.woozle.org/",
"icon": "https://photos.woozle.org/icon.png",
"target": "_blank"
},
{
"title": "Git",
"href": "https://git.woozle.org/",
"icon": "https://git.woozle.org/assets/img/logo.svg",
"target": "_blank"
},
{
"title": "Genealogy",
"href": "https://ancestry.woozle.org/",
"icon": "https://ancestry.woozle.org/images/arbre_start.png",
"target": "_blank"
},
{
"title": "Movies",
"href": "https://deergrove.woozle.org/radarr/",
"icon": "/radarr/Content/Images/logo.svg"
},
{
"title": "Episodes",
"href": "https://deergrove.woozle.org/sonarr/",
"icon": "/sonarr/Content/Images/logo.svg"
},
{
"title": "Music",
"href": "https://deergrove.woozle.org/lidarr/",
"icon": "/lidarr/Content/Images/logo.svg"
},
{
"title": "Books",
"href": "https://deergrove.woozle.org/readarr/",
"icon": "/readarr/Content/Images/logo.svg"
},
{
"title": "Media Sucker",
"href": "https://deergrove.woozle.org/sucker/",
"icon": "/sucker/cd-dvd.svg"
},
{
"title": "Searcher",
"href": "https://deergrove.woozle.org/prowlarr/",
"icon": "/prowlarr/Content/Images/logo.png"
},
{
"title": "Usenet",
"href": "https://deergrove.woozle.org/nzbget/",
"icon": "/nzbget/img/favicon-256x256.png"
},
{
"title": "BitTorrent",
"href": "https://deergrove.woozle.org/transmission/web/",
"icon": "/transmission/web/images/webclip-icon.png"
},
{
"title": "3D Printer",
"href": "https://deergrove.woozle.org/octoprint/",
"icon": "/octoprint/static/img/logo.png"
},
{
"title": "Host Stats",
"href": "/stat.html",
"app": "stat"
}
]

9
homelab/portal/run Executable file
View File

@ -0,0 +1,9 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network homelab \
--volume ./portal.json:/web/portal.json:ro \
--volume ./deergrove.png:/web/portal.png:ro \
git.woozle.org/neale/portal

3
homelab/prowlarr/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

8
homelab/prowlarr/run Executable file
View File

@ -0,0 +1,8 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network homelab \
--volume /srv/sys/prowlarr:/config \
lscr.io/linuxserver/prowlarr

3
homelab/radarr/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

10
homelab/radarr/run Executable file
View File

@ -0,0 +1,10 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network homelab \
--volume /srv/sys/radarr:/config \
--volume /srv/media/movies:/srv/media/movies \
--volume /srv/incoming:/srv/incoming \
lscr.io/linuxserver/radarr

3
homelab/readarr/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

11
homelab/readarr/run Executable file
View File

@ -0,0 +1,11 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network homelab \
--volume /srv/sys/readarr:/config \
--volume /srv/media/books:/srv/media/books \
--volume /srv/media/audiobooks:/srv/media/audiobooks \
--volume /srv/incoming:/srv/incoming \
lscr.io/linuxserver/readarr:develop

3
homelab/samba/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

17
homelab/samba/run Executable file
View File

@ -0,0 +1,17 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network homelab \
--publish 139:139 \
--publish 445:445 \
--env NMBD=enable \
--env RECYCLE=disable \
--env USERID=911 \
--env GROUPID=911 \
--env SHARE1='drive;/srv;yes;no;no' \
--env SHARE2='media;/srv/media;yes;yes;yes' \
--env-file /srv/secrets/samba-users.env \
--volume /srv:/srv \
dperson/samba

3
homelab/simpleauth/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

9
homelab/simpleauth/run Executable file
View File

@ -0,0 +1,9 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network homelab \
--volume /srv/secrets/passwd:/run/secrets/passwd:ro \
--volume /srv/secrets/simpleauth.key:/run/secrets/simpleauth.key:ro \
git.woozle.org/neale/simpleauth

3
homelab/sonarr/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

10
homelab/sonarr/run Executable file
View File

@ -0,0 +1,10 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network homelab \
--volume /srv/sys/sonarr:/config \
--volume /srv/media/tv:/srv/media/tv \
--volume /srv/incoming:/srv/incoming \
lscr.io/linuxserver/sonarr

3
homelab/sucker/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

15
homelab/sucker/run Executable file
View File

@ -0,0 +1,15 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name=$me \
--device-cgroup-rule 'b 11:* rmw' \
--network homelab \
-v /dev:/hdev \
-v /srv/ext/incoming/sucker:/incoming/sucker \
--cpu-shares 256 \
--user 911:19 \
git.woozle.org/neale/media-sucker \
-incoming /incoming/sucker \
-drive /hdev/sr0 /hdev/sr1 /hdev/sr2

11
homelab/sync.sh Executable file
View File

@ -0,0 +1,11 @@
#! /bin/sh
service=/host/etc/service
if ! [ -d $service ]; then
echo "=== $service is not a directory" 1>&2
exit 1
fi
rsync -vaxp --delete \
--exclude=supervise/ \
$service/* .

14
homelab/sys-backup/run Executable file
View File

@ -0,0 +1,14 @@
#! /bin/sh
set -e
. /etc/lbu/lbu.conf
hostname=$(hostname)
mkdir -p /srv/backups/$hostname/
install -p -m 0600 /media/$LBU_MEDIA/$hostname.*.tar.gz /srv/backups/$hostname/
for path in /srv/backups/$hostname/$hostname.*.tar.gz; do
filename=$(basename $path)
[ -f /media/$LBU_MEDIA/$filename ] || rm $path
done
sleep 4h

3
homelab/transmission/finish Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
me=$(basename $(pwd))
podman stop $me

12
homelab/transmission/run Executable file
View File

@ -0,0 +1,12 @@
#! /bin/sh
me=$(basename $(pwd))
podman rm $me
podman run \
--name $me \
--network homelab \
--publish 51413:51413 \
--publish 51413:51413/udp \
--env PEERPORT=51413 \
--volume /srv/sys/transmission:/config \
--volume /srv/incoming:/srv/incoming \
lscr.io/linuxserver/transmission:latest

View File

@ -1,58 +0,0 @@
version: "3.8"
services:
syncthing:
image: syncthing/syncthing
environment:
PUID: 911
CGID: 911
volumes:
- type: bind
source: /srv/ext/sys/syncthing
target: /var/syncthing
- type: bind
source: /srv/ext
target: /srv/ext
ports:
- published: 22000
target: 22000
protocol: tcp
- published: 22000
target: 22000
protocol: udp
- published: 21027
target: 21027
protocol: udp
deploy:
labels:
traefik.enable: "true"
traefik.http.routers.syncthing.rule: "PathPrefix(`/syncthing`)"
traefik.http.routers.syncthing.middlewares: syncthing-striparoo
traefik.http.middlewares.syncthing-striparoo.stripprefix.prefixes: "/syncthing"
traefik.http.services.syncthing.loadbalancer.server.port: "8384"
## Drop this in to get a netdata container.
## It uses a lot of RAM and causes my machine to swap.
## Granted, it's a lot more lightweight than nextcloud.
## But I can live without netdata.
netdata:
image: netdata/netdata
hostname: $HOSTNAME
volumes:
- type: bind
source: /
target: /host
read_only: true
configs:
- source: netdata.conf
target: /etc/netdata/netdata.conf
deploy:
labels:
traefik.http.routers.netdata.rule: "PathPrefix(`/netdata`)"
traefik.http.middlewares.netdata-striparoo.stripprefix.prefixes: "/netdata"
traefik.http.routers.netdata.middlewares: netdata-striparoo
traefik.http.services.netdata.loadbalancer.server.port: "19999"
configs:
netdata.conf:
file: netdata.conf
name: netdata.conf-v4

View File

@ -1,10 +0,0 @@
[server]
domain = {{.Node.Hostname}}
root_url = %(protocol)s://%(domain)s:%(http_port)s/grafana/
serve_from_sub_path = true
[auth.anonymous]
enabled = false
org_name = Main Org.
org_role = Viewer

View File

@ -1,363 +0,0 @@
version: "3.8"
services:
coredns:
image: coredns/coredns
networks:
- hostnet
configs:
- source: Corefile
target: /Corefile
caddy:
image: caddy:2-alpine
ports:
- target: 443
published: 443
mode: host
- target: 80
published: 80
mode: host
volumes:
- type: bind
source: /srv
target: /srv
read_only: true
- type: bind
source: /srv/sys/caddy
target: /data/caddy
configs:
- source: Caddyfile
target: /etc/caddy/Caddyfile
- source: index.html
target: /www/index.html
- source: index.mjs
target: /www/index.mjs
- source: deergrove.png
target: /www/deergrove.png
- source: index.css
target: /www/index.css
- source: browser.html
target: /browser.html
extra_hosts:
- host.docker.internal:host-gateway
authelia:
image: authelia/authelia
environment:
AUTHELIA_JWT_SECRET_FILE: /run/secrets/jwt.secret
AUTHELIA_SESSION_SECRET_FILE: /run/secrets/session.secret
AUTHELIA_STORAGE_ENCRYPTION_FILE: /run/secrets/storage.secret
secrets:
- jwt.secret
- session.secret
- storage.secret
- users.yaml
configs:
- source: authelia.yaml
target: /config/configuration.yml
volumes:
- type: bind
source: /srv/sys/authelia
target: /srv/sys/authelia
jellyfin:
image: jellyfin/jellyfin
environment:
TZ: US/Mountain
volumes:
- type: bind
source: /srv/sys/jellyfin/config
target: /config
- type: bind
source: /srv/sys/jellyfin/cache
target: /cache
- type: bind
source: /srv/media
target: /srv/media
read_only: true
plex:
image: ghcr.io/linuxserver/plex:1.29.2
networks:
- hostnet
environment:
TZ: US/Mountain
VERSION: public
volumes:
- type: bind
source: /srv/sys/plex
target: /config
- type: bind
source: /srv
target: /srv
read_only: true
transmission:
image: lscr.io/linuxserver/transmission
volumes:
- type: bind
source: /srv/sys/transmission
target: /config
- type: bind
source: /srv/incoming
target: /srv/incoming
networks:
- hostnet
sonarr:
image: lscr.io/linuxserver/sonarr
extra_hosts:
- host.docker.internal:host-gateway
volumes:
- type: bind
source: /srv/sys/sonarr
target: /config
- type: bind
source: /srv/media/tv
target: /srv/media/tv
- type: bind
source: /srv/incoming
target: /srv/incoming
radarr:
image: lscr.io/linuxserver/radarr
extra_hosts:
- host.docker.internal:host-gateway
volumes:
- type: bind
source: /srv/sys/radarr
target: /config
- type: bind
source: /srv/media/movies
target: /srv/media/movies
- type: bind
source: /srv/incoming
target: /srv/incoming
lidarr:
image: lscr.io/linuxserver/lidarr
extra_hosts:
- host.docker.internal:host-gateway
volumes:
- type: bind
source: /srv/sys/lidarr
target: /config
- type: bind
source: /srv/media/music
target: /srv/media/music
- type: bind
source: /srv/incoming
target: /srv/incoming
readarr:
image: lscr.io/linuxserver/readarr:develop
extra_hosts:
- host.docker.internal:host-gateway
volumes:
- type: bind
source: /srv/sys/readarr
target: /config
- type: bind
source: /srv/media/books
target: /srv/media/books
- type: bind
source: /srv/media/audiobooks
target: /srv/media/audiobooks
- type: bind
source: /srv/incoming
target: /srv/incoming
prowlarr:
image: lscr.io/linuxserver/prowlarr:latest
extra_hosts:
- host.docker.internal:host-gateway
volumes:
- type: bind
source: /srv/sys/prowlarr
target: /config
nzbget:
image: lscr.io/linuxserver/nzbget
volumes:
- type: bind
source: /srv/sys/nzbget
target: /config
- type: bind
source: /srv/incoming
target: /srv/incoming
forgejo:
image: codeberg.org/forgejo/forgejo:1.18-rootless
secrets:
- source: forgejo.ini
target: /etc/gitea/app.ini
uid: "1000"
gid: "1000"
mode: 0400
volumes:
- type: bind
source: /srv/sys/forgejo
target: /data
- type: bind
source: /etc/timezone
target: /etc/timezone
read_only: true
- type: bind
source: /etc/localtime
target: /etc/localtime
read_only: true
atlas:
image: ctassisf/ripe-atlas-alpine:arm64v8
volumes:
- type: bind
source: /srv/sys/atlas/etc
target: /var/atlas-probe/etc
- type: bind
source: /srv/sys/atlas/status
target: /var/atlas-probe/status
geneweb:
image: ravermeister/geneweb
volumes:
- type: bind
source: /srv/sys/geneweb/etc
target: /usr/local/sha