Compare commits
No commits in common. "e32e4f586f6cddcbe8759924c445e65e35d69a6a" and "b54e137b2ead0e9ab9ba3b05df2bf6c78fe013d2" have entirely different histories.
e32e4f586f
...
b54e137b2e
|
@ -1,13 +1,11 @@
|
||||||
{
|
{
|
||||||
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-Username
|
copy_headers X-Simpleauth-Token
|
||||||
header_down X-Simpleauth-Domain "woozle.org"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,11 +15,19 @@ git.woozle.org {
|
||||||
|
|
||||||
drive.woozle.org {
|
drive.woozle.org {
|
||||||
import restricted-access
|
import restricted-access
|
||||||
reverse_proxy webfs:5000
|
|
||||||
}
|
|
||||||
|
|
||||||
media.woozle.org {
|
# XXX: browsing says method not allowed
|
||||||
reverse_proxy jellyfin:8096
|
@nondav {
|
||||||
|
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
|
||||||
|
@ -29,69 +35,89 @@ 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.woozle.org {
|
(deergrove) {
|
||||||
import restricted-access
|
|
||||||
|
|
||||||
handle_path /ddns/* {
|
handle_path /ddns/* {
|
||||||
|
import restricted-access
|
||||||
reverse_proxy ddns:8000
|
reverse_proxy ddns:8000
|
||||||
}
|
}
|
||||||
|
|
||||||
handle /transmission/* {
|
handle /transmission/* {
|
||||||
reverse_proxy transmission:9091
|
import restricted-access
|
||||||
|
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/* {
|
||||||
reverse_proxy host.lan:5801
|
import restricted-access
|
||||||
|
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 {
|
||||||
reverse_proxy portal:8080
|
import restricted-access
|
||||||
|
file_server {
|
||||||
|
root /www
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deergrove.woozle.org {
|
||||||
|
import deergrove
|
||||||
|
}
|
||||||
|
|
||||||
|
sweetums.lan {
|
||||||
|
tls internal
|
||||||
|
import deergrove
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
. {
|
. {
|
||||||
bind 192.168.86.2
|
bind lan
|
||||||
hosts {
|
hosts {
|
||||||
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
|
192.168.86.2 sweetums.woozle.org deergrove.woozle.org drive.woozle.org git.woozle.org ancestry.woozle.org
|
||||||
fallthrough
|
fallthrough
|
||||||
}
|
}
|
||||||
forward . 8.8.8.8
|
forward . 8.8.8.8
|
||||||
|
|
|
@ -4,16 +4,14 @@ 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.
|
||||||
|
|
||||||
## Portal
|
## Routing
|
||||||
|
|
||||||
In the [www](www) directory is a static HTML/JavaScript portal thing I wrote.
|
My ISP uses Carrier-Grade NAT,
|
||||||
It doesn't need any server configuration,
|
which I would have called IP Masquerading.
|
||||||
you just edit the HTML to manage what apps it serves.
|
|
||||||
|
|
||||||
Other things like this exist,
|
This means I can't bind ports on a routeable IP.
|
||||||
but they all require ridiculous things like relational databases or weird config files.
|
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.
|
||||||
|
|
||||||
I should probably package this up or something,
|
It's a gross kludge but it works well :)
|
||||||
but then I'd have to put effort into publicizing it,
|
|
||||||
and run a ticketing system or something,
|
|
||||||
so meh.
|
|
||||||
|
|
|
@ -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)
|
|
|
@ -1,12 +1,10 @@
|
||||||
#! /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))
|
||||||
|
|
||||||
extra="--resolve-image changed"
|
docker --context deergrove stack deploy -c docker-compose.yaml --prune $stack
|
||||||
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,44 +28,28 @@ 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
|
||||||
secrets:
|
command:
|
||||||
|
- -secret
|
||||||
|
- /run/secrets/simpleauth.key
|
||||||
|
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: lscr.io/linuxserver/plex:latest
|
image: ghcr.io/linuxserver/plex:1.29.2
|
||||||
networks:
|
networks:
|
||||||
- hostnet
|
- hostnet
|
||||||
environment:
|
environment:
|
||||||
|
@ -76,29 +60,14 @@ services:
|
||||||
source: /srv/sys/plex
|
source: /srv/sys/plex
|
||||||
target: /config
|
target: /config
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /srv/media/
|
source: /srv
|
||||||
target: /srv/media/
|
target: /srv
|
||||||
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:latest
|
image: lscr.io/linuxserver/transmission
|
||||||
volumes:
|
volumes:
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /srv/sys/transmission
|
source: /srv/sys/transmission
|
||||||
|
@ -106,11 +75,8 @@ services:
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /srv/incoming
|
source: /srv/incoming
|
||||||
target: /srv/incoming
|
target: /srv/incoming
|
||||||
environment:
|
networks:
|
||||||
PEERPORT: "51413"
|
- hostnet
|
||||||
ports:
|
|
||||||
- 51413:51413
|
|
||||||
- 51413:51413/udp
|
|
||||||
|
|
||||||
sonarr:
|
sonarr:
|
||||||
image: lscr.io/linuxserver/sonarr
|
image: lscr.io/linuxserver/sonarr
|
||||||
|
@ -172,7 +138,7 @@ services:
|
||||||
source: /srv/incoming
|
source: /srv/incoming
|
||||||
target: /srv/incoming
|
target: /srv/incoming
|
||||||
prowlarr:
|
prowlarr:
|
||||||
image: lscr.io/linuxserver/prowlarr:latest
|
image: lscr.io/linuxserver/prowlarr:develop
|
||||||
extra_hosts:
|
extra_hosts:
|
||||||
- host.docker.internal:host-gateway
|
- host.docker.internal:host-gateway
|
||||||
volumes:
|
volumes:
|
||||||
|
@ -191,16 +157,10 @@ services:
|
||||||
target: /srv/incoming
|
target: /srv/incoming
|
||||||
|
|
||||||
gitea:
|
gitea:
|
||||||
image: codeberg.org/forgejo/forgejo:1.18-rootless
|
image: gitea/gitea:1
|
||||||
secrets:
|
environment:
|
||||||
- source: gitea.ini
|
USER_UID: 1000
|
||||||
target: /etc/gitea/app.ini
|
USER_GID: 1000
|
||||||
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
|
||||||
|
@ -224,37 +184,18 @@ 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/
|
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
|
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
|
||||||
|
@ -280,21 +221,15 @@ services:
|
||||||
- published: 445
|
- published: 445
|
||||||
target: 445
|
target: 445
|
||||||
|
|
||||||
webfs:
|
webdav:
|
||||||
image: sigoden/dufs
|
image: micromata/dave
|
||||||
volumes:
|
volumes:
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /srv/storage
|
source: /srv
|
||||||
target: /srv/storage
|
target: /data
|
||||||
- type: bind
|
configs:
|
||||||
source: /srv/incoming
|
- source: dave.yaml
|
||||||
target: /srv/incoming
|
target: /config/config.yaml
|
||||||
- type: bind
|
|
||||||
source: /srv/media
|
|
||||||
target: /srv/media
|
|
||||||
command:
|
|
||||||
- -A
|
|
||||||
- /srv
|
|
||||||
user: "911:911"
|
user: "911:911"
|
||||||
|
|
||||||
ddns:
|
ddns:
|
||||||
|
@ -305,10 +240,8 @@ services:
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /srv/sys/ddns-updater
|
source: /srv/sys/ddns-updater
|
||||||
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:
|
||||||
|
@ -339,22 +272,22 @@ configs:
|
||||||
name: dave.yaml-v3
|
name: dave.yaml-v3
|
||||||
Corefile:
|
Corefile:
|
||||||
file: Corefile
|
file: Corefile
|
||||||
name: Corefile-v7
|
name: Corefile-v2
|
||||||
Caddyfile:
|
Caddyfile:
|
||||||
file: Caddyfile
|
file: Caddyfile
|
||||||
name: Caddyfile-v145
|
name: Caddyfile-v80
|
||||||
portal.json:
|
index.html:
|
||||||
file: portal.json
|
file: www/index.html
|
||||||
name: portal.json-v6
|
name: index.html-v32
|
||||||
deergrove.png:
|
index.mjs:
|
||||||
file: www/deergrove.png
|
file: www/index.mjs
|
||||||
name: deergrove.png-v1
|
name: index.mjs-v1
|
||||||
netdata.conf:
|
index.css:
|
||||||
file: netdata.conf
|
file: www/index.css
|
||||||
name: netdata.conf-v1
|
name: index.css-v1
|
||||||
gitea-robots.txt:
|
browser.html:
|
||||||
file: gitea-robots.txt
|
file: www/browser.html
|
||||||
name: gitea-robots.txt-v1
|
name: browser.html-v3
|
||||||
|
|
||||||
secrets:
|
secrets:
|
||||||
passwd:
|
passwd:
|
||||||
|
@ -369,24 +302,6 @@ 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:
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"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,363 +1,47 @@
|
||||||
version: "3.8"
|
version: "3.8"
|
||||||
services:
|
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:
|
jellyfin:
|
||||||
image: jellyfin/jellyfin
|
image: ghcr.io/linuxserver/jellyfin:10.7.7
|
||||||
|
ports:
|
||||||
|
- target: 8096
|
||||||
|
published: 8096
|
||||||
|
- target: 7359
|
||||||
|
published: 7359
|
||||||
|
protocol: udp
|
||||||
|
- target: 1900
|
||||||
|
published: 1900
|
||||||
|
protocol: udp
|
||||||
environment:
|
environment:
|
||||||
TZ: US/Mountain
|
TZ: US/Mountain
|
||||||
volumes:
|
volumes:
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /srv/sys/jellyfin/config
|
source: /mnt/ext/srv/jellyfin
|
||||||
target: /config
|
target: /config
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /srv/sys/jellyfin/cache
|
source: /media
|
||||||
target: /cache
|
target: /media
|
||||||
- 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
|
||||||
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
|
- type: bind
|
||||||
source: /srv
|
source: /dev/video10
|
||||||
target: /data
|
target: /dev/video10
|
||||||
configs:
|
|
||||||
- source: dave.yaml
|
|
||||||
target: /config/config.yaml
|
|
||||||
user: "911:911"
|
|
||||||
|
|
||||||
ddns:
|
|
||||||
image: qmcgaw/ddns-updater
|
|
||||||
dns:
|
|
||||||
- 1.1.1.1
|
|
||||||
volumes:
|
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /srv/sys/ddns-updater
|
source: /dev/video11
|
||||||
target: /updater/data
|
target: /dev/video11
|
||||||
|
- type: bind
|
||||||
tunnel:
|
source: /dev/video12
|
||||||
deploy:
|
target: /dev/video12
|
||||||
replicas: 0
|
- type: bind
|
||||||
image: lscr.io/linuxserver/openssh-server
|
source: /dev/video13
|
||||||
user: abc
|
target: /dev/video13
|
||||||
entrypoint:
|
- type: bind
|
||||||
- /usr/bin/ssh
|
source: /dev/video14
|
||||||
- -N
|
target: /dev/video14
|
||||||
- -R 172.17.0.1:5880:caddy:80 # 172.17.0.1 = docker host IP
|
- type: bind
|
||||||
- -R :5822:host.docker.internal:22
|
source: /dev/video15
|
||||||
- -o ServerAliveInterval=30
|
target: /dev/video15
|
||||||
- core@melville.woozle.org
|
- type: bind
|
||||||
extra_hosts:
|
source: /dev/video16
|
||||||
- host.docker.internal:host-gateway
|
target: /dev/video16
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
<!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.
Before 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[data-no-menu] {
|
nav a[target] {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
nav a:hover {
|
nav a:hover {
|
||||||
|
|
|
@ -4,12 +4,29 @@
|
||||||
<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="deergrove.png">
|
<link rel="icon" href="icons/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,5 +1,8 @@
|
||||||
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
|
||||||
|
@ -46,7 +49,7 @@ function frameLoaded(frame) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let defaultIcon = null
|
let defaultIcon = null
|
||||||
async function init() {
|
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
|
||||||
|
@ -65,40 +68,22 @@ async 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")
|
||||||
|
|
||||||
let portalURL = new URL("portal.json", window.location)
|
for (let link of document.querySelectorAll("nav a")) {
|
||||||
let resp = await fetch(portalURL)
|
let dlink = icons.appendChild(link.cloneNode(true))
|
||||||
let obj = await resp.json()
|
dlink.textContent = ""
|
||||||
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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let dlink = icons.appendChild(doc.createElement("a"))
|
if (link.dataset.icon) {
|
||||||
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 = app.icon
|
icon.src = link.dataset.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 = app.title
|
text.textContent = link.textContent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make both of them update the selected tab
|
||||||
|
link.addEventListener("click", event => activate(event, link))
|
||||||
|
dlink.addEventListener("click", event => activate(event, link))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,6 @@ 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-v11
|
name: Caddyfile-v9
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue