docker compose update mediahost

This commit is contained in:
lucas committed 2026-10-01 14:07:55 +00:00
1 parent 72fe77f040
commit 0e45389c60
27 files changed
+2029

No files matched your search

@@ -0,0 +1,26 @@
services:
audiobookshelf:
image: ghcr.io/advplyr/audiobookshelf:latest
container_name: audiobookshelf
restart: unless-stopped
ports:
- "13378:80"
volumes:
- /data/audiobookshelf/data/audiobooks-englisch:/audiobooks
- /data/audiobookshelf//data/audiobooks-deutsch:/audiobooks-deutsch
- /data/audiobookshelf/data/audiobooks-kinder:/audiobooks-kinder
- /data/audiobookshelf/data/podcasts:/podcasts
- /docker/audiobookshelf/config:/config
- /docker/audiobookshelf/metadata:/metadata
networks:
- shared-proxy-services
- default
networks:
default:
external: true
name: mediarr-services
shared-proxy-services:
external: true
@@ -0,0 +1,89 @@
services:
postgresql:
image: docker.io/library/postgres:16
restart: unless-stopped
environment:
POSTGRES_PASSWORD: authentik
POSTGRES_USER: authentik
POSTGRES_DB: authentik
volumes:
- database:/var/lib/postgresql/data
server:
image: ghcr.io/goauthentik/server:2026.8
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_REDIS__PASSWORD: PerCent7heStorySp0tInOrd3r
AUTHENTIK_REDIS__DB: 0
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: authentik
AUTHENTIK_SECRET_KEY: "/jpOrfgtWEoLukXgpqC0JQWgmKUqyu5dG+oUwawVsLs83Wl5dC+nALtsosyrnBAIyWefKKQMcET2yy1RwhZO5w=="
AUTHENTIK_EMAIL__HOST: smtp.web.de
AUTHENTIK_EMAIL__PORT: 587
AUTHENTIK_EMAIL__USERNAME: "ll_m@web.de"
AUTHENTIK_EMAIL__PASSWORD: "Mira2012"
AUTHENTIK_EMAIL__USE_TLS: true
AUTHENTIK_EMAIL__USE_SSL: false
AUTHENTIK_EMAIL__TIMEOUT: 30
AUTHENTIK_EMAIL__FROM: "ll_m@web.de"
ports:
- "9000:9000"
- "9443:9443"
depends_on:
- postgresql
volumes:
- media:/media
- custom-templates:/templates
networks:
- shared-proxy-services
- default
worker:
image: ghcr.io/goauthentik/server:2026.8
restart: unless-stopped
command: worker
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_REDIS__PASSWORD: PerCent7heStorySp0tInOrd3r
AUTHENTIK_REDIS__DB: 0
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: authentik
AUTHENTIK_SECRET_KEY: "/jpOrfgtWEoLukXgpqC0JQWgmKUqyu5dG+oUwawVsLs83Wl5dC+nALtsosyrnBAIyWefKKQMcET2yy1RwhZO5w=="
AUTHENTIK_EMAIL__HOST: smtp.web.de
AUTHENTIK_EMAIL__PORT: 587
AUTHENTIK_EMAIL__USERNAME: "ll_m@web.de"
AUTHENTIK_EMAIL__PASSWORD: "Mira2012"
AUTHENTIK_EMAIL__USE_TLS: true
AUTHENTIK_EMAIL__USE_SSL: false
AUTHENTIK_EMAIL__TIMEOUT: 30
AUTHENTIK_EMAIL__FROM: "ll_m@web.de"
depends_on:
- postgresql
volumes:
- media:/media
- certificates:/certificates
- custom-templates:/templates
networks:
- shared-proxy-services
- default
volumes:
database:
redis:
media:
certificates:
custom-templates:
networks:
default:
external: true
name: shared-redis-services
shared-proxy-services:
external: true
@@ -0,0 +1,33 @@
services:
diun:
image: crazymax/diun:latest
container_name: diun
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data:/data
environment:
TZ: Europe/Vienna
# General
DIUN_WATCH_WORKERS: 20
DIUN_WATCH_SCHEDULE: "0 0 * * *"
DIUN_PROVIDERS_DOCKER: "true"
DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT: "true"
# Email notifications
DIUN_NOTIF_MAIL_HOST: smtp.web.de
DIUN_NOTIF_MAIL_PORT: 587
DIUN_NOTIF_MAIL_USERNAME: ll_m@web.de
DIUN_NOTIF_MAIL_PASSWORD: Mira2012
DIUN_NOTIF_MAIL_FROM: ll_m@web.de
DIUN_NOTIF_MAIL_TO: ll_m@web.de
DIUN_NOTIF_MAIL_INSECURESKIPVERIFY: "false"
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
@@ -0,0 +1,19 @@
services:
gitea:
image: gitea/gitea:latest
container_name: gitea
restart: always
environment:
USER_UID: 1000
USER_GID: 1000
ports:
- "3001:3000"
- "2222:22"
volumes:
- /data/gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
@@ -0,0 +1,23 @@
services:
homeassistant:
container_name: homeassistant
image: ghcr.io/home-assistant/home-assistant:stable
restart: unless-stopped
privileged: true
network_mode: host
environment:
TZ: Europe/Vienna
volumes:
- /srv/homeassistant:/config
mosquitto:
container_name: mosquitto
image: eclipse-mosquitto:latest
restart: unless-stopped
ports:
- "1883:1883"
- "9001:9001"
volumes:
- ./mosquitto/config:/mosquitto/config
- ./mosquitto/data:/mosquitto/data
- ./mosquitto/log:/mosquitto/log
@@ -0,0 +1,37 @@
services:
jellyfin:
image: jellyfin/jellyfin
container_name: jellyfin
volumes:
- /docker/jellyfin/config:/config
- /docker/jellyfin/cache:/cache
- /data/jellyfin/media:/media
restart: unless-stopped
ports:
- "8096:8096"
environment:
- TZ=Europe/Berlin
networks:
- default
- shared-proxy-services
seerr:
image: ghcr.io/seerr-team/seerr:latest
container_name: seerr
restart: unless-stopped
ports:
- "5055:5055"
volumes:
- /docker/jellyfin/seerr:/app/config
environment:
TZ: Europe/Berlin
networks:
- default
- shared-proxy-services
networks:
default:
external: true
name: mediarr-services
shared-proxy-services:
external: true
@@ -0,0 +1,8 @@
#!/usr/bin/with-contenv bash
echo "Creating /buffer..."
mkdir -p /buffer
chown -R abc:users /buffer
chmod 775 /buffer
@@ -0,0 +1,276 @@
services:
sonarr-en:
image: lscr.io/linuxserver/sonarr:latest
container_name: sonarr-en
restart: unless-stopped
ports:
- "8989:8989"
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Berlin
volumes:
- ./sonarr_EN:/config
- /data/jellyfin/media/series-english:/JellyfinSeriesEnglish
- /data/jellyfin/media/anime-english:/JellyfinAnimeEnglish
- /data/jellyfin/media/documentaries-english:/JellyfinDocus
- /data/jellyfin/buffer:/buffer
- /torrent/qbittorrent/downloads:/downloads
sonarr-de:
image: lscr.io/linuxserver/sonarr:latest
container_name: sonarr-de
restart: unless-stopped
ports:
- "8990:8989"
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Berlin
volumes:
- ./sonarr_DE:/config
- /data/jellyfin/media/series-german:/JellyfinSeriesGerman
- /data/jellyfin/media/anime-german:/JellyfinAnimeGerman
- /data/jellyfin/media/series-kids:/JellyfinKinder
- /data/jellyfin/buffer:/buffer
- /torrent/qbittorrent/downloads:/downloads
- /torrent/rundfunkarr:/downloads-rundfunkarr
radarr-en:
image: lscr.io/linuxserver/radarr:latest
container_name: radarr-en
restart: unless-stopped
ports:
- "7878:7878"
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Berlin
volumes:
- ./radarr_EN:/config
- /data/jellyfin/media/movies-english:/JellyfinMoviesEnglish
- /data/jellyfin/media/comedy-english:/JellyfinComedy
- /torrent/qbittorrent/downloads:/downloads
- /data/jellyfin/buffer:/buffer
radarr-de:
image: lscr.io/linuxserver/radarr:latest
container_name: radarr-de
restart: unless-stopped
ports:
- "7879:7878"
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Berlin
volumes:
- ./radarr_DE:/config
- /data/jellyfin/media/movies-german:/JellyfinMoviesGerman
- /data/jellyfin/media/movies-kids:/JellyfinKinder
- /data/jellyfin/buffer:/buffer
- /torrent/qbittorrent/downloads:/downloads
- /torrent/rundfunkarr:/downloads-rundfunkarr
prowlarr:
image: lscr.io/linuxserver/prowlarr:latest
container_name: prowlarr
restart: unless-stopped
ports:
- "9696:9696"
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Vienna
volumes:
- ./prowlarr:/config
gluetun-rundfunkarr-de:
image: qmcgaw/gluetun
container_name: gluetun-rundfunkarr-de
cap_add:
- NET_ADMIN
restart: unless-stopped
volumes:
- ./gluetun-de:/gluetun/wireguard
environment:
- VPN_SERVICE_PROVIDER=custom
- VPN_TYPE=wireguard
ports:
- "6767:6767" # Rundfunkarr UI
rundfunkarr-de:
image: ghcr.io/rundfunkarr/rundfunkarr:latest
container_name: rundfunkarr-de
environment:
- TZ=Europe/Berlin
- PUID=1000 # User ID (id -u)
- PGID=1000 # Group ID (id -g)
- DOWNLOAD_FOLDER_PATH=/downloads-rundfunkarr
volumes:
- ./rundfunkarr-de:/app/prisma/data
- /torrent/rundfunkarr-de:/downloads-rundfunkarr
# ports:
# - 6767:6767
restart: unless-stopped
network_mode: "service:gluetun-rundfunkarr-de"
depends_on:
- gluetun-rundfunkarr-de
gluetun-at:
image: qmcgaw/gluetun:latest
container_name: gluetun-at
restart: unless-stopped
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
ports:
- "8888:8888" # HTTP Proxy
- "1080:1080" # SOCKS5 Proxy
environment:
- VPN_SERVICE_PROVIDER=custom
- VPN_TYPE=wireguard
- SOCKS5_ENABLED=on
- HTTPPROXY=on
- SOCKSPROXY=on
- TZ=Europe/Vienna
volumes:
- ./gluetun-at:/gluetun/wireguard
# lazylibrarian:
# image: lscr.io/linuxserver/lazylibrarian:latest
# container_name: lazylibrarian
# restart: unless-stopped
# environment:
# - PUID=1000
# - PGID=1000
# - TZ=Europe/Vienna
# ports:
# - "5299:5299"
# volumes:
# - ./lazylibrarian:/config
# - /data/audiobookshelf/podcasts:/podcasts
# - /data/audiobookshelf/audiobooks-englisch:/audiobooks
# - /torrent/qbittorrent/downloads:/downloads
flaresolverr:
image: ghcr.io/flaresolverr/flaresolverr:latest
container_name: flaresolverr
restart: unless-stopped
environment:
- LOG_LEVEL=info
- LOG_HTML=false
- CAPTCHA_SOLVER=none
- TZ=Europe/Vienna
ports:
- "8191:8191"
lidarr:
image: lscr.io/linuxserver/lidarr:latest
container_name: lidarr
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Berlin
volumes:
- ./lidarr:/config
- /data/navidrome/music:/music
- /torrent/qbittorrent/downloads:/downloads
ports:
- 8686:8686
restart: unless-stopped
umlautadaptarr:
image: pcjones/umlautadaptarr:latest
restart: unless-stopped
container_name: umlautadaptarr
ports:
- "5006:5006" # can be removed if you use the recommended prowlarr+proxy configuration
environment:
- TZ=Europe/Berlin
- SONARR_0_ENABLED=true
- SONARR_0_HOST=http://sonarr-en:8989
- SONARR_0_APIKEY=e2005c5c204840878f8eb37d1ac6aa0e
- RADARR_0_ENABLED=true
- RADARR_0_HOST=http://radar-en:7878
- RADARR_0_APIKEY=4332aee075c748f2acee41aa26f06007
- SONARR_1_ENABLED=true
- SONARR_1_HOST=http://sonarr-de:8990
- SONARR_1_APIKEY=707d4fcbb3d74822ba990c6a8b7278e9
- RADARR_1_ENABLED=true
- RADARR_1_HOST=http://radarr-de:7879
- RADARR_1_APIKEY=29f67f0ac8894357b22ea3f7fc1abfdf
- LIDARR__ENABLED=true
- LIDARR__HOST=http://lidarr:8686
- LIDARR__APIKEY=bb41cbf2b17e439290f90ecfaeb24dff
recyclarr:
image: ghcr.io/recyclarr/recyclarr:8
container_name: recyclarr
user: 1000:1000
restart: unless-stopped
environment:
- TZ=Europe/Berlin
volumes:
- ./recyclarr:/config
listenarr:
image: ghcr.io/listenarrs/listenarr:canary
container_name: listenarr
ports:
- "4545:4545"
environment:
- PUID=1000
- PGID=1000
- UMASK=022
# - LISTENARR_PUBLIC_URL=https://your-domain.com ## OPTIONAL: Used by Discord Bot
volumes:
- ./listenarr:/app/config
- /data/audiobookshelf/data/audiobooks-englisch:/audiobooks-english
- /data/audiobookshelf/data/audiobooks-deutsch:/audiobooks-german
- /data/audiobookshelf/data/audiobooks-kinder:/audiobooks-kinder
- /torrent/qbittorrent/downloads:/downloads
restart: unless-stopped
upload-assistant:
image: ghcr.io/audionut/upload-assistant:latest
container_name: upload-assistant
restart: unless-stopped
ports:
- "5000:5000"
environment:
- PUID=1000
- PGID=1000
# Paths visible in the file browser
- UA_BROWSE_ROOTS=/downloads,/data
command: ["--webui", "0.0.0.0:5000"]
volumes:
- ./upload-assistant:/Upload-Assistant/data
# Sonarr/Radarr libraries
- /data/jellyfin/media/series-english:/data/series-english:ro
- /data/jellyfin/media/anime-english:/data/anime-english:ro
- /data/jellyfin/media/documentaries-english:/docus-english:ro
- /data/jellyfin/media/series-german:/series-german:ro
- /data/jellyfin/media/anime-german:/anime-german:ro
- /data/jellyfin/media/series-kids:/series-kids:ro
- /data/jellyfin/media/movies-english:/data/movies-english:ro
- /data/jellyfin/media/comedy-english:/data/comedy-english:ro
- /data/jellyfin/media/movies-german:/data/movies-german:ro
- /data/jellyfin/media/movies-kids:/data/movies-kids:ro
# - /data/audiobookshelf/podcasts:/podcasts
# - /data/audiobookshelf/audiobooks-englisch:/audiobooks
- /data/navidrome/music:/data/music:ro
- /data/audiobookshelf/data/audiobooks-englisch:/data/audiobooks-english:ro
- /data/audiobookshelf/data/audiobooks-deutsch:/data/audiobooks-german:ro
- /data/audiobookshelf/data/audiobooks-kinder:/data/audiobooks-kinder:ro
# Download location
- /torrent/qbittorrent/downloads:/downloads
networks:
default:
external: true
name: mediarr-services
@@ -0,0 +1,11 @@
#
# Use this configuration with WireGuard client
#
[Interface]
Address = 10.14.0.2/16
PrivateKey = mKeDQdxtM1iFJS7WLlb2jPGabZIt3NkoA/nGCcNOU1I=
DNS = 162.252.172.57, 149.154.159.92
[Peer]
PublicKey = dPZe8Jq3Hu0k07MDk+Y4+AS2XHSLYalyg91TSFXRYEA=
AllowedIPs = 0.0.0.0/0
Endpoint = 87.249.133.4:51820
@@ -0,0 +1,11 @@
#
# Use this configuration with WireGuard client
#
[Interface]
Address = 10.14.0.2/16
PrivateKey = mKeDQdxtM1iFJS7WLlb2jPGabZIt3NkoA/nGCcNOU1I=
DNS = 162.252.172.57, 149.154.159.92
[Peer]
PublicKey = d3ldwEjnFcbLwD1o8uC5xC3DaSNek8DGeTpOb/h/IE4=
AllowedIPs = 0.0.0.0/0
Endpoint = 86.38.98.8:51820
@@ -0,0 +1,9 @@
# secrets.yml
sonarr_en_url: http://sonarr-en:8989
sonarr_en_apikey: e2005c5c204840878f8eb37d1ac6aa0e
radarr_en_url: http://radarr-en:7878
radarr_en_apikey: 4332aee075c748f2acee41aa26f06007
sonarr_de_url: http://sonarr-de:8989
sonarr_de_apikey: 707d4fcbb3d74822ba990c6a8b7278e9
radarr_de_url: http://radarr-de:7878
radarr_de_apikey: 29f67f0ac8894357b22ea3f7fc1abfdf
@@ -0,0 +1,5 @@
# yaml-language-server: $schema=https://schemas.recyclarr.dev/latest/settings-schema.json
# Edit this file to customize the behavior of Recyclarr beyond its defaults
# For the settings file reference guide, visit the link to the wiki below:
# https://recyclarr.dev/reference/settings/
@@ -0,0 +1,2 @@
sed -i 's/speed:a/speed:BigInt(Math.round(a))/g' /app/.next/server/chunks/*.js
sed -i 's/speed,/speed: BigInt(Math.round(speed)),/' /app/src/server/download-manager.ts
@@ -0,0 +1,70 @@
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus-data:/prometheus
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
ports:
- "3000:3000"
environment:
GF_SECURITY_ADMIN_USER: lucas
GF_SECURITY_ADMIN_PASSWORD: Mira2012
GF_SMTP_ENABLED: "true"
GF_SMTP_HOST: "smtp.web.de:587"
GF_SMTP_USER: "ll_m@web.de"
GF_SMTP_PASSWORD: "Mira2012"
GF_SMTP_FROM_ADDRESS: "ll_m@web.de"
GF_SMTP_FROM_NAME: "Grafana"
GF_SMTP_SKIP_VERIFY: "false"
GF_SERVER_ROOT_URL: https://status.someoneslinux.selfhost.eu
GF_SERVER_PROTOCOL: http
volumes:
- grafana-data:/var/lib/grafana
- ./grafana/provisioning/datasources:/etc/grafana/provisioning/datasources
- ./grafana/provisioning/dashboards:/etc/grafana/provisioning/dashboards
- ./grafana/provisioning/dashboards/imported:/var/lib/grafana/dashboards
networks:
- default
- shared-proxy-services
node-exporter:
container_name: node-exporter
image: prom/node-exporter:latest
restart: unless-stopped
pid: host
command:
- '--path.rootfs=/host'
- '--collector.textfile.directory=/textfile'
volumes:
- '/:/host:ro,rslave'
- ./node_exporter/textfile_collector:/textfile:ro
ports:
- '9100:9100'
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /data:/data:ro
- /docker:/docker:ro
volumes:
prometheus-data:
grafana-data:
networks:
default:
shared-proxy-services:
external: true
@@ -0,0 +1,37 @@
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets:
- "prometheus:9090"
- job_name: "node-exporter"
static_configs:
- targets:
- "192.168.0.2:9100"
labels:
host: serverhost
- targets:
- "node-exporter:9100"
labels:
host: "mediahost"
- job_name: "cadvisor"
static_configs:
- targets:
- "cadvisor:8080"
- job_name: "smartctl"
static_configs:
- targets:
- "192.168.0.2:9633"
labels:
host: serverhost
- targets:
- "192.168.0.4:9633"
labels:
host: "mediahost"
+34
View File
@@ -0,0 +1,34 @@
services:
navidrome:
image: deluan/navidrome:latest
container_name: navidrome
restart: unless-stopped
ports:
- "4533:4533"
environment:
ND_SCANSCHEDULE: 1h
ND_LOGLEVEL: info
ND_SESSIONTIMEOUT: 24h
ND_MUSICFOLDER: /music
ND_DATAFOLDER: /data
ND_SCANNER_PURGEMISSING: always
volumes:
- /data/navidrome/data:/data
- /data/navidrome/music/music:/music:ro
- /data/navidrome/music/kinder:/kinder:ro
- /data/navidrome/music/kamerun:/kamerun:ro
- /data/navidrome/music/weihnachten:/weihnachten:ro
- /data/navidrome/music/playlists:/playlists:ro
networks:
- shared-proxy-services
- default
networks:
default:
shared-proxy-services:
external: true
@@ -0,0 +1,172 @@
(
echo "============================================================"
echo "NEXTCLOUD DIAGNOSTIC"
echo "Date: $(date)"
echo "============================================================"
echo
run() {
echo
echo "============================================================"
echo "COMMAND:"
echo "$*"
echo "============================================================"
"$@" 2>&1
echo
echo "EXIT CODE: $?"
}
echo "### 1. Docker containers"
run docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Image}}'
echo "### 2. Nextcloud status"
run docker exec nextcloud php occ status
echo "### 3. Effective Nextcloud configuration"
echo 'COMMAND: docker exec nextcloud php -r ...'
docker exec nextcloud php -r '
$CONFIG = [];
include "/var/www/html/config/config.php";
if (file_exists("/var/www/html/config/zz-docker-env.config.php")) {
include "/var/www/html/config/zz-docker-env.config.php";
}
echo "dbtype: " . ($CONFIG["dbtype"] ?? "MISSING") . PHP_EOL;
echo "dbhost: " . ($CONFIG["dbhost"] ?? "MISSING") . PHP_EOL;
echo "dbname: " . ($CONFIG["dbname"] ?? "MISSING") . PHP_EOL;
echo "dbuser: " . ($CONFIG["dbuser"] ?? "MISSING") . PHP_EOL;
echo "dbpassword: " . (empty($CONFIG["dbpassword"] ?? "") ? "EMPTY" : "SET") . PHP_EOL;
echo "instanceid: " . ($CONFIG["instanceid"] ?? "MISSING") . PHP_EOL;
echo "version: " . ($CONFIG["version"] ?? "MISSING") . PHP_EOL;
echo "datadirectory: " . ($CONFIG["datadirectory"] ?? "MISSING") . PHP_EOL;
echo "overwrite.cli.url: " . ($CONFIG["overwrite.cli.url"] ?? "MISSING") . PHP_EOL;
echo "overwriteprotocol: " . ($CONFIG["overwriteprotocol"] ?? "MISSING") . PHP_EOL;
echo "redis.host: " . ($CONFIG["redis"]["host"] ?? "MISSING") . PHP_EOL;
echo "redis.password: " . (empty($CONFIG["redis"]["password"] ?? "") ? "EMPTY" : "SET") . PHP_EOL;
echo "trusted_domains:" . PHP_EOL;
foreach (($CONFIG["trusted_domains"] ?? []) as $domain) {
echo " - " . $domain . PHP_EOL;
}
echo "trusted_proxies:" . PHP_EOL;
foreach (($CONFIG["trusted_proxies"] ?? []) as $proxy) {
echo " - " . $proxy . PHP_EOL;
}
' 2>&1
echo "EXIT CODE: $?"
echo
echo "### 4. Test MariaDB connection"
echo 'COMMAND: docker exec nextcloud php -r ...'
docker exec nextcloud php -r '
$CONFIG = [];
include "/var/www/html/config/config.php";
if (file_exists("/var/www/html/config/zz-docker-env.config.php")) {
include "/var/www/html/config/zz-docker-env.config.php";
}
try {
$dsn = "mysql:host=" . $CONFIG["dbhost"] .
";dbname=" . $CONFIG["dbname"];
$pdo = new PDO(
$dsn,
$CONFIG["dbuser"],
$CONFIG["dbpassword"],
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]
);
echo "PASS: MariaDB connection works" . PHP_EOL;
} catch (Throwable $e) {
echo "FAIL: MariaDB connection failed" . PHP_EOL;
echo $e->getMessage() . PHP_EOL;
}
' 2>&1
echo "EXIT CODE: $?"
echo
echo "### 5. Nextcloud config directory"
run docker exec nextcloud ls -la /var/www/html/config
echo "### 6. Nextcloud root directory"
run docker exec nextcloud ls -la /var/www/html
echo "### 7. Nextcloud data directory"
run docker exec nextcloud sh -c 'ls -ld /var/www/html/data && ls -la /var/www/html/data | head -30'
echo "### 8. Config.php syntax"
run docker exec nextcloud php -l /var/www/html/config/config.php
echo "### 9. zz-docker-env.config.php syntax"
run docker exec nextcloud php -l /var/www/html/config/zz-docker-env.config.php
echo "### 10. Docker environment"
echo 'COMMAND: docker exec nextcloud env'
docker exec nextcloud env 2>&1 |
sed -E \
-e 's/(MYSQL_PASSWORD=).*/\1[REDACTED]/' \
-e 's/(MYSQL_ROOT_PASSWORD=).*/\1[REDACTED]/' \
-e 's/(REDIS_PASSWORD=).*/\1[REDACTED]/' \
-e 's/(NEXTCLOUD_ADMIN_PASSWORD=).*/\1[REDACTED]/'
echo "EXIT CODE: ${PIPESTATUS[0]}"
echo "### 11. Nextcloud container logs"
run docker logs --tail 20 nextcloud
echo "### 12. MariaDB container logs"
run docker logs --tail 20 nextcloud-db
echo "### 13. Nextcloud application log"
echo 'COMMAND: docker exec nextcloud sh -c ...'
docker exec nextcloud sh -c '
if [ -f /var/www/html/data/nextcloud.log ]; then
tail -2 /var/www/html/data/nextcloud.log
else
echo "nextcloud.log not found"
fi
' 2>&1
echo "EXIT CODE: $?"
echo "### 14. Network"
run docker inspect nextcloud --format '{{json .NetworkSettings.Networks}}'
echo "### 15. Database network"
run docker inspect nextcloud-db --format '{{json .NetworkSettings.Networks}}'
echo "### 16. Docker Compose configuration"
echo 'COMMAND: docker compose config'
docker compose config 2>&1 |
sed -E \
-e 's/(MYSQL_PASSWORD:).*/\1 [REDACTED]/' \
-e 's/(MYSQL_ROOT_PASSWORD:).*/\1 [REDACTED]/' \
-e 's/(REDIS_PASSWORD:).*/\1 [REDACTED]/' \
-e 's/(NEXTCLOUD_ADMIN_PASSWORD:).*/\1 [REDACTED]/'
echo "### 17. Disk space"
run df -h
echo "### 18. Docker volumes/mounts"
echo 'COMMAND: docker inspect nextcloud --format ...'
docker inspect nextcloud \
--format '{{range .Mounts}}{{println .Source "->" .Destination}}{{end}}' \
2>&1
echo
echo "============================================================"
echo "END OF DIAGNOSTIC"
echo "============================================================"
) 2>&1 | tee nextcloud-diagnostic.txt
echo
echo "Diagnostic saved to:"
echo " $(pwd)/nextcloud-diagnostic.txt"
@@ -0,0 +1,109 @@
services:
nextcloud:
image: nextcloud:latest
container_name: nextcloud
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
# PHP
- PHP_UPLOAD_LIMIT=16G
# APACHE2
- APACHE_BODY_LIMIT=0
# MYSQL
- MYSQL_HOST=db
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
# REDIS
- REDIS_HOST=redis
- REDIS_HOST_PASSWORD=${REDIS_PASSWORD}
# NEXTCLOUD
- NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER}
- NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD}
- NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_DOMAIN} 192.168.0.4
- NEXTCLOUD_MIMI_PASSWORD=${NEXTCLOUD_MIMI_PASSWORD}
- OVERWRITEPROTOCOL=https
- OVERWRITECLIURL=https://${NEXTCLOUD_DOMAIN}
- OVERWRITEHOST=${NEXTCLOUD_DOMAIN}
- TRUSTED_PROXIES=nginx 172.16.0.0/12
# SMTP
- SMTP_HOST=${SMTP_HOST}
- SMTP_PORT=${SMTP_PORT}
- SMTP_SECURE=${SMTP_SECURE}
- SMTP_USER=${SMTP_USER}
- SMTP_PASSWORD=${SMTP_PASSWORD}
- SMTP_FROM_ADDRESS=${SMTP_FROM_ADDRESS}
- SMTP_FROM_DOMAIN=${SMTP_FROM_DOMAIN}
# Collabora
- COLLABORA_DOMAIN=${COLLABORA_DOMAIN}
- LUCAS_EMAIL=${LUCAS_EMAIL}
volumes:
- ./html:/var/www/html
- /data/nextcloud/data:/var/www/html/data
# Post-installation hooks
- ./hooks/nextcloud-init.sh:/docker-entrypoint-hooks.d/post-installation/nextcloud-init.sh:ro
ports:
- "8082:80"
networks:
- default
- shared-proxy-services
- shared-redis-services
db:
image: mariadb:11
container_name: nextcloud-db
restart: unless-stopped
command:
- --transaction-isolation=READ-COMMITTED
- --log-bin=binlog
- --binlog-format=ROW
- --slow-query-log=ON
- --slow-query-log-file=/var/lib/mysql/slow-query.log
- --long-query-time=2
- --innodb-log-file-size=256M
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
volumes:
- ./db:/var/lib/mysql
healthcheck:
test:
[
"CMD-SHELL",
"healthcheck.sh --connect --innodb_initialized"
]
interval: 10s
timeout: 5s
retries: 10
start_period: 30s
collabora:
image: collabora/code
expose:
- 9980
cap_add:
- MKNOD
environment:
- domain=${NEXTCLOUD_DOMAIN}
- VIRTUAL_HOST=${COLLABORA_DOMAIN}
- VIRTUAL_PORT=9980
- VIRTUAL_PROTO=https
- LETSENCRYPT_HOST=${COLLABORA_DOMAIN}
- LETSENCRYPT_EMAIL=${LUCAS_EMAIL}
networks:
- shared-proxy-services
restart: always
networks:
default:
driver: bridge
shared-redis-services:
external: true
shared-proxy-services:
external: true
@@ -0,0 +1,515 @@
#!/usr/bin/env bash
set -Eeuo pipefail
CONTAINER="nextcloud"
OVERRIDE="/var/www/html/config/zz-docker-env.config.php"
FIX=false
if [[ "${1:-}" == "--fix" ]]; then
FIX=true
fi
PASS=0
FAIL=0
pass() {
echo "PASS: $1"
PASS=$((PASS + 1))
}
fail() {
echo "FAIL: $1"
FAIL=$((FAIL + 1))
}
# ============================================================
# Basic checks
# ============================================================
echo "=========================================="
echo " Nextcloud Docker configuration checker"
echo "=========================================="
echo
if ! docker inspect "$CONTAINER" >/dev/null 2>&1; then
echo "FAIL: Docker container '$CONTAINER' does not exist"
exit 1
fi
if [[ "$(docker inspect -f '{{.State.Running}}' "$CONTAINER")" != "true" ]]; then
echo "FAIL: Docker container '$CONTAINER' is not running"
exit 1
fi
if [[ ! -f ".env" ]]; then
echo "FAIL: .env not found"
exit 1
fi
# ============================================================
# Read .env
# ============================================================
declare -A ENV
while IFS='=' read -r key value; do
key="${key//$'\r'/}"
value="${value//$'\r'/}"
# Ignore empty lines
[[ -z "${key// /}" ]] && continue
# Ignore comments
[[ "$key" =~ ^[[:space:]]*# ]] && continue
# Trim whitespace
key="${key#"${key%%[![:space:]]*}"}"
key="${key%"${key##*[![:space:]]}"}"
# Remove "export "
key="${key#export }"
# Remove quotes
value="${value#\"}"
value="${value%\"}"
value="${value#\'}"
value="${value%\'}"
ENV["$key"]="$value"
done < .env
MYSQL_PASSWORD="${ENV[MYSQL_PASSWORD]:-}"
MYSQL_ROOT_PASSWORD="${ENV[MYSQL_ROOT_PASSWORD]:-}"
REDIS_PASSWORD="${ENV[REDIS_PASSWORD]:-}"
NEXTCLOUD_ADMIN_USER="${ENV[NEXTCLOUD_ADMIN_USER]:-}"
NEXTCLOUD_ADMIN_PASSWORD="${ENV[NEXTCLOUD_ADMIN_PASSWORD]:-}"
NEXTCLOUD_DOMAIN="${ENV[NEXTCLOUD_DOMAIN]:-}"
# ============================================================
# Environment checks
# ============================================================
echo "Checking .env variables"
echo "-----------------------"
for name in \
MYSQL_PASSWORD \
MYSQL_ROOT_PASSWORD \
REDIS_PASSWORD \
NEXTCLOUD_ADMIN_USER \
NEXTCLOUD_ADMIN_PASSWORD \
NEXTCLOUD_DOMAIN
do
if [[ -n "${ENV[$name]:-}" ]]; then
pass "$name is defined"
else
fail "$name is missing"
fi
done
echo
# ============================================================
# Read config.php
#
# PHP runs ONLY inside Docker.
# No PHP is required on the host.
# ============================================================
CONFIG_JSON="$(
docker exec "$CONTAINER" php -r '
$CONFIG = [];
include "/var/www/html/config/config.php";
echo json_encode([
"dbhost" =>
$CONFIG["dbhost"] ?? "",
"dbname" =>
$CONFIG["dbname"] ?? "",
"dbuser" =>
$CONFIG["dbuser"] ?? "",
"dbpassword" =>
$CONFIG["dbpassword"] ?? "",
"redis_host" =>
$CONFIG["redis"]["host"] ?? "",
"redis_password" =>
$CONFIG["redis"]["password"] ?? "",
"overwriteprotocol" =>
$CONFIG["overwriteprotocol"] ?? "",
"overwrite_cli_url" =>
$CONFIG["overwrite.cli.url"] ?? "",
"trusted_domains" =>
$CONFIG["trusted_domains"] ?? [],
"trusted_proxies" =>
$CONFIG["trusted_proxies"] ?? []
]);
'
)"
# ============================================================
# Extract configuration
# ============================================================
DB_HOST="$(jq -r '.dbhost' <<< "$CONFIG_JSON")"
DB_NAME="$(jq -r '.dbname' <<< "$CONFIG_JSON")"
DB_USER="$(jq -r '.dbuser' <<< "$CONFIG_JSON")"
DB_PASSWORD="$(jq -r '.dbpassword' <<< "$CONFIG_JSON")"
REDIS_HOST="$(jq -r '.redis_host' <<< "$CONFIG_JSON")"
REDIS_PASSWORD_CONFIG="$(jq -r '.redis_password' <<< "$CONFIG_JSON")"
OVERWRITE_PROTOCOL="$(jq -r '.overwriteprotocol' <<< "$CONFIG_JSON")"
OVERWRITE_CLI_URL="$(jq -r '.overwrite_cli_url' <<< "$CONFIG_JSON")"
# ============================================================
# Database
# ============================================================
echo "Checking database configuration"
echo "-------------------------------"
if [[ "$DB_HOST" == "mariadb" ]]; then
pass "dbhost = mariadb"
else
fail "dbhost: expected mariadb, got $DB_HOST"
fi
if [[ "$DB_NAME" == "nextcloud" ]]; then
pass "dbname = nextcloud"
else
fail "dbname: expected nextcloud, got $DB_NAME"
fi
if [[ "$DB_USER" == "nextcloud" ]]; then
pass "dbuser = nextcloud"
else
fail "dbuser: expected nextcloud, got $DB_USER"
fi
if [[ "$MYSQL_PASSWORD" == "$DB_PASSWORD" ]]; then
pass "dbpassword"
else
fail "dbpassword"
fi
echo
# ============================================================
# Redis
# ============================================================
echo "Checking Redis configuration"
echo "----------------------------"
if [[ "$REDIS_HOST" == "redis" ]]; then
pass "redis host = redis"
else
fail "redis host: expected redis, got $REDIS_HOST"
fi
if [[ "$REDIS_PASSWORD" == "$REDIS_PASSWORD_CONFIG" ]]; then
pass "redis password"
else
fail "redis password"
echo " expected: [hidden]"
echo " actual: [hidden]"
fi
echo
# ============================================================
# URL
# ============================================================
echo "Checking Nextcloud URL configuration"
echo "------------------------------------"
if [[ "$OVERWRITE_PROTOCOL" == "https" ]]; then
pass "overwriteprotocol = https"
else
fail "overwriteprotocol: expected https, got $OVERWRITE_PROTOCOL"
fi
EXPECTED_URL="https://${NEXTCLOUD_DOMAIN}"
if [[ "$OVERWRITE_CLI_URL" == "$EXPECTED_URL" ]]; then
pass "overwrite.cli.url = $EXPECTED_URL"
else
fail "overwrite.cli.url"
echo " expected: $EXPECTED_URL"
echo " actual: $OVERWRITE_CLI_URL"
fi
echo
# ============================================================
# Trusted domains
# ============================================================
echo "Checking trusted domains"
echo "-----------------------"
if jq -e \
--arg domain "$NEXTCLOUD_DOMAIN" \
'.trusted_domains | index($domain) != null' \
<<< "$CONFIG_JSON" >/dev/null
then
pass "trusted_domains contains $NEXTCLOUD_DOMAIN"
else
fail "trusted_domains does not contain $NEXTCLOUD_DOMAIN"
fi
echo
# ============================================================
# Trusted proxies
# ============================================================
echo "Checking trusted proxies"
echo "------------------------"
if jq -e \
'.trusted_proxies | index("172.16.0.0/12") != null' \
<<< "$CONFIG_JSON" >/dev/null
then
pass "trusted_proxies contains 172.16.0.0/12"
else
fail "trusted_proxies does not contain 172.16.0.0/12"
fi
echo
# ============================================================
# FIX
# ============================================================
if [[ "$FIX" == true ]]; then
echo "=========================================="
echo " Fixing Nextcloud configuration"
echo "=========================================="
echo
# --------------------------------------------------------
# Backup existing override
# --------------------------------------------------------
if docker exec "$CONTAINER" test -f "$OVERRIDE"; then
BACKUP="/var/www/html/config/zz-docker-env.config.php.backup.$(date +%Y%m%d-%H%M%S)"
docker exec "$CONTAINER" \
cp "$OVERRIDE" "$BACKUP"
echo "Backup created:"
echo " $BACKUP"
echo
fi
# --------------------------------------------------------
# Generate override INSIDE the container.
#
# Therefore PHP is NOT required on the host.
# --------------------------------------------------------
docker exec \
-e MYSQL_PASSWORD="$MYSQL_PASSWORD" \
-e REDIS_PASSWORD="$REDIS_PASSWORD" \
-e NEXTCLOUD_DOMAIN="$NEXTCLOUD_DOMAIN" \
"$CONTAINER" \
php -r '
$mysql = getenv("MYSQL_PASSWORD");
$redis = getenv("REDIS_PASSWORD");
$domain = getenv("NEXTCLOUD_DOMAIN");
$file = "/var/www/html/config/zz-docker-env.config.php";
$config = "<?php\n\n";
$config .= "\$CONFIG[\"dbhost\"] = "
. var_export("mariadb", true)
. ";\n";
$config .= "\$CONFIG[\"dbname\"] = "
. var_export("nextcloud", true)
. ";\n";
$config .= "\$CONFIG[\"dbuser\"] = "
. var_export("nextcloud", true)
. ";\n";
$config .= "\$CONFIG[\"dbpassword\"] = "
. var_export($mysql, true)
. ";\n\n";
$config .= "\$CONFIG[\"redis\"][\"host\"] = "
. var_export("redis", true)
. ";\n";
$config .= "\$CONFIG[\"redis\"][\"port\"] = 6379;\n";
$config .= "\$CONFIG[\"redis\"][\"password\"] = "
. var_export($redis, true)
. ";\n\n";
$config .= "\$CONFIG[\"overwriteprotocol\"] = "
. var_export("https", true)
. ";\n";
$config .= "\$CONFIG[\"overwrite.cli.url\"] = "
. var_export("https://" . $domain, true)
. ";\n\n";
$config .= "\$CONFIG[\"trusted_domains\"][] = "
. var_export($domain, true)
. ";\n";
$config .= "\$CONFIG[\"trusted_proxies\"][] = "
. var_export("172.16.0.0/12", true)
. ";\n";
file_put_contents($file, $config);
'
# --------------------------------------------------------
# Permissions
# --------------------------------------------------------
docker exec "$CONTAINER" \
chown www-data:www-data "$OVERRIDE"
docker exec "$CONTAINER" \
chmod 640 "$OVERRIDE"
echo "Configuration override written:"
echo " $OVERRIDE"
echo
# --------------------------------------------------------
# Show the file WITHOUT exposing passwords
# --------------------------------------------------------
echo "Configuration written:"
docker exec "$CONTAINER" \
sed -E \
's/(password"\] = ).*/\1"[HIDDEN]";/' \
"$OVERRIDE"
echo
# --------------------------------------------------------
# Verify
# --------------------------------------------------------
echo "=========================================="
echo " Verification"
echo "=========================================="
echo
# Important:
# config.php itself is not modified.
# Nextcloud loads the additional config file.
#
# Re-read effective Nextcloud configuration.
EFFECTIVE_JSON="$(
docker exec "$CONTAINER" php -r '
$CONFIG = [];
include "/var/www/html/config/config.php";
if (file_exists("/var/www/html/config/zz-docker-env.config.php")) {
include "/var/www/html/config/zz-docker-env.config.php";
}
echo json_encode([
"dbhost" => $CONFIG["dbhost"] ?? "",
"dbname" => $CONFIG["dbname"] ?? "",
"dbuser" => $CONFIG["dbuser"] ?? "",
"dbpassword" => $CONFIG["dbpassword"] ?? "",
"redis_host" => $CONFIG["redis"]["host"] ?? "",
"redis_password" => $CONFIG["redis"]["password"] ?? "",
"overwriteprotocol" =>
$CONFIG["overwriteprotocol"] ?? "",
"overwrite_cli_url" =>
$CONFIG["overwrite.cli.url"] ?? "",
"trusted_domains" =>
$CONFIG["trusted_domains"] ?? [],
"trusted_proxies" =>
$CONFIG["trusted_proxies"] ?? []
]);
'
)"
EFFECTIVE_REDIS_PASSWORD="$(
jq -r '.redis_password' <<< "$EFFECTIVE_JSON"
)"
EFFECTIVE_DOMAINS="$(
jq -r '.trusted_domains[]?' <<< "$EFFECTIVE_JSON"
)"
if [[ "$EFFECTIVE_REDIS_PASSWORD" == "$REDIS_PASSWORD" ]]; then
pass "Redis password fixed"
else
fail "Redis password was not fixed"
fi
if grep -Fxq "$NEXTCLOUD_DOMAIN" <<< "$EFFECTIVE_DOMAINS"; then
pass "trusted_domains fixed"
else
fail "trusted_domains was not fixed"
fi
echo
echo "=========================================="
echo " Fix complete"
echo "=========================================="
exit 0
fi
# ============================================================
# Summary
# ============================================================
echo "=========================================="
echo "Result"
echo "=========================================="
echo "PASS: $PASS"
echo "FAIL: $FAIL"
if [[ "$FAIL" -eq 0 ]]; then
echo
echo "PASS: configuration is consistent."
exit 0
else
echo
echo "FAIL: configuration has mismatches."
echo
echo "Run:"
echo
echo " $0 --fix"
echo
exit 1
fi
+102
View File
@@ -0,0 +1,102 @@
#!/bin/bash
set -e
echo "==> Configuring Nextcloud"
OCC="php /var/www/html/occ"
# -------------------------
# SMTP
# -------------------------
$OCC config:system:set mail_smtpmode \
--value="smtp"
$OCC config:system:set mail_smtphost \
--value="${SMTP_HOST}"
$OCC config:system:set mail_smtpport \
--value="${SMTP_PORT}"
$OCC config:system:set mail_smtpsecure \
--value="${SMTP_SECURE}"
# Require SMTP authentication
$OCC config:system:set mail_smtpauth \
--type=boolean \
--value="true"
$OCC config:system:set mail_smtpname \
--value="${SMTP_USER}"
$OCC config:system:set mail_smtppassword \
--value="${SMTP_PASSWORD}"
$OCC config:system:set mail_from_address \
--value="${SMTP_FROM_ADDRESS}"
$OCC config:system:set mail_domain \
--value="${SMTP_FROM_DOMAIN}"
# -------------------------
# Apps
# -------------------------
apps=(
calendar
contacts
tasks
notes
richdocuments
cookbook
)
for app in "${apps[@]}"; do
echo "==> Installing app: ${app}"
if ! $OCC app:list | grep -q "^ ${app}:"; then
$OCC app:install "${app}" || true
fi
$OCC app:enable "${app}" || true
done
# -------------------------
# Collabora
# -------------------------
if [ -n "${COLLABORA_DOMAIN}" ]; then
echo "==> Configuring Collabora"
$OCC config:app:set richdocuments wopi_url \
--value="https://${COLLABORA_DOMAIN}"
fi
echo "==> Creating users"
export OC_PASS="${NEXTCLOUD_MIMI_PASSWORD}"
# Mimi
if ! $OCC user:info Mimi >/dev/null 2>&1; then
$OCC user:add \
--password-from-env \
--display-name="Mimi" \
Mimi
fi
$OCC user:setting Mimi settings email "miriam.m.faber@gmail.com"
# Lucas
if ! $OCC user:info lucas >/dev/null 2>&1; then
echo "ERROR: User 'lucas' does not exist."
exit 1
fi
$OCC user:setting lucas settings email "${LUCAS_EMAIL}"
echo "Set backroundjob to cron"
$OCC background:cron
echo "==> Nextcloud post-installation configuration complete"
@@ -0,0 +1,2 @@
docker compose exec nextcloud php occ config:system:set overwriteprotocol --value=https
docker compose exec nextcloud php occ config:system:set overwrite.cli.url --value=https://someoneslinux.ddns.net
@@ -0,0 +1,304 @@
# WebSocket support
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Redirect HTTP -> HTTPS
server {
listen 80;
server_name
cloud.someoneslinux.selfhost.eu
media.someoneslinux.selfhost.eu
audiobooks.someoneslinux.selfhost.eu
login.someoneslinux.selfhost.eu
auto.someoneslinux.selfhost.eu
music.someoneslinux.selfhost.eu
passwd.someoneslinux.selfhost.eu
requests.someoneslinux.selfhost.eu
torrent.someoneslinux.selfhost.eu
status.someoneslinux.selfhost.eu;
#ssl_conf_command Groups X25519:secp256r1:secp384r1;
# ssl_conf_command Groups X25519:prime256v1:secp384r1;
location /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
try_files $uri =404;
}
location / {
return 301 https://$host$request_uri;
}
}
# Common SSL settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
###################
# NEXTCLOUD
###################
server {
listen 443 ssl;http2 on;
server_name cloud.someoneslinux.selfhost.eu;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
ssl_certificate /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/privkey.pem;
client_max_body_size 10G;
location / {
proxy_pass http://nextcloud:80;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
###################
# JELLYFIN
###################
server {
listen 443 ssl;http2 on;
server_name media.someoneslinux.selfhost.eu;
add_header Content-Security-Policy "frame-ancestors 'self';" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
ssl_certificate /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/privkey.pem;
location / {
proxy_pass http://jellyfin:8096;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
###################
# AUDIOBOOKSHELF
###################
server {
listen 443 ssl;http2 on;
server_name audiobooks.someoneslinux.selfhost.eu;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
ssl_certificate /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/privkey.pem;
location / {
proxy_pass http://audiobookshelf:80;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-Proto https;
}
}
###################
# AUTHENTIK
###################
server {
listen 443 ssl;http2 on;
server_name login.someoneslinux.selfhost.eu;
add_header Content-Security-Policy "frame-ancestors 'self';" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
ssl_certificate /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/privkey.pem;
location / {
proxy_pass http://authentik-server-1:9000;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
####################
## HOME ASSISTANT
####################
#server {
# listen 443 ssl;http2 on;
# server_name auto.someoneslinux.selfhost.eu;
#
# add_header Content-Security-Policy "default-src 'self'; frame-ancestors 'self';" always;
# add_header X-Frame-Options "SAMEORIGIN" always;
# add_header X-Content-Type-Options "nosniff" always;
# add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
#
# ssl_certificate /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/fullchain.pem;
# ssl_certificate_key /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/privkey.pem;
#
# location / {
# proxy_pass http://192.168.0.4:8123;
# proxy_http_version 1.1;
#
# proxy_set_header Host $host;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection $connection_upgrade;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto https;
# }
#}
###################
# NAVIDROME
###################
server {
listen 443 ssl;http2 on;
server_name music.someoneslinux.selfhost.eu;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
ssl_certificate /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/privkey.pem;
location / {
proxy_pass http://navidrome:4533;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP $remote_addr;
}
}
###################
# VAULTWARDEN
###################
server {
listen 443 ssl;http2 on;
server_name passwd.someoneslinux.selfhost.eu;
add_header Content-Security-Policy "default-src 'self'; frame-ancestors 'self';" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
ssl_certificate /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/privkey.pem;
location / {
proxy_pass http://vaultwarden:80;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /notifications/hub {
proxy_pass http://vaultwarden:3012;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
###################
# SEERR
###################
server {
listen 443 ssl;http2 on;
server_name requests.someoneslinux.selfhost.eu;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
ssl_certificate /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/privkey.pem;
location / {
proxy_pass http://seerr:5055;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-Proto https;
}
}
###################
# QBITTORRENT
###################
server {
listen 443 ssl;http2 on;
server_name torrent.someoneslinux.selfhost.eu;
add_header Content-Security-Policy "frame-ancestors 'self';" always;
# add_header Content-Security-Policy "default-src 'self'; frame-ancestors 'self';" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
ssl_certificate /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/privkey.pem;
location / {
proxy_pass http://192.168.0.2:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-Proto https;
}
}
###################
# GRFANA
###################
server {
listen 443 ssl;http2 on;
server_name status.someoneslinux.selfhost.eu;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
ssl_certificate /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/live/cloud.someoneslinux.selfhost.eu/privkey.pem;
location / {
proxy_pass http://grafana:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-Proto https;
}
}
@@ -0,0 +1,47 @@
services:
nginx:
image: nginx:stable
container_name: nginx
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./conf.d:/etc/nginx/conf.d
- ./certs:/etc/nginx/certs
- ./html:/usr/share/nginx/html
# Access and error logs
- ./logs:/var/log/nginx
networks:
- shared-proxy-services
crowdsec:
image: crowdsecurity/crowdsec:latest
container_name: crowdsec
restart: unless-stopped
environment:
COLLECTIONS: >
crowdsecurity/nginx
crowdsecurity/http-cve
volumes:
- crowdsec-db:/var/lib/crowdsec/data
- ./logs:/var/log/nginx:ro
- /etc/localtime:/etc/localtime:ro
certbot:
image: certbot/certbot:latest
container_name: certbot
volumes:
- ./certs:/etc/letsencrypt
- ./html:/var/www/certbot
networks:
- shared-proxy-services
networks:
shared-proxy-services:
external: true
volumes:
crowdsec-db:
@@ -0,0 +1,19 @@
#!/bin/bash
# selfHOST DynDNS Update Script
URL='https://549335:GoviYPrfj4XI@carol.selfhost.de/nic/update?myip='
# Get current public IPv4 address
PUBLIC_IP=$(curl -4 -s https://api.ipify.org)
# Exit if IP detection failed
if [ -z "$PUBLIC_IP" ]; then
echo "$(date): Failed to determine public IP"
exit 1
fi
# Send update to selfHOST
RESULT=$(curl -s "${URL}${PUBLIC_IP}")
echo "$(date): IP=${PUBLIC_IP}"
@@ -0,0 +1,22 @@
services:
redis:
image: redis:7
container_name: redis
restart: unless-stopped
command: redis-server --appendonly yes --requirepass PerCent7heStorySp0tInOrd3r
healthcheck:
test:
[
"CMD-SHELL",
"redis-cli -a \"$${REDIS_PASSWORD}\" ping | grep PONG"
]
interval: 10s
timeout: 5s
retries: 10
start_period: 10s
networks:
default:
external: true
name: shared-redis-services
@@ -0,0 +1,27 @@
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
environment:
WEBSOCKET_ENABLED: "true"
SIGNUPS_ALLOWED: "true" # Registrierung deaktivieren (optional)
DOMAIN: ${DOMAIN}
ADMIN_TOKEN: ${ADMIN_TOKEN}
SMTP_HOST: "smtp.web.de"
SMTP_FROM: "ll_m@web.de"
SMTP_PORT: 587
SMTP_SSL: "false"
SMTP_SECURITY: starttls
SMTP_USERNAME: ll_m@web.de
SMTP_PASSWORD: ${SMTP_PASSWORD}
volumes:
- ./vaultwarden:/data
ports:
- "8081:80"
networks:
- shared-proxy-services
networks:
shared-proxy-services:
external: true
@@ -0,0 +1,20 @@
services:
wireguard:
image: lscr.io/linuxserver/wireguard:latest
container_name: wireguard
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Vienna
- SERVERURL=someoneslinux.selfhost.eu
- SERVERPORT=51820
- PEERS=5
volumes:
- ./config:/config
- /lib/modules:/lib/modules:ro
ports:
- 51820:51820/udp
restart: unless-stopped