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) {
|
(restricted-access) {
|
||||||
forward_auth simpleauth:8080 {
|
forward_auth simpleauth:8080 {
|
||||||
uri /
|
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 {
|
drive.woozle.org {
|
||||||
import restricted-access
|
import restricted-access
|
||||||
|
reverse_proxy webfs:5000
|
||||||
|
}
|
||||||
|
|
||||||
# XXX: browsing says method not allowed
|
media.woozle.org {
|
||||||
@nondav {
|
reverse_proxy jellyfin:8096
|
||||||
method HEAD GET
|
|
||||||
}
|
|
||||||
# route overrides built-in ordering
|
|
||||||
route {
|
|
||||||
file_server @nondav {
|
|
||||||
root /srv/
|
|
||||||
browse /browser.html
|
|
||||||
}
|
|
||||||
reverse_proxy webdav:8000
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# XXX: have this use caddy auth
|
# XXX: have this use caddy auth
|
||||||
|
@ -35,89 +29,69 @@ ancestry.woozle.org {
|
||||||
reverse_proxy geneweb:2317
|
reverse_proxy geneweb:2317
|
||||||
}
|
}
|
||||||
|
|
||||||
|
photos.woozle.org {
|
||||||
|
import restricted-access
|
||||||
|
reverse_proxy pigallery2:80
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## handle sends original path
|
## handle sends original path
|
||||||
## handle_path truncates path
|
## handle_path truncates path
|
||||||
##
|
##
|
||||||
|
|
||||||
(deergrove) {
|
deergrove.woozle.org {
|
||||||
|
import restricted-access
|
||||||
|
|
||||||
handle_path /ddns/* {
|
handle_path /ddns/* {
|
||||||
import restricted-access
|
|
||||||
reverse_proxy ddns:8000
|
reverse_proxy ddns:8000
|
||||||
}
|
}
|
||||||
|
|
||||||
handle /transmission/* {
|
handle /transmission/* {
|
||||||
import restricted-access
|
reverse_proxy transmission:9091
|
||||||
reverse_proxy host.docker.internal:9091
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handle /nzbget/* {
|
handle /nzbget/* {
|
||||||
import restricted-access
|
|
||||||
reverse_proxy nzbget:6789
|
reverse_proxy nzbget:6789
|
||||||
}
|
}
|
||||||
|
|
||||||
handle /sonarr/* {
|
handle /sonarr/* {
|
||||||
import restricted-access
|
|
||||||
reverse_proxy sonarr:8989
|
reverse_proxy sonarr:8989
|
||||||
}
|
}
|
||||||
handle /radarr/* {
|
handle /radarr/* {
|
||||||
import restricted-access
|
|
||||||
reverse_proxy radarr:7878
|
reverse_proxy radarr:7878
|
||||||
}
|
}
|
||||||
handle /readarr/* {
|
handle /readarr/* {
|
||||||
import restricted-access
|
|
||||||
reverse_proxy readarr:8787
|
reverse_proxy readarr:8787
|
||||||
}
|
}
|
||||||
handle /lidarr/* {
|
handle /lidarr/* {
|
||||||
import restricted-access
|
|
||||||
reverse_proxy lidarr:8686
|
reverse_proxy lidarr:8686
|
||||||
}
|
}
|
||||||
handle /prowlarr/* {
|
handle /prowlarr/* {
|
||||||
import restricted-access
|
|
||||||
reverse_proxy prowlarr:9696
|
reverse_proxy prowlarr:9696
|
||||||
}
|
}
|
||||||
|
handle /unmanic/* {
|
||||||
|
reverse_proxy unmanic:8888
|
||||||
|
}
|
||||||
|
|
||||||
handle_path /sucker/* {
|
handle_path /sucker/* {
|
||||||
import restricted-access
|
reverse_proxy host.lan:5801
|
||||||
reverse_proxy host.docker.internal:5880
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handle_path /netdata/* {
|
||||||
|
reverse_proxy netdata:19999
|
||||||
|
}
|
||||||
|
|
||||||
|
# Octoprint serves up broken webcam URLs
|
||||||
|
uri replace /webcam/ /octoprint/webcam/
|
||||||
handle_path /octoprint/* {
|
handle_path /octoprint/* {
|
||||||
import restricted-access
|
|
||||||
reverse_proxy {
|
reverse_proxy {
|
||||||
to 192.168.86.20:80
|
to 192.168.86.20:80
|
||||||
header_up X-Script-Name "/octoprint"
|
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 {
|
handle {
|
||||||
import restricted-access
|
reverse_proxy portal:8080
|
||||||
file_server {
|
|
||||||
root /www
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deergrove.woozle.org {
|
|
||||||
import deergrove
|
|
||||||
}
|
|
||||||
|
|
||||||
sweetums.lan {
|
|
||||||
tls internal
|
|
||||||
import deergrove
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
. {
|
. {
|
||||||
bind lan
|
bind 192.168.86.2
|
||||||
hosts {
|
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
|
fallthrough
|
||||||
}
|
}
|
||||||
forward . 8.8.8.8
|
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.
|
I guess I fiddle around with it pretty frequently.
|
||||||
|
|
||||||
## Routing
|
## Portal
|
||||||
|
|
||||||
My ISP uses Carrier-Grade NAT,
|
In the [www](www) directory is a static HTML/JavaScript portal thing I wrote.
|
||||||
which I would have called IP Masquerading.
|
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.
|
Other things like this exist,
|
||||||
So instead what I do is run this SSH connection off to my cloud server,
|
but they all require ridiculous things like relational databases or weird config files.
|
||||||
listens for incoming connections on port 5800,
|
|
||||||
and then have my cloud server proxy stuff to port 5800.
|
|
||||||
|
|
||||||
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
|
#! /bin/sh
|
||||||
|
|
||||||
caddy_hash () {
|
|
||||||
echo -n "$1 "
|
|
||||||
echo "$2" | docker run --rm -i caddy caddy hash-password
|
|
||||||
}
|
|
||||||
|
|
||||||
stack=$(basename $(pwd))
|
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:
|
configs:
|
||||||
- source: Caddyfile
|
- source: Caddyfile
|
||||||
target: /etc/caddy/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:
|
extra_hosts:
|
||||||
- host.docker.internal:host-gateway
|
- host.docker.internal:host-gateway
|
||||||
|
- host.lan:192.168.86.2
|
||||||
|
|
||||||
simpleauth:
|
simpleauth:
|
||||||
image: git.woozle.org/neale/simpleauth
|
image: git.woozle.org/neale/simpleauth
|
||||||
command:
|
|
||||||
- -secret
|
|
||||||
- /run/secrets/simpleauth.key
|
|
||||||
secrets:
|
secrets:
|
||||||
- passwd
|
- passwd
|
||||||
- simpleauth.key
|
- 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:
|
plex:
|
||||||
image: ghcr.io/linuxserver/plex:1.29.2
|
image: lscr.io/linuxserver/plex:latest
|
||||||
networks:
|
networks:
|
||||||
- hostnet
|
- hostnet
|
||||||
environment:
|
environment:
|
||||||
|
@ -60,14 +76,29 @@ services:
|
||||||
source: /srv/sys/plex
|
source: /srv/sys/plex
|
||||||
target: /config
|
target: /config
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /srv
|
source: /srv/media/
|
||||||
target: /srv
|
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
|
read_only: true
|
||||||
bind:
|
|
||||||
propagation: rslave
|
|
||||||
|
|
||||||
transmission:
|
transmission:
|
||||||
image: lscr.io/linuxserver/transmission
|
image: lscr.io/linuxserver/transmission:latest
|
||||||
volumes:
|
volumes:
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /srv/sys/transmission
|
source: /srv/sys/transmission
|
||||||
|
@ -75,8 +106,11 @@ services:
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /srv/incoming
|
source: /srv/incoming
|
||||||
target: /srv/incoming
|
target: /srv/incoming
|
||||||
networks:
|
environment:
|
||||||
- hostnet
|
PEERPORT: "51413"
|
||||||
|
ports:
|
||||||
|
- 51413:51413
|
||||||
|
- 51413:51413/udp
|
||||||
|
|
||||||
sonarr:
|
sonarr:
|
||||||
image: lscr.io/linuxserver/sonarr
|
image: lscr.io/linuxserver/sonarr
|
||||||
|
@ -138,7 +172,7 @@ services:
|
||||||
source: /srv/incoming
|
source: /srv/incoming
|
||||||
target: /srv/incoming
|
target: /srv/incoming
|
||||||
prowlarr:
|
prowlarr:
|
||||||
image: lscr.io/linuxserver/prowlarr:develop
|
image: lscr.io/linuxserver/prowlarr:latest
|
||||||
extra_hosts:
|
extra_hosts:
|
||||||
- host.docker.internal:host-gateway
|
- host.docker.internal:host-gateway
|
||||||
volumes:
|
volumes:
|
||||||
|
@ -157,10 +191,16 @@ services:
|
||||||
target: /srv/incoming
|
target: /srv/incoming
|
||||||
|
|
||||||
gitea:
|
gitea:
|
||||||
image: gitea/gitea:1
|
image: codeberg.org/forgejo/forgejo:1.18-rootless
|
||||||
environment:
|
secrets:
|
||||||
USER_UID: 1000
|
- source: gitea.ini
|
||||||
USER_GID: 1000
|
target: /etc/gitea/app.ini
|
||||||
|
uid: "1000"
|
||||||
|
gid: "1000"
|
||||||
|
mode: 0400
|
||||||
|
configs:
|
||||||
|
- source: gitea-robots.txt
|
||||||
|
target: /var/lib/gitea/custom/robots.txt
|
||||||
volumes:
|
volumes:
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /srv/sys/gitea
|
source: /srv/sys/gitea
|
||||||
|
@ -184,18 +224,37 @@ services:
|
||||||
source: /srv/sys/atlas/status
|
source: /srv/sys/atlas/status
|
||||||
target: /var/atlas-probe/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:
|
geneweb:
|
||||||
image: ravermeister/geneweb
|
image: ravermeister/geneweb
|
||||||
volumes:
|
volumes:
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /srv/sys/geneweb/etc
|
source: /srv/sys/geneweb/
|
||||||
target: /usr/local/share/geneweb/etc
|
|
||||||
- type: bind
|
|
||||||
source: /srv/sys/geneweb/share/data
|
|
||||||
target: /usr/local/share/geneweb/share/data
|
target: /usr/local/share/geneweb/share/data
|
||||||
- type: bind
|
|
||||||
source: /srv/sys/geneweb/log
|
|
||||||
target: /usr/local/share/geneweb/log
|
|
||||||
|
|
||||||
samba:
|
samba:
|
||||||
image: dperson/samba
|
image: dperson/samba
|
||||||
|
@ -221,15 +280,21 @@ services:
|
||||||
- published: 445
|
- published: 445
|
||||||
target: 445
|
target: 445
|
||||||
|
|
||||||
webdav:
|
webfs:
|
||||||
image: micromata/dave
|
image: sigoden/dufs
|
||||||
volumes:
|
volumes:
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /srv
|
source: /srv/storage
|
||||||
target: /data
|
target: /srv/storage
|
||||||
configs:
|
- type: bind
|
||||||
- source: dave.yaml
|
source: /srv/incoming
|
||||||
target: /config/config.yaml
|
target: /srv/incoming
|
||||||
|
- type: bind
|
||||||
|
source: /srv/media
|
||||||
|
target: /srv/media
|
||||||
|
command:
|
||||||
|
- -A
|
||||||
|
- /srv
|
||||||
user: "911:911"
|
user: "911:911"
|
||||||
|
|
||||||
ddns:
|
ddns:
|
||||||
|
@ -242,6 +307,8 @@ services:
|
||||||
target: /updater/data
|
target: /updater/data
|
||||||
|
|
||||||
tunnel:
|
tunnel:
|
||||||
|
deploy:
|
||||||
|
replicas: 0
|
||||||
image: lscr.io/linuxserver/openssh-server
|
image: lscr.io/linuxserver/openssh-server
|
||||||
user: abc
|
user: abc
|
||||||
entrypoint:
|
entrypoint:
|
||||||
|
@ -272,22 +339,22 @@ configs:
|
||||||
name: dave.yaml-v3
|
name: dave.yaml-v3
|
||||||
Corefile:
|
Corefile:
|
||||||
file: Corefile
|
file: Corefile
|
||||||
name: Corefile-v2
|
name: Corefile-v7
|
||||||
Caddyfile:
|
Caddyfile:
|
||||||
file: Caddyfile
|
file: Caddyfile
|
||||||
name: Caddyfile-v80
|
name: Caddyfile-v145
|
||||||
index.html:
|
portal.json:
|
||||||
file: www/index.html
|
file: portal.json
|
||||||
name: index.html-v32
|
name: portal.json-v6
|
||||||
index.mjs:
|
deergrove.png:
|
||||||
file: www/index.mjs
|
file: www/deergrove.png
|
||||||
name: index.mjs-v1
|
name: deergrove.png-v1
|
||||||
index.css:
|
netdata.conf:
|
||||||
file: www/index.css
|
file: netdata.conf
|
||||||
name: index.css-v1
|
name: netdata.conf-v1
|
||||||
browser.html:
|
gitea-robots.txt:
|
||||||
file: www/browser.html
|
file: gitea-robots.txt
|
||||||
name: browser.html-v3
|
name: gitea-robots.txt-v1
|
||||||
|
|
||||||
secrets:
|
secrets:
|
||||||
passwd:
|
passwd:
|
||||||
|
@ -302,6 +369,24 @@ secrets:
|
||||||
known_hosts:
|
known_hosts:
|
||||||
file: secrets/known_hosts
|
file: secrets/known_hosts
|
||||||
name: known_hosts-v1
|
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:
|
networks:
|
||||||
hostnet:
|
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"
|
version: "3.8"
|
||||||
services:
|
services:
|
||||||
jellyfin:
|
coredns:
|
||||||
image: ghcr.io/linuxserver/jellyfin:10.7.7
|
image: coredns/coredns
|
||||||
|
networks:
|
||||||
|
- hostnet
|
||||||
|
configs:
|
||||||
|
- source: Corefile
|
||||||
|
target: /Corefile
|
||||||
|
|
||||||
|
caddy:
|
||||||
|
image: caddy:2-alpine
|
||||||
ports:
|
ports:
|
||||||
- target: 8096
|
- target: 443
|
||||||
published: 8096
|
published: 443
|
||||||
- target: 7359
|
mode: host
|
||||||
published: 7359
|
- target: 80
|
||||||
protocol: udp
|
published: 80
|
||||||
- target: 1900
|
mode: host
|
||||||
published: 1900
|
volumes:
|
||||||
protocol: udp
|
- 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:
|
environment:
|
||||||
TZ: US/Mountain
|
TZ: US/Mountain
|
||||||
volumes:
|
volumes:
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /mnt/ext/srv/jellyfin
|
source: /srv/sys/jellyfin/config
|
||||||
target: /config
|
target: /config
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /media
|
source: /srv/sys/jellyfin/cache
|
||||||
target: /media
|
target: /cache
|
||||||
|
- type: bind
|
||||||
|
source: /srv/media
|
||||||
|
target: /srv/media
|
||||||
read_only: true
|
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:
|
bind:
|
||||||
propagation: rslave
|
propagation: rslave
|
||||||
- type: bind
|
environment:
|
||||||
source: /dev/video10
|
NMBD: enable
|
||||||
target: /dev/video10
|
RECYCLE: disable
|
||||||
- type: bind
|
USERID: 911
|
||||||
source: /dev/video11
|
GROUPID: 911
|
||||||
target: /dev/video11
|
# name;path;browse;readonly;guest
|
||||||
- type: bind
|
SHARE1: drive;/srv;yes;no;no
|
||||||
source: /dev/video12
|
SHARE2: retropie;/srv/media/games/retropie;yes;yes;yes
|
||||||
target: /dev/video12
|
env_file:
|
||||||
- type: bind
|
- secrets/samba-users.env
|
||||||
source: /dev/video13
|
ports:
|
||||||
target: /dev/video13
|
- published: 139
|
||||||
- type: bind
|
target: 139
|
||||||
source: /dev/video14
|
- published: 445
|
||||||
target: /dev/video14
|
target: 445
|
||||||
- type: bind
|
|
||||||
source: /dev/video15
|
webdav:
|
||||||
target: /dev/video15
|
image: micromata/dave
|
||||||
- type: bind
|
volumes:
|
||||||
source: /dev/video16
|
- type: bind
|
||||||
target: /dev/video16
|
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;
|
text-decoration: none;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
nav a[target] {
|
nav a[data-no-menu] {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
nav a:hover {
|
nav a:hover {
|
||||||
|
|
|
@ -4,29 +4,12 @@
|
||||||
<title>Deer Grove</title>
|
<title>Deer Grove</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<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">
|
<link rel="stylesheet" href="index.css">
|
||||||
<script src="index.mjs" type="module"></script>
|
<script src="index.mjs" type="module"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<nav>
|
<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>
|
</nav>
|
||||||
<section id="app">
|
<section id="app">
|
||||||
<iframe></iframe>
|
<iframe></iframe>
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
let frames = {}
|
let frames = {}
|
||||||
function activate(event, element) {
|
function activate(event, element) {
|
||||||
if (element.target) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
||||||
let parent = element.parentElement
|
let parent = element.parentElement
|
||||||
|
@ -49,7 +46,7 @@ function frameLoaded(frame) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let defaultIcon = null
|
let defaultIcon = null
|
||||||
function init() {
|
async function init() {
|
||||||
let doc = document.querySelector("iframe").contentDocument
|
let doc = document.querySelector("iframe").contentDocument
|
||||||
|
|
||||||
defaultIcon = document.querySelector("link[rel~='icon']").href
|
defaultIcon = document.querySelector("link[rel~='icon']").href
|
||||||
|
@ -68,22 +65,40 @@ function init() {
|
||||||
let icons = doc.body.appendChild(doc.createElement("section"))
|
let icons = doc.body.appendChild(doc.createElement("section"))
|
||||||
icons.classList.add("icons")
|
icons.classList.add("icons")
|
||||||
|
|
||||||
for (let link of document.querySelectorAll("nav a")) {
|
let portalURL = new URL("portal.json", window.location)
|
||||||
let dlink = icons.appendChild(link.cloneNode(true))
|
let resp = await fetch(portalURL)
|
||||||
dlink.textContent = ""
|
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"))
|
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"
|
icon.style.objectFit = "cover"
|
||||||
} else {
|
} else {
|
||||||
let text = dlink.appendChild(doc.createElement("div"))
|
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
|
reverse_proxy host.docker.internal:5880
|
||||||
}
|
}
|
||||||
|
|
||||||
|
passwords.woozle.org {
|
||||||
|
reverse_proxy /notifications/hub vaultwarden:3012
|
||||||
|
reverse_proxy vaultwarden:80
|
||||||
|
}
|
||||||
|
|
||||||
www.woozle.org, woozle.org {
|
www.woozle.org, woozle.org {
|
||||||
root * /srv/www/woozle.org
|
root * /srv/www/woozle.org
|
||||||
file_server
|
file_server
|
||||||
|
|
|
@ -36,5 +36,5 @@ services:
|
||||||
configs:
|
configs:
|
||||||
Caddyfile:
|
Caddyfile:
|
||||||
file: Caddyfile
|
file: Caddyfile
|
||||||
name: Caddyfile-v9
|
name: Caddyfile-v11
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue