Compare commits

..

3 Commits

Author SHA1 Message Date
Simon 73a3381217 Upgrade peekskog to PHP 8.4 and MySQL 8.4, fix traefik headers
- wordpress:5.6.0-apache (PHP 7.4) -> wordpress:php8.4-apache
- mysql:5.7 -> mysql:8.4 with new datadir peekskog/db84 (imported
  from dump; old 5.7 datadir kept for rollback)
- Remove duplicate router middlewares label so www-redirect is applied
- Add upgrade-insecure-requests to CSP and a Permissions-Policy header
- Ignore local peek_backup/ directory

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 22:17:20 +01:00
Simon c64be0ab02 Add CouchDB and livesync-bridge for Obsidian LiveSync
CouchDB is served at livesync.${DOMAIN} via Traefik without a middleware
chain, since CouchDB handles CORS itself. livesync-bridge mirrors the
vault to ~/repo/notes, and notes-autocommit.sh pushes it from cron.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 23:55:30 +02:00
Simon 8e6866fb20 Updates 2026-09-21 21:15:40 +02:00
12 changed files with 394 additions and 43 deletions

13
.gitignore vendored
View File

@ -1,11 +1,22 @@
librespeed/config/log/*
**/[Ll]ogs
**/[Ll]og
librespeed/config/log/*
ha/config/custom_components/*
ha/config/themes/*
ha/config/image/*
ha/config/www/community/*
ha/config/www/community/*
ha/config/www/media/ha-bambulab/*
ha/config/www/last_person_detection.jpg
ha/config/.ha_run.lock
ha/config/.HA_VERSION
ha/matter_server/
ha/zwave-config/
secrets/
evcc/evcc/evcc.db
letsencrypt/
letsencrypt_peek/
zigbee2mqtt/configuration_*.yaml
zigbee_home_2/database.db
ha/config/.cache/**
peek_backup/

View File

@ -10,7 +10,7 @@ services:
max-file: "3"
depends_on:
- db_peek
image: wordpress:5.6.0-apache
image: wordpress:php8.4-apache
volumes:
- ${DIR_LOCAL}/peekskog/wp:/var/www/html
- ./wp/php.conf.ini:/usr/local/etc/php/conf.d/uploads.ini
@ -34,8 +34,8 @@ services:
- "traefik.http.routers.peek-secure.entrypoints=web-secure"
- "traefik.http.routers.peek-secure.rule=Host(`peekskog.se`) || Host(`www.peekskog.se`)"
- "traefik.http.routers.peek-secure.middlewares=www-redirect,peek-middle"
- "traefik.http.routers.peek-secure.middlewares=peek-middle"
- "traefik.http.middlewares.peek-middle.headers.contentSecurityPolicy=frame-ancestors 'self' peekskog.se"
- "traefik.http.middlewares.peek-middle.headers.contentSecurityPolicy=frame-ancestors 'self' peekskog.se; upgrade-insecure-requests"
- "traefik.http.middlewares.peek-middle.headers.permissionsPolicy=camera=(), microphone=(), geolocation=(), payment=(), usb=()"
- "traefik.http.middlewares.peek-middle.headers.framedeny=true"
- "traefik.http.middlewares.peek-middle.headers.stsSeconds=155520011"
- "traefik.http.middlewares.peek-middle.headers.stsIncludeSubdomains=true"
@ -52,14 +52,14 @@ services:
db_peek:
container_name: db_peek
image: mysql:5.7
image: mysql:8.4
logging:
driver: "json-file"
options:
max-size: "5m"
max-file: "3"
volumes:
- ${DIR_LOCAL}/peekskog/db:/var/lib/mysql
- ${DIR_LOCAL}/peekskog/db84:/var/lib/mysql
restart: always
networks:
- backend

View File

@ -13,7 +13,7 @@ services:
- backend
ports:
- "8088:8080"
image: koenkk/zigbee2mqtt:2.10
image: koenkk/zigbee2mqtt:2.13
restart: always
volumes:
- ./zigbee_home_2:/app/data
@ -43,7 +43,7 @@ services:
max-file: "5"
networks:
- backend
image: koenkk/zigbee2mqtt:2.10
image: koenkk/zigbee2mqtt:2.13
restart: always
volumes:
- ${DIR}/zigbee2matt:/app/data

View File

@ -28,8 +28,17 @@ secrets:
file: $SECRETSDIR/skoda_spin
carconnect_grafana_pw:
file: $SECRETSDIR/carconnect_grafana_pw
home_assistant_token_spoolman:
file: $SECRETSDIR/home_assistant_token_spoolman
couchdb_password:
file: $SECRETSDIR/couchdb_password
livesync_bridge_config:
file: $SECRETSDIR/livesync_bridge_config.json
include:
- ./evcc/docker-compose.yml
########################### EXTENSION FIELDS ##########################
# Helps eliminate repetition of sections
# More Info on how to use this: https://github.com/htpcBeginner/docker-traefik/pull/228
@ -44,6 +53,7 @@ x-common-keys-monitoring: &common-keys-monitoring
- backend
security_opt:
- no-new-privileges:true restart: always
services:
reverse-proxy:
@ -176,7 +186,6 @@ services:
- "traefik.http.routers.ddnsupdater.tls.certresolver=milvert_dns"
- "traefik.http.routers.ddnsupdater.tls=true"
######################### DATABASE ############################
#
# DATABASE
@ -317,7 +326,7 @@ services:
ha:
container_name: ha
image: homeassistant/home-assistant:2026.2
image: homeassistant/home-assistant:2026.9
restart: always
privileged: true
networks:
@ -373,7 +382,7 @@ services:
appdaemon:
container_name: appdaemon
image: acockburn/appdaemon:4.4.2
image: acockburn/appdaemon:4.5.13
restart: unless-stopped
depends_on:
- ha
@ -445,11 +454,12 @@ services:
image: ghcr.io/matter-js/python-matter-server:stable
container_name: matter-server
restart: unless-stopped
networks:
backend:
docker_vlan:
ipv4_address: 10.0.0.204
ipv6_address: "2001:9b0:215:8e00::204"
network_mode: host
#networks:
#backend:
#docker_vlan:
#ipv4_address: 10.0.0.204
#ipv6_address: "2001:9b0:215:8e00::204"
#security_opt:
# Needed for Bluetooth via dbus
# - apparmor:unconfined
@ -459,29 +469,7 @@ services:
environment:
- diun.enable=true
evcc:
command:
- evcc
container_name: evcc
image: evcc/evcc:0.305.1
ports:
- 7070:7070/tcp
volumes:
- "./evcc/evcc.yaml:/etc/evcc.yaml:ro"
- ./evcc/evcc:/root/.evcc
restart: unless-stopped
networks:
- backend
labels:
- diun.enable=true
- "traefik.enable=true"
- "traefik.http.routers.evcc.entrypoints=web-secure"
- "traefik.http.routers.evcc.rule=Host(`box.${DOMAIN}`)"
- "traefik.http.services.evcc.loadbalancer.server.port=7070"
- "traefik.http.routers.evcc.middlewares=chain-no-auth@file"
- "traefik.http.routers.evcc.tls.certresolver=milvert_dns"
- "traefik.http.routers.evcc.tls=true"
grafana:
image: grafana/grafana:10.3.1
container_name: grafana
@ -681,6 +669,60 @@ services:
- "traefik.http.routers.librespeed.tls.certresolver=milvert_dns"
- "traefik.http.routers.librespeed.tls=true"
spoolman:
image: ghcr.io/donkie/spoolman:0.23
container_name: spoolman
restart: unless-stopped
networks:
- backend
volumes:
- ${DIR_LOCAL}/spoolman/data:/home/app/.local/share/spoolman
environment:
- TZ=Europe/Stockholm
labels:
- "diun.enable=true"
- "traefik.enable=true"
- "traefik.http.services.spoolman-service.loadbalancer.server.port=8000"
- "traefik.http.routers.spoolman-secure.entrypoints=web-secure"
- "traefik.http.routers.spoolman-secure.rule=Host(`spoolman.${DOMAIN}`)"
- "traefik.http.routers.spoolman-secure.tls.certresolver=milvert_dns"
- "traefik.http.routers.spoolman-secure.tls=true"
- "traefik.http.routers.spoolman-secure.middlewares=chain-authelia@file"
spoolman-updater:
image: marcokreeft/spoolman-updater:latest
container_name: spoolman-updater
restart: unless-stopped
secrets:
- home_assistant_token_spoolman
entrypoint:
- /bin/sh
- -c
- |
export APPLICATION__HOMEASSISTANT__TOKEN="$$(cat /run/secrets/home_assistant_token_spoolman)"
exec dotnet Application.dll
ports:
- "8089:8080"
networks:
- backend
environment:
- TZ=Europe/Stockholm
- APPLICATION__HOMEASSISTANT__URL=http://ha:8123
- APPLICATION__SPOOLMAN__URL=http://spoolman:8000
- APPLICATION__HOMEASSISTANT__EXTERNALSPOOLENTITY=sensor.a1mini_0309da441900142_externalspool_external_spool
- APPLICATION__HOMEASSISTANT__TRAYENTITIES__0=sensor.a1mini_0309da441900142_ams_1_tray_1
- APPLICATION__HOMEASSISTANT__TRAYENTITIES__1=sensor.a1mini_0309da441900142_ams_1_tray_2
- APPLICATION__HOMEASSISTANT__TRAYENTITIES__2=sensor.a1mini_0309da441900142_ams_1_tray_3
- APPLICATION__HOMEASSISTANT__TRAYENTITIES__3=sensor.a1mini_0309da441900142_ams_1_tray_4
labels:
- "diun.enable=true"
- "traefik.enable=true"
- "traefik.http.services.spoolman-updater-service.loadbalancer.server.port=8080"
- "traefik.http.routers.spoolman-updater-secure.entrypoints=web-secure"
- "traefik.http.routers.spoolman-updater-secure.rule=Host(`spoolman-updater.${DOMAIN}`)"
- "traefik.http.routers.spoolman-updater-secure.tls.certresolver=milvert_dns"
- "traefik.http.routers.spoolman-updater-secure.tls=true"
- "traefik.http.routers.spoolman-updater-secure.middlewares=chain-authelia@file"
jelu:
image: wabayang/jelu
@ -871,6 +913,56 @@ services:
- "traefik.http.routers.carconnect-grafana.tls.certresolver=milvert_dns"
- "traefik.http.routers.carconnect-grafana.tls=true"
couchdb:
image: couchdb:3.5
container_name: couchdb
restart: unless-stopped
entrypoint: ["/bin/sh", "/couchdb-entrypoint.sh"]
networks:
- backend
environment:
- TZ=${TZ}
- COUCHDB_USER=obsidian
secrets:
- couchdb_password
volumes:
- ${DIR_LOCAL}/couchdb/data:/opt/couchdb/data
- ./obsidian-livesync/couchdb-entrypoint.sh:/couchdb-entrypoint.sh:ro
- ./obsidian-livesync/livesync.ini:/livesync.ini:ro
labels:
- diun.enable=true
# No middleware chain: CouchDB handles CORS itself, and chain-no-auth's
# secure-headers (GET/OPTIONS/PUT only) and rate limit break LiveSync.
- "traefik.enable=true"
- "traefik.http.services.livesync-service.loadbalancer.server.port=5984"
- "traefik.http.routers.livesync-secure.entrypoints=web-secure"
- "traefik.http.routers.livesync-secure.rule=Host(`livesync.${DOMAIN}`)"
- "traefik.http.routers.livesync-secure.tls.certresolver=milvert_dns"
- "traefik.http.routers.livesync-secure.tls=true"
# Mirrors the CouchDB vault to ~/repo/notes as markdown.
# No published image, so it is built from a pinned commit.
livesync-bridge:
build: https://github.com/vrtmrz/livesync-bridge.git#fc0e028d33b3a12ddee1322951375e05107edc55
image: livesync-bridge:fc0e028
container_name: livesync-bridge
restart: unless-stopped
user: "${UID}:${GID}"
depends_on:
- couchdb
networks:
- backend
environment:
- TZ=${TZ}
- LSB_CONFIG=/run/secrets/livesync_bridge_config
secrets:
- livesync_bridge_config
volumes:
- /home/simon/repo/notes:/app/data/vault
- ${DIR_LOCAL}/livesync-bridge:/deno-dir/location_data
labels:
- "traefik.enable=false"
networks:
frontend:
external: true

View File

@ -174,7 +174,7 @@
alias: växtlampa schema
description: ''
triggers:
- value_template: '{{ now().hour == 9 }}'
- value_template: '{{ now().hour == 8 }}'
id: 'on'
trigger: template
- value_template: '{{ (now().hour, now().minute) == (21,30) }}'
@ -813,3 +813,35 @@
title: "Dags att vattna! \U0001F331"
message: Fuktnivån är nu nere på {{ states('sensor.h034s_soil_moisture') }}%.
mode: single
- id: '1783927143748'
alias: Framsida pling
description: Sparar en fast bild till notis, en unik bild med tidsstämpel och skickar
notis.
triggers:
- trigger: state
entity_id:
- binary_sensor.kamera_framsida_visitor
to: 'on'
conditions: []
actions:
- action: camera.snapshot
metadata: {}
data:
filename: /config/www/doorbell_snapshots.jpg
target:
entity_id: camera.kamera_framsida_fluent
- action: camera.snapshot
metadata: {}
data:
filename: /config/www/doorbell_snapshots/pling_{{ now().strftime('%Y%m%d_%H%M%S')
}}.jpg
target:
entity_id: camera.kamera_framsida_fluent
- action: notify.mobile_app_simon_mobil
metadata: {}
data:
title: "Dörrklocka! \U0001F514"
message: Någon plingar på framsidan.
data:
image: /local/doorbell_snapshots.jpg
mode: single

View File

@ -702,6 +702,16 @@
- candle
- fireplace
- colorloop
- sunset
- sunrise
- sparkle
- opal
- glisten
- underwater
- cosmos
- sunbeam
- enchant
- none
- finish_effect
- stop_effect
- stop_hue_effect
@ -774,6 +784,70 @@
switch.h015l:
friendly_name: Framsida fasad
state: 'on'
light.h026l:
min_color_temp_kelvin: 2202
max_color_temp_kelvin: 4000
min_mireds: 250
max_mireds: 454
effect_list:
- blink
- breathe
- okay
- channel_change
- finish_effect
- stop_effect
supported_color_modes:
- color_temp
effect:
color_mode: color_temp
brightness: 148
color_temp_kelvin: 2202
color_temp: 454
hs_color:
- 29.79
- 84.553
rgb_color:
- 255
- 146
- 39
xy_color:
- 0.579
- 0.388
friendly_name: Pollare_2
supported_features: 44
state: 'on'
light.h027l:
min_color_temp_kelvin: 2202
max_color_temp_kelvin: 4000
min_mireds: 250
max_mireds: 454
effect_list:
- blink
- breathe
- okay
- channel_change
- finish_effect
- stop_effect
supported_color_modes:
- color_temp
effect:
color_mode: color_temp
brightness: 148
color_temp_kelvin: 2202
color_temp: 454
hs_color:
- 29.79
- 84.553
rgb_color:
- 255
- 146
- 39
xy_color:
- 0.579
- 0.388
friendly_name: Pollare_3
supported_features: 44
state: 'on'
icon: mdi:home-sound-out
metadata:
switch.h016s:
@ -792,6 +866,10 @@
entity_only: true
switch.h015l:
entity_only: true
light.h026l:
entity_only: true
light.h027l:
entity_only: true
- id: '1708976892459'
name: Ute Av
entities:
@ -808,6 +886,16 @@
- candle
- fireplace
- colorloop
- sunset
- sunrise
- sparkle
- opal
- glisten
- underwater
- cosmos
- sunbeam
- enchant
- none
- finish_effect
- stop_effect
- stop_hue_effect
@ -889,7 +977,7 @@
supported_features: 44
state: 'off'
switch.h024s:
friendly_name: Framsida slingor
friendly_name: Garage slinga
state: 'off'
switch.h023s:
friendly_name: Ute baksida
@ -905,10 +993,74 @@
supported_color_modes:
- brightness
effect:
color_mode:
brightness:
color_mode: brightness
brightness: 22
friendly_name: Liten_gultrum
supported_features: 44
state: 'on'
light.h026l:
min_color_temp_kelvin: 2202
max_color_temp_kelvin: 4000
min_mireds: 250
max_mireds: 454
effect_list:
- blink
- breathe
- okay
- channel_change
- finish_effect
- stop_effect
supported_color_modes:
- color_temp
effect:
color_mode: color_temp
brightness: 148
color_temp_kelvin: 2202
color_temp: 454
hs_color:
- 29.79
- 84.553
rgb_color:
- 255
- 146
- 39
xy_color:
- 0.579
- 0.388
friendly_name: Pollare_2
supported_features: 44
state: 'off'
light.h027l:
min_color_temp_kelvin: 2202
max_color_temp_kelvin: 4000
min_mireds: 250
max_mireds: 454
effect_list:
- blink
- breathe
- okay
- channel_change
- finish_effect
- stop_effect
supported_color_modes:
- color_temp
effect:
color_mode: color_temp
brightness: 148
color_temp_kelvin: 2202
color_temp: 454
hs_color:
- 29.79
- 84.553
rgb_color:
- 255
- 146
- 39
xy_color:
- 0.579
- 0.388
friendly_name: Pollare_3
supported_features: 44
state: 'off'
icon: mdi:home-sound-out
metadata:
@ -934,6 +1086,10 @@
entity_only: true
light.liten_gultrum:
entity_only: true
light.h026l:
entity_only: true
light.h027l:
entity_only: true
- id: '1715369441992'
name: Bevattning
entities:

View File

@ -0,0 +1,9 @@
#!/bin/sh
# Reads the admin password from the Docker secret and installs the LiveSync
# settings before handing over to the image's own entrypoint.
set -e
export COUCHDB_PASSWORD="$(cat /run/secrets/couchdb_password)"
cp /livesync.ini /opt/couchdb/etc/local.d/10-livesync.ini
exec tini -- /docker-entrypoint.sh /opt/couchdb/bin/couchdb

View File

@ -0,0 +1,26 @@
; CouchDB settings required by Obsidian Self-hosted LiveSync.
; Values follow obsidian-livesync docker/scripts/couchdb-init.sh.
[couchdb]
single_node = true
max_document_size = 50000000
[chttpd]
require_valid_user = true
max_http_request_size = 4294967296
enable_cors = true
[chttpd_auth]
require_valid_user = true
authentication_redirect = /_utils/session.html
[httpd]
WWW-Authenticate = Basic realm="couchdb"
enable_cors = true
[cors]
origins = app://obsidian.md,capacitor://localhost,http://localhost
credentials = true
headers = accept, authorization, content-type, origin, referer
methods = GET, PUT, POST, HEAD, DELETE
max_age = 3600

View File

@ -0,0 +1,15 @@
#!/bin/sh
# Commits and pushes the LiveSync-mirrored notes repo. Run from cron.
set -eu
REPO=/home/simon/repo/notes
# Skip this run if the previous one is still going.
exec 9>/tmp/notes-autocommit.lock
flock -n 9 || exit 0
cd "$REPO"
git add -A
git diff --cached --quiet && exit 0
git commit -q -m "Autocommit $(date '+%Y-%m-%d %H:%M')"
git push -q origin main

1
torrent/config/rutorrent/.gitignore vendored Executable file
View File

@ -0,0 +1 @@
profiles

View File

@ -25,3 +25,11 @@ http:
- middlewares-secure-headers
- middlewares-authelia
- middlewares-compress
chain-local:
chain:
middlewares:
- localNetwork
- middlewares-rate-limit
- middlewares-secure-headers
- middlewares-compress

View File

@ -36,6 +36,7 @@ http:
sourceRange:
- "127.0.0.1/32"
- "10.0.0.0/8"
- "2001:9b0:215:8e00::/62"
middlewares-https-redirectscheme:
redirectScheme: