Compare commits
19 Commits
b54e137b2e
...
e32e4f586f
Author | SHA1 | Date |
---|---|---|
Neale Pickett | e32e4f586f | |
Neale Pickett | befbffb12e | |
Neale Pickett | bb7db9b716 | |
Neale Pickett | 3911727e0c | |
Neale Pickett | de62a99037 | |
Neale Pickett | a9e4c9fea1 | |
Neale Pickett | e10bde0646 | |
Neale Pickett | a44f5cc39b | |
Neale Pickett | 960ab95b98 | |
neale | b0afab5ef6 | |
Neale Pickett | 30b7290e31 | |
Neale Pickett | 1bf3249d49 | |
Neale Pickett | 067b0e3cef | |
Neale Pickett | 335849665d | |
Neale Pickett | c58bcb36f3 | |
Neale Pickett | 27886e6110 | |
Neale Pickett | be6fcf0c54 | |
neale | af2a86c28e | |
Neale Pickett | 47e40fbe41 |
|
@ -1,11 +1,13 @@
|
|||
{
|
||||
email neale@woozle.org
|
||||
email neale@woozle.org
|
||||
#debug
|
||||
}
|
||||
|
||||
(restricted-access) {
|
||||
forward_auth simpleauth:8080 {
|
||||
uri /
|
||||
copy_headers X-Simpleauth-Token
|
||||
copy_headers X-Simpleauth-Username
|
||||
header_down X-Simpleauth-Domain "woozle.org"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,19 +17,11 @@ git.woozle.org {
|
|||
|
||||
drive.woozle.org {
|
||||
import restricted-access
|
||||
reverse_proxy webfs:5000
|
||||
}
|
||||
|
||||
# XXX: browsing says method not allowed
|
||||
@nondav {
|
||||
method HEAD GET
|
||||
}
|
||||
# route overrides built-in ordering
|
||||
route {
|
||||
file_server @nondav {
|
||||
root /srv/
|
||||
browse /browser.html
|
||||
}
|
||||
reverse_proxy webdav:8000
|
||||
}
|
||||
media.woozle.org {
|
||||
reverse_proxy jellyfin:8096
|
||||
}
|
||||
|
||||
# XXX: have this use caddy auth
|
||||
|
@ -35,89 +29,69 @@ ancestry.woozle.org {
|
|||
reverse_proxy geneweb:2317
|
||||
}
|
||||
|
||||
photos.woozle.org {
|
||||
import restricted-access
|
||||
reverse_proxy pigallery2:80
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
## handle sends original path
|
||||
## handle_path truncates path
|
||||
##
|
||||
|
||||
(deergrove) {
|
||||
deergrove.woozle.org {
|
||||
import restricted-access
|
||||
|
||||
handle_path /ddns/* {
|
||||
import restricted-access
|
||||
reverse_proxy ddns:8000
|
||||
}
|
||||
|
||||
handle /transmission/* {
|
||||
import restricted-access
|
||||
reverse_proxy host.docker.internal:9091
|
||||
reverse_proxy transmission:9091
|
||||
}
|
||||
|
||||
handle /nzbget/* {
|
||||
import restricted-access
|
||||
reverse_proxy nzbget:6789
|
||||
}
|
||||
|
||||
handle /sonarr/* {
|
||||
import restricted-access
|
||||
reverse_proxy sonarr:8989
|
||||
}
|
||||
handle /radarr/* {
|
||||
import restricted-access
|
||||
reverse_proxy radarr:7878
|
||||
}
|
||||
handle /readarr/* {
|
||||
import restricted-access
|
||||
reverse_proxy readarr:8787
|
||||
}
|
||||
handle /lidarr/* {
|
||||
import restricted-access
|
||||
reverse_proxy lidarr:8686
|
||||
}
|
||||
handle /prowlarr/* {
|
||||
import restricted-access
|
||||
reverse_proxy prowlarr:9696
|
||||
}
|
||||
handle /unmanic/* {
|
||||
reverse_proxy unmanic:8888
|
||||
}
|
||||
|
||||
handle_path /sucker/* {
|
||||
import restricted-access
|
||||
reverse_proxy host.docker.internal:5880
|
||||
reverse_proxy host.lan:5801
|
||||
}
|
||||
|
||||
handle_path /netdata/* {
|
||||
reverse_proxy netdata:19999
|
||||
}
|
||||
|
||||
# Octoprint serves up broken webcam URLs
|
||||
uri replace /webcam/ /octoprint/webcam/
|
||||
handle_path /octoprint/* {
|
||||
import restricted-access
|
||||
reverse_proxy {
|
||||
to 192.168.86.20:80
|
||||
header_up X-Script-Name "/octoprint"
|
||||
}
|
||||
}
|
||||
|
||||
handle /webcam/* {
|
||||
# Octoprint doesn't properly prefix webcam URLs
|
||||
import restricted-access
|
||||
reverse_proxy {
|
||||
to 192.168.86.20:80
|
||||
}
|
||||
}
|
||||
|
||||
handle_path /public/* {
|
||||
file_server {
|
||||
root /srv/storage/public
|
||||
}
|
||||
}
|
||||
|
||||
handle {
|
||||
import restricted-access
|
||||
file_server {
|
||||
root /www
|
||||
}
|
||||
reverse_proxy portal:8080
|
||||
}
|
||||
}
|
||||
|
||||
deergrove.woozle.org {
|
||||
import deergrove
|
||||
}
|
||||
|
||||
sweetums.lan {
|
||||
tls internal
|
||||
import deergrove
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
. {
|
||||
bind lan
|
||||
bind 192.168.86.2
|
||||
hosts {
|
||||
192.168.86.2 sweetums.woozle.org deergrove.woozle.org drive.woozle.org git.woozle.org ancestry.woozle.org
|
||||
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
|
||||
fallthrough
|
||||
}
|
||||
forward . 8.8.8.8
|
||||
|
|
|
@ -4,14 +4,16 @@ This is the stuff I run on my little Raspberry Pi.
|
|||
|
||||
I guess I fiddle around with it pretty frequently.
|
||||
|
||||
## Routing
|
||||
## Portal
|
||||
|
||||
My ISP uses Carrier-Grade NAT,
|
||||
which I would have called IP Masquerading.
|
||||
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.
|
||||
|
||||
This means I can't bind ports on a routeable IP.
|
||||
So instead what I do is run this SSH connection off to my cloud server,
|
||||
listens for incoming connections on port 5800,
|
||||
and then have my cloud server proxy stuff to port 5800.
|
||||
Other things like this exist,
|
||||
but they all require ridiculous things like relational databases or weird config files.
|
||||
|
||||
It's a gross kludge but it works well :)
|
||||
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.
|
|
@ -0,0 +1,9 @@
|
|||
* 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)
|
|
@ -1,10 +1,12 @@
|
|||
#! /bin/sh
|
||||
|
||||
caddy_hash () {
|
||||
echo -n "$1 "
|
||||
echo "$2" | docker run --rm -i caddy caddy hash-password
|
||||
}
|
||||
|
||||
stack=$(basename $(pwd))
|
||||
|
||||
docker --context deergrove stack deploy -c docker-compose.yaml --prune $stack
|
||||
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
|
||||
|
|
|
@ -28,28 +28,44 @@ services:
|
|||
configs:
|
||||
- source: Caddyfile
|
||||
target: /etc/caddy/Caddyfile
|
||||
- source: index.html
|
||||
target: /www/index.html
|
||||
- source: index.mjs
|
||||
target: /www/index.mjs
|
||||
- source: index.css
|
||||
target: /www/index.css
|
||||
- source: browser.html
|
||||
target: /browser.html
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
- host.lan:192.168.86.2
|
||||
|
||||
simpleauth:
|
||||
image: git.woozle.org/neale/simpleauth
|
||||
command:
|
||||
- -secret
|
||||
- /run/secrets/simpleauth.key
|
||||
secrets:
|
||||
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: ghcr.io/linuxserver/plex:1.29.2
|
||||
image: lscr.io/linuxserver/plex:latest
|
||||
networks:
|
||||
- hostnet
|
||||
environment:
|
||||
|
@ -60,14 +76,29 @@ services:
|
|||
source: /srv/sys/plex
|
||||
target: /config
|
||||
- type: bind
|
||||
source: /srv
|
||||
target: /srv
|
||||
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/media/photos
|
||||
target: /srv/media/photos
|
||||
read_only: true
|
||||
bind:
|
||||
propagation: rslave
|
||||
|
||||
transmission:
|
||||
image: lscr.io/linuxserver/transmission
|
||||
image: lscr.io/linuxserver/transmission:latest
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /srv/sys/transmission
|
||||
|
@ -75,8 +106,11 @@ services:
|
|||
- type: bind
|
||||
source: /srv/incoming
|
||||
target: /srv/incoming
|
||||
networks:
|
||||
- hostnet
|
||||
environment:
|
||||
PEERPORT: "51413"
|
||||
ports:
|
||||
- 51413:51413
|
||||
- 51413:51413/udp
|
||||
|
||||
sonarr:
|
||||
image: lscr.io/linuxserver/sonarr
|
||||
|
@ -138,7 +172,7 @@ services:
|
|||
source: /srv/incoming
|
||||
target: /srv/incoming
|
||||
prowlarr:
|
||||
image: lscr.io/linuxserver/prowlarr:develop
|
||||
image: lscr.io/linuxserver/prowlarr:latest
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
volumes:
|
||||
|
@ -157,10 +191,16 @@ services:
|
|||
target: /srv/incoming
|
||||
|
||||
gitea:
|
||||
image: gitea/gitea:1
|
||||
environment:
|
||||
USER_UID: 1000
|
||||
USER_GID: 1000
|
||||
image: codeberg.org/forgejo/forgejo:1.18-rootless
|
||||
secrets:
|
||||
- source: gitea.ini
|
||||
target: /etc/gitea/app.ini
|
||||
uid: "1000"
|
||||
gid: "1000"
|
||||
mode: 0400
|
||||
configs:
|
||||
- source: gitea-robots.txt
|
||||
target: /var/lib/gitea/custom/robots.txt
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /srv/sys/gitea
|
||||
|
@ -184,18 +224,37 @@ services:
|
|||
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/etc
|
||||
target: /usr/local/share/geneweb/etc
|
||||
- type: bind
|
||||
source: /srv/sys/geneweb/share/data
|
||||
source: /srv/sys/geneweb/
|
||||
target: /usr/local/share/geneweb/share/data
|
||||
- type: bind
|
||||
source: /srv/sys/geneweb/log
|
||||
target: /usr/local/share/geneweb/log
|
||||
|
||||
samba:
|
||||
image: dperson/samba
|
||||
|
@ -221,15 +280,21 @@ services:
|
|||
- published: 445
|
||||
target: 445
|
||||
|
||||
webdav:
|
||||
image: micromata/dave
|
||||
webfs:
|
||||
image: sigoden/dufs
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /srv
|
||||
target: /data
|
||||
configs:
|
||||
- source: dave.yaml
|
||||
target: /config/config.yaml
|
||||
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"
|
||||
|
||||
ddns:
|
||||
|
@ -240,8 +305,10 @@ services:
|
|||
- type: bind
|
||||
source: /srv/sys/ddns-updater
|
||||
target: /updater/data
|
||||
|
||||
|
||||
tunnel:
|
||||
deploy:
|
||||
replicas: 0
|
||||
image: lscr.io/linuxserver/openssh-server
|
||||
user: abc
|
||||
entrypoint:
|
||||
|
@ -272,22 +339,22 @@ configs:
|
|||
name: dave.yaml-v3
|
||||
Corefile:
|
||||
file: Corefile
|
||||
name: Corefile-v2
|
||||
name: Corefile-v7
|
||||
Caddyfile:
|
||||
file: Caddyfile
|
||||
name: Caddyfile-v80
|
||||
index.html:
|
||||
file: www/index.html
|
||||
name: index.html-v32
|
||||
index.mjs:
|
||||
file: www/index.mjs
|
||||
name: index.mjs-v1
|
||||
index.css:
|
||||
file: www/index.css
|
||||
name: index.css-v1
|
||||
browser.html:
|
||||
file: www/browser.html
|
||||
name: browser.html-v3
|
||||
name: Caddyfile-v145
|
||||
portal.json:
|
||||
file: portal.json
|
||||
name: portal.json-v6
|
||||
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
|
||||
|
||||
secrets:
|
||||
passwd:
|
||||
|
@ -302,6 +369,24 @@ secrets:
|
|||
known_hosts:
|
||||
file: secrets/known_hosts
|
||||
name: known_hosts-v1
|
||||
gitea.ini:
|
||||
file: secrets/gitea.ini
|
||||
name: gitea.ini-v4
|
||||
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
|
||||
|
||||
networks:
|
||||
hostnet:
|
||||
|
|
|
@ -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/assets/icon_inv.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"
|
||||
}
|
||||
}
|
|
@ -1,47 +1,363 @@
|
|||
version: "3.8"
|
||||
services:
|
||||
jellyfin:
|
||||
image: ghcr.io/linuxserver/jellyfin:10.7.7
|
||||
coredns:
|
||||
image: coredns/coredns
|
||||
networks:
|
||||
- hostnet
|
||||
configs:
|
||||
- source: Corefile
|
||||
target: /Corefile
|
||||
|
||||
caddy:
|
||||
image: caddy:2-alpine
|
||||
ports:
|
||||
- target: 8096
|
||||
published: 8096
|
||||
- target: 7359
|
||||
published: 7359
|
||||
protocol: udp
|
||||
- target: 1900
|
||||
published: 1900
|
||||
protocol: udp
|
||||
- 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: /mnt/ext/srv/jellyfin
|
||||
source: /srv/sys/jellyfin/config
|
||||
target: /config
|
||||
- type: bind
|
||||
source: /media
|
||||
target: /media
|
||||
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/share/geneweb/etc
|
||||
- type: bind
|
||||
source: /srv/sys/geneweb/share/data
|
||||
target: /usr/local/share/geneweb/share/data
|
||||
- type: bind
|
||||
source: /srv/sys/geneweb/log
|
||||
target: /usr/local/share/geneweb/log
|
||||
|
||||
samba:
|
||||
image: dperson/samba
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /srv
|
||||
target: /srv
|
||||
bind:
|
||||
propagation: rslave
|
||||
- type: bind
|
||||
source: /dev/video10
|
||||
target: /dev/video10
|
||||
- type: bind
|
||||
source: /dev/video11
|
||||
target: /dev/video11
|
||||
- type: bind
|
||||
source: /dev/video12
|
||||
target: /dev/video12
|
||||
- type: bind
|
||||
source: /dev/video13
|
||||
target: /dev/video13
|
||||
- type: bind
|
||||
source: /dev/video14
|
||||
target: /dev/video14
|
||||
- type: bind
|
||||
source: /dev/video15
|
||||
target: /dev/video15
|
||||
- type: bind
|
||||
source: /dev/video16
|
||||
target: /dev/video16
|
||||
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
|
||||
|
||||
webdav:
|
||||
image: micromata/dave
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /srv
|
||||
target: /data
|
||||
configs:
|
||||
- source: dave.yaml
|
||||
target: /config/config.yaml
|
||||
user: "911:911"
|
||||
|
||||
ddns:
|
||||
image: qmcgaw/ddns-updater
|
||||
dns:
|
||||
- 1.1.1.1
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /srv/sys/ddns-updater
|
||||
target: /updater/data
|
||||
|
||||
tunnel:
|
||||
deploy:
|
||||
replicas: 0
|
||||
image: lscr.io/linuxserver/openssh-server
|
||||
user: abc
|
||||
entrypoint:
|
||||
- /usr/bin/ssh
|
||||
- -N
|
||||
- -R 172.17.0.1:5880:caddy:80 # 172.17.0.1 = docker host IP
|
||||
- -R :5822:host.docker.internal:22
|
||||
- -o ServerAliveInterval=30
|
||||
- core@melville.woozle.org
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
secrets:
|
||||
- source: tunnel
|
||||
target: /config/.ssh/id_rsa
|
||||
uid: "911"
|
||||
gid: "911"
|
||||
mode: 0600
|
||||
- source: known_hosts
|
||||
target: /config/.ssh/known_hosts
|
||||
uid: "911"
|
||||
gid: "911"
|
||||
mode: 0600
|
||||
|
||||
|
||||
configs:
|
||||
dave.yaml:
|
||||
file: dave.yaml
|
||||
name: dave.yaml-v3
|
||||
Corefile:
|
||||
file: Corefile
|
||||
name: Corefile-v3
|
||||
Caddyfile:
|
||||
file: Caddyfile
|
||||
name: Caddyfile-v89
|
||||
index.html:
|
||||
file: www/index.html
|
||||
name: index.html-v36
|
||||
index.mjs:
|
||||
file: www/index.mjs
|
||||
name: index.mjs-v1
|
||||
index.css:
|
||||
file: www/index.css
|
||||
name: index.css-v1
|
||||
browser.html:
|
||||
file: www/browser.html
|
||||
name: browser.html-v3
|
||||
deergrove.png:
|
||||
file: www/deergrove.png
|
||||
name: deergrove.png-v1
|
||||
authelia.yaml:
|
||||
file: authelia.yaml
|
||||
name: authelia.yaml-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
|
||||
forgejo.ini:
|
||||
file: secrets/forgejo.ini
|
||||
name: forgejo.ini-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-v1
|
||||
|
||||
networks:
|
||||
hostnet:
|
||||
external: true
|
||||
name: host
|
||||
|
||||
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Woozle Drive</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/dom111/webdav-js/assets/css/style-min.css">
|
||||
<script>
|
||||
function init() {
|
||||
// This is dumb, but webdav-min.js doesn't have any checks to make sure the document is loaded.
|
||||
let scr = document.head.appendChild(document.createElement("script"))
|
||||
scr.src = "https://cdn.jsdelivr.net/gh/dom111/webdav-js/src/webdav-min.js"
|
||||
|
||||
for (let e of document.querySelectorAll(".listing")) {
|
||||
console.log("Let's pray the WebDAV stuff works!", e)
|
||||
e.remove()
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", init)
|
||||
} else {
|
||||
init()
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<ul class="listing">
|
||||
{{range .Items}}
|
||||
<li>
|
||||
<a href="{{html .URL}}">{{html .Name}}</a>
|
||||
<span class="size" data-value="{{.Size}}">{{.HumanSize}}</span>
|
||||
<time>{{.HumanModTime "2006-01-02T15:04:05Z"}}</time>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
|
@ -27,7 +27,7 @@ nav a {
|
|||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
nav a[target] {
|
||||
nav a[data-no-menu] {
|
||||
display: none;
|
||||
}
|
||||
nav a:hover {
|
||||
|
|
|
@ -4,29 +4,12 @@
|
|||
<title>Deer Grove</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" href="icons/deergrove.png">
|
||||
<link rel="icon" href="deergrove.png">
|
||||
<link rel="stylesheet" href="index.css">
|
||||
<script src="index.mjs" type="module"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<a href="/sonarr/" data-icon="/sonarr/Content/Images/logo.svg" title="Episode manager">Shows</a>
|
||||
<a href="/radarr/" data-icon="/radarr/Content/Images/logo.svg" title="Movie manager">Movies</a>
|
||||
<a href="/lidarr/" data-icon="/lidarr/Content/Images/logo.svg" title="Music manager">Music</a>
|
||||
<a href="/readarr/" data-icon="/readarr/Content/Images/logo.svg" title="Book manager">Books</a>
|
||||
<a href="/sucker/" data-icon="/sucker/cd-dvd.svg" title="Media Sucker">Sucker</a>
|
||||
<hr>
|
||||
<a href="/prowlarr/" data-icon="/prowlarr/Content/Images/logo.png" title="Indexer/Searcher">Search</a>
|
||||
<a href="/nzbget/" data-icon="/nzbget/img/favicon-256x256.png" title="Usenet downloader">Usenet</a>
|
||||
<a href="/transmission/web/" data-icon="/transmission/web/style/transmission/images/logo.png" title="BitTorrent downloader">BitTorrent</a>
|
||||
<hr>
|
||||
<a href="/octoprint/" data-icon="/octoprint/static/img/logo.png" title="3D Printer Front-End">Octoprint</a>
|
||||
<a href="/wallart/" data-icon="/wallart/wallart.png" title="Wall Art uploader">Wall Art</a>
|
||||
|
||||
<!-- Items that launch a new tab don't appear in the top menu -->
|
||||
<a href="https://git.woozle.org" target="_blank" data-icon="https://git.woozle.org/assets/img/logo.svg" title="Git repositories">Git</a>
|
||||
<a href="https://drive.woozle.org/" target="_blank" data-icon="/public/icons/cloud-folder.png" titled="Shared storage">Drive</a>
|
||||
<a href="https://ancestry.woozle.org/" target="_blank" data-icon="https://ancestry.woozle.org/images/favicon_gwd.png" title="Genealogy">Ancestry</a>
|
||||
</nav>
|
||||
<section id="app">
|
||||
<iframe></iframe>
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
let frames = {}
|
||||
function activate(event, element) {
|
||||
if (element.target) {
|
||||
return
|
||||
}
|
||||
event.preventDefault()
|
||||
|
||||
let parent = element.parentElement
|
||||
|
@ -49,7 +46,7 @@ function frameLoaded(frame) {
|
|||
}
|
||||
|
||||
let defaultIcon = null
|
||||
function init() {
|
||||
async function init() {
|
||||
let doc = document.querySelector("iframe").contentDocument
|
||||
|
||||
defaultIcon = document.querySelector("link[rel~='icon']").href
|
||||
|
@ -68,22 +65,40 @@ function init() {
|
|||
let icons = doc.body.appendChild(doc.createElement("section"))
|
||||
icons.classList.add("icons")
|
||||
|
||||
for (let link of document.querySelectorAll("nav a")) {
|
||||
let dlink = icons.appendChild(link.cloneNode(true))
|
||||
dlink.textContent = ""
|
||||
let portalURL = new URL("portal.json", window.location)
|
||||
let resp = await fetch(portalURL)
|
||||
let obj = await resp.json()
|
||||
let nav = document.querySelector("nav")
|
||||
for (let app of obj) {
|
||||
let hlink = null
|
||||
if (app.target != "_blank") {
|
||||
hlink = nav.appendChild(document.createElement("a"))
|
||||
hlink.href = app.href
|
||||
hlink.textContent = app.title
|
||||
if (app.target) {
|
||||
hlink.target = app.target
|
||||
} else {
|
||||
hlink.addEventListener("click", event => activate(event, hlink))
|
||||
}
|
||||
}
|
||||
|
||||
if (link.dataset.icon) {
|
||||
let dlink = icons.appendChild(doc.createElement("a"))
|
||||
dlink.href = app.href
|
||||
if (app.target) {
|
||||
dlink.target = app.target
|
||||
} else {
|
||||
dlink.addEventListener("click", event => activate(event, hlink))
|
||||
}
|
||||
if (app.icon) {
|
||||
let icon = dlink.appendChild(doc.createElement("img"))
|
||||
icon.src = link.dataset.icon
|
||||
icon.src = app.icon
|
||||
icon.alt = app.title
|
||||
icon.title = app.title
|
||||
icon.style.objectFit = "cover"
|
||||
} else {
|
||||
let text = dlink.appendChild(doc.createElement("div"))
|
||||
text.textContent = link.textContent
|
||||
text.textContent = app.title
|
||||
}
|
||||
|
||||
// Make both of them update the selected tab
|
||||
link.addEventListener("click", event => activate(event, link))
|
||||
dlink.addEventListener("click", event => activate(event, link))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,11 @@ deergrove.woozle.org, git.woozle.org, ancestry.woozle.org, drive.woozle.org {
|
|||
reverse_proxy host.docker.internal:5880
|
||||
}
|
||||
|
||||
passwords.woozle.org {
|
||||
reverse_proxy /notifications/hub vaultwarden:3012
|
||||
reverse_proxy vaultwarden:80
|
||||
}
|
||||
|
||||
www.woozle.org, woozle.org {
|
||||
root * /srv/www/woozle.org
|
||||
file_server
|
||||
|
|
|
@ -36,5 +36,5 @@ services:
|
|||
configs:
|
||||
Caddyfile:
|
||||
file: Caddyfile
|
||||
name: Caddyfile-v9
|
||||
name: Caddyfile-v11
|
||||
|
||||
|
|
Loading…
Reference in New Issue