chore: audit and fix service configurations and allowedOrigins

This commit is contained in:
KonradHerman
2026-05-06 13:23:51 -04:00
parent f52b4ae2b4
commit ccb9d44c04
13 changed files with 522 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
# Global options
{
auto_https disable_redirects
email k.radikal@gmail.com
}
# Consolidated wildcard site block
*.klhoud.com, http://*.klhoud.com {
# Automatic HTTPS via DNS challenge for all subdomains
tls {
dns cloudflare {$CLOUDFLARE_API_TOKEN}
}
# Proxmox
@proxmox host proxmox.klhoud.com
handle @proxmox {
reverse_proxy https://192.168.0.112:8006 {
# Required for connecting to Proxmox's self-signed/untrusted certificate
transport http {
tls_insecure_skip_verify
versions 1.1
}
}
}
# AdGuard Home
@adguard host adguard.klhoud.com
handle @adguard {
reverse_proxy 192.168.0.170:80
}
# Dockge
@dockge host dockge.klhoud.com
handle @dockge {
reverse_proxy 192.168.0.12:5001
}
# Nextcloud
@cloud host cloud.klhoud.com
handle @cloud {
reverse_proxy 192.168.0.12:8080
# Nextcloud-specific headers
header Strict-Transport-Security "max-age=31536000;"
# Handle large file uploads
request_body {
max_size 10GB
}
}
# Coolify (control plane runs on LXC 103). Upstream HTTPS to 443 because
# coolify-proxy's HTTP entry forces a redirect-to-https which would loop
# back through us. HTTPS upstream hits the no-redirect routes; cert is
# self-signed since coolify-proxy's ACME for coolify.klhoud.com fails
# (DNS points at us, not it), so we skip verify.
# coolify-proxy (Traefik) on LXC 103 listens on :80. We added a custom
# higher-priority router in /data/coolify/proxy/dynamic/coolify-noredirect.yaml
# there to bypass Coolify's auto-generated http->https redirect (which would
# loop us). WebSocket routes (/app, /terminal/ws) work natively on :80.
@coolify host coolify.klhoud.com
handle @coolify {
reverse_proxy 192.168.0.47:80
}
# IMPORTANT: Fallback Handler
# This prevents non-matching requests from falling through and failing.
handle {
respond "Not Found" 404
}
}
+20
View File
@@ -0,0 +1,20 @@
# Override file added by us (homelab-configs).
# Coolify auto-generates /data/coolify/proxy/dynamic/coolify.yaml with a
# redirect-to-https middleware on the HTTP router. That redirect causes a
# loop with our upstream alpine-caddy (LXC 101) which already terminates TLS.
# This higher-priority router wins for the UI but explicitly excludes the
# WebSocket paths so they keep using Coolify's own routers (coolify-realtime-ws
# for /app, coolify-terminal-ws for /terminal/ws).
http:
routers:
coolify-http-noredirect:
entryPoints:
- http
service: coolify-noredirect-svc
rule: 'Host(`coolify.klhoud.com`) && !PathPrefix(`/app`) && !PathPrefix(`/terminal/ws`)'
priority: 1000
services:
coolify-noredirect-svc:
loadBalancer:
servers:
- url: 'http://coolify:8080'
+72
View File
@@ -0,0 +1,72 @@
=== PVE host info ===
pve
Linux pve 6.17.2-1-pve #1 SMP PREEMPT_DYNAMIC PMX 6.17.2-1 (2025-10-21T11:55Z) x86_64 GNU/Linux
pve-manager/9.1.1/42db4a6cf33dac83 (running kernel: 6.17.2-1-pve)
=== LXC list ===
VMID Status Lock Name
100 running alpine-adguard
101 running alpine-caddy
102 running dockge
103 running coolify
=== VM list ===
=== Per-LXC config ===
===LXC-100===
arch: amd64
cores: 1
description: <div align='center'>%0A <a href='https%3A//Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>%0A <img src='https%3A//raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width%3A81px;height%3A112px;'/>%0A </a>%0A%0A <h2 style='font-size%3A 24px; margin%3A 20px 0;'>Alpine-AdGuard LXC</h2>%0A%0A <p style='margin%3A 16px 0;'>%0A <a href='https%3A//ko-fi.com/community_scripts' target='_blank' rel='noopener noreferrer'>%0A <img src='https%3A//img.shields.io/badge/&#x2615;-Buy us a coffee-blue' alt='spend Coffee' />%0A </a>%0A </p>%0A%0A <span style='margin%3A 0 10px;'>%0A <i class="fa fa-github fa-fw" style="color%3A #f5f5f5;"></i>%0A <a href='https%3A//github.com/community-scripts/ProxmoxVE' target='_blank' rel='noopener noreferrer' style='text-decoration%3A none; color%3A #00617f;'>GitHub</a>%0A </span>%0A <span style='margin%3A 0 10px;'>%0A <i class="fa fa-comments fa-fw" style="color%3A #f5f5f5;"></i>%0A <a href='https%3A//github.com/community-scripts/ProxmoxVE/discussions' target='_blank' rel='noopener noreferrer' style='text-decoration%3A none; color%3A #00617f;'>Discussions</a>%0A </span>%0A <span style='margin%3A 0 10px;'>%0A <i class="fa fa-exclamation-circle fa-fw" style="color%3A #f5f5f5;"></i>%0A <a href='https%3A//github.com/community-scripts/ProxmoxVE/issues' target='_blank' rel='noopener noreferrer' style='text-decoration%3A none; color%3A #00617f;'>Issues</a>%0A </span>%0A</div>%0A
features: keyctl=1,nesting=1
hostname: alpine-adguard
memory: 256
net0: name=eth0,bridge=vmbr0,hwaddr=BC:24:11:A4:76:5F,ip=dhcp,type=veth
onboot: 1
ostype: alpine
rootfs: local-lvm:vm-100-disk-0,size=1G
swap: 512
tags: adblock;alpine;community-script
unprivileged: 1
===LXC-101===
arch: amd64
cores: 1
description: <div align='center'>%0A <a href='https%3A//Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>%0A <img src='https%3A//raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width%3A81px;height%3A112px;'/>%0A </a>%0A%0A <h2 style='font-size%3A 24px; margin%3A 20px 0;'>Alpine-Caddy LXC</h2>%0A%0A <p style='margin%3A 16px 0;'>%0A <a href='https%3A//ko-fi.com/community_scripts' target='_blank' rel='noopener noreferrer'>%0A <img src='https%3A//img.shields.io/badge/&#x2615;-Buy us a coffee-blue' alt='spend Coffee' />%0A </a>%0A </p>%0A%0A <span style='margin%3A 0 10px;'>%0A <i class="fa fa-github fa-fw" style="color%3A #f5f5f5;"></i>%0A <a href='https%3A//github.com/community-scripts/ProxmoxVE' target='_blank' rel='noopener noreferrer' style='text-decoration%3A none; color%3A #00617f;'>GitHub</a>%0A </span>%0A <span style='margin%3A 0 10px;'>%0A <i class="fa fa-comments fa-fw" style="color%3A #f5f5f5;"></i>%0A <a href='https%3A//github.com/community-scripts/ProxmoxVE/discussions' target='_blank' rel='noopener noreferrer' style='text-decoration%3A none; color%3A #00617f;'>Discussions</a>%0A </span>%0A <span style='margin%3A 0 10px;'>%0A <i class="fa fa-exclamation-circle fa-fw" style="color%3A #f5f5f5;"></i>%0A <a href='https%3A//github.com/community-scripts/ProxmoxVE/issues' target='_blank' rel='noopener noreferrer' style='text-decoration%3A none; color%3A #00617f;'>Issues</a>%0A </span>%0A</div>%0A
features: keyctl=1,nesting=1
hostname: alpine-caddy
memory: 256
net0: name=eth0,bridge=vmbr0,hwaddr=BC:24:11:4E:3F:97,ip=dhcp,type=veth
onboot: 1
ostype: alpine
rootfs: local-lvm:vm-101-disk-0,size=3G
swap: 512
tags: community-script;webserver
unprivileged: 1
===LXC-102===
arch: amd64
cores: 2
description: <div align='center'>%0A <a href='https%3A//Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>%0A <img src='https%3A//raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width%3A81px;height%3A112px;'/>%0A </a>%0A%0A <h2 style='font-size%3A 24px; margin%3A 20px 0;'>Dockge LXC</h2>%0A%0A <p style='margin%3A 16px 0;'>%0A <a href='https%3A//ko-fi.com/community_scripts' target='_blank' rel='noopener noreferrer'>%0A <img src='https%3A//img.shields.io/badge/&#x2615;-Buy us a coffee-blue' alt='spend Coffee' />%0A </a>%0A </p>%0A%0A <span style='margin%3A 0 10px;'>%0A <i class="fa fa-github fa-fw" style="color%3A #f5f5f5;"></i>%0A <a href='https%3A//github.com/community-scripts/ProxmoxVE' target='_blank' rel='noopener noreferrer' style='text-decoration%3A none; color%3A #00617f;'>GitHub</a>%0A </span>%0A <span style='margin%3A 0 10px;'>%0A <i class="fa fa-comments fa-fw" style="color%3A #f5f5f5;"></i>%0A <a href='https%3A//github.com/community-scripts/ProxmoxVE/discussions' target='_blank' rel='noopener noreferrer' style='text-decoration%3A none; color%3A #00617f;'>Discussions</a>%0A </span>%0A <span style='margin%3A 0 10px;'>%0A <i class="fa fa-exclamation-circle fa-fw" style="color%3A #f5f5f5;"></i>%0A <a href='https%3A//github.com/community-scripts/ProxmoxVE/issues' target='_blank' rel='noopener noreferrer' style='text-decoration%3A none; color%3A #00617f;'>Issues</a>%0A </span>%0A</div>%0A
features: keyctl=1,nesting=1
hostname: dockge
memory: 2048
net0: name=eth0,bridge=vmbr0,hwaddr=BC:24:11:FA:D7:D4,ip=dhcp,type=veth
onboot: 1
ostype: debian
rootfs: local-lvm:vm-102-disk-0,size=18G
swap: 512
tags: community-script;docker
unprivileged: 1
===LXC-103===
arch: amd64
cores: 2
features: nesting=1
hostname: coolify
memory: 4096
net0: name=eth0,bridge=vmbr0,firewall=1,hwaddr=BC:24:11:36:EC:64,ip=dhcp,type=veth
ostype: debian
rootfs: local-lvm:vm-103-disk-0,size=60G
swap: 512
unprivileged: 1
+10
View File
@@ -0,0 +1,10 @@
total 28
drwxr-xr-x 2 root root 4096 May 6 09:27 .
drwxr-xr-x 32 root root 4096 Apr 30 02:29 ..
-rw-r--r-- 1 root root 1471 May 6 09:27 Caddyfile
-rw-r--r-- 1 root root 1390 Nov 25 05:04 Caddyfile.bak.1777516902
-rw-r--r-- 1 root root 1444 Apr 30 02:43 Caddyfile.bak.1777517752
-rw-r--r-- 1 root root 1473 May 6 09:27 Caddyfile.bak.1778059646
-rw------- 1 root root 62 Oct 13 2025 caddy.env
---
ls: /etc/caddy/Caddyfile.bak.*: No such file or directory
@@ -0,0 +1,62 @@
# Global options
{
auto_https disable_redirects
email k.radikal@gmail.com
}
# Consolidated wildcard site block
*.klhoud.com, http://*.klhoud.com {
# Automatic HTTPS via DNS challenge for all subdomains
tls {
dns cloudflare {$CLOUDFLARE_API_TOKEN}
}
# Proxmox
@proxmox host proxmox.klhoud.com
handle @proxmox {
reverse_proxy https://192.168.0.112:8006 {
# Required for connecting to Proxmox's self-signed/untrusted certificate
transport http {
tls_insecure_skip_verify
versions 1.1
}
}
}
# AdGuard Home
@adguard host adguard.klhoud.com
handle @adguard {
reverse_proxy 192.168.0.170:80
}
# Dockge
@dockge host dockge.klhoud.com
handle @dockge {
reverse_proxy 192.168.0.12:5001
}
# Nextcloud
@cloud host cloud.klhoud.com
handle @cloud {
reverse_proxy 192.168.0.12:8080
# Nextcloud-specific headers
header Strict-Transport-Security "max-age=31536000;"
# Handle large file uploads
request_body {
max_size 10GB
}
}
# Coolify
@coolify host coolify.klhoud.com
handle @coolify {
reverse_proxy 192.168.0.47:80
}
# IMPORTANT: Fallback Handler
# This prevents non-matching requests from falling through and failing.
handle {
respond "Not Found" 404
}
}
+6
View File
@@ -0,0 +1,6 @@
coolify ghcr.io/coollabsio/coolify:4.0.0 Up 6 days (healthy)
coolify-db postgres:15-alpine Up 6 days (healthy)
coolify-redis redis:7-alpine Up 6 days (healthy)
coolify-realtime ghcr.io/coollabsio/coolify-realtime:1.0.13 Up 6 days (healthy)
coolify-sentinel ghcr.io/coollabsio/sentinel:0.0.21 Up 2 weeks (healthy)
coolify-proxy traefik:v3.6 Up 5 months (healthy)
@@ -0,0 +1,54 @@
name: coolify-proxy
networks:
coolify:
external: true
services:
traefik:
container_name: coolify-proxy
image: 'traefik:v3.6'
restart: unless-stopped
extra_hosts:
- 'host.docker.internal:host-gateway'
networks:
- coolify
ports:
- '80:80'
- '443:443'
- '443:443/udp'
- '8080:8080'
healthcheck:
test: 'wget -qO- http://localhost:80/ping || exit 1'
interval: 4s
timeout: 2s
retries: 5
volumes:
- '/var/run/docker.sock:/var/run/docker.sock:ro'
- '/data/coolify/proxy/:/traefik'
command:
- '--ping=true'
- '--ping.entrypoint=http'
- '--api.dashboard=true'
- '--entrypoints.http.address=:80'
- '--entrypoints.http.forwardedheaders.trustedips=192.168.0.40'
- '--entrypoints.https.address=:443'
- '--entrypoints.https.forwardedheaders.trustedips=192.168.0.40'
- '--entrypoints.http.http.encodequerysemicolons=true'
- '--entryPoints.http.http2.maxConcurrentStreams=250'
- '--entrypoints.https.http.encodequerysemicolons=true'
- '--entryPoints.https.http2.maxConcurrentStreams=250'
- '--entrypoints.https.http3'
- '--providers.file.directory=/traefik/dynamic/'
- '--providers.file.watch=true'
- '--certificatesresolvers.letsencrypt.acme.httpchallenge=true'
- '--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http'
- '--certificatesresolvers.letsencrypt.acme.storage=/traefik/acme.json'
- '--api.insecure=false'
- '--providers.docker=true'
- '--providers.docker.exposedbydefault=false'
labels:
- traefik.enable=true
- traefik.http.routers.traefik.entrypoints=http
- traefik.http.routers.traefik.service=api@internal
- traefik.http.services.traefik.loadbalancer.server.port=8080
- coolify.managed=true
- coolify.proxy=true
@@ -0,0 +1 @@
import /dynamic/*.caddy
@@ -0,0 +1,65 @@
# This file is automatically generated by Coolify.
# Do not edit it manually (only if you know what are you doing).
http:
middlewares:
redirect-to-https:
redirectscheme:
scheme: https
gzip:
compress: true
routers:
coolify-http:
middlewares:
- redirect-to-https
entryPoints:
- http
service: coolify
rule: Host(`coolify.klhoud.com`)
coolify-realtime-ws:
entryPoints:
- http
service: coolify-realtime
rule: 'Host(`coolify.klhoud.com`) && PathPrefix(`/app`)'
coolify-terminal-ws:
entryPoints:
- http
service: coolify-terminal
rule: 'Host(`coolify.klhoud.com`) && PathPrefix(`/terminal/ws`)'
coolify-https:
entryPoints:
- https
service: coolify
rule: Host(`coolify.klhoud.com`)
tls:
certresolver: letsencrypt
coolify-realtime-wss:
entryPoints:
- https
service: coolify-realtime
rule: 'Host(`coolify.klhoud.com`) && PathPrefix(`/app`)'
tls:
certresolver: letsencrypt
coolify-terminal-wss:
entryPoints:
- https
service: coolify-terminal
rule: 'Host(`coolify.klhoud.com`) && PathPrefix(`/terminal/ws`)'
tls:
certresolver: letsencrypt
services:
coolify:
loadBalancer:
servers:
-
url: 'http://coolify:8080'
coolify-realtime:
loadBalancer:
servers:
-
url: 'http://coolify-realtime:6001'
coolify-terminal:
loadBalancer:
servers:
-
url: 'http://coolify-realtime:6002'
@@ -0,0 +1,18 @@
# This file is generated by Coolify, do not edit it manually.
# Disable the default redirect to customize (only if you know what are you doing).
http:
routers:
catchall:
entryPoints:
- http
- https
service: noop
rule: PathPrefix(`/`)
tls:
certResolver: letsencrypt
priority: -1000
services:
noop:
loadBalancer:
servers: { }
@@ -0,0 +1,17 @@
APP_ID=4ade2d03d47e25dbd2477aebeea02f68
APP_NAME=Coolify
APP_KEY=base64:/NXqvQqLEoiL2l95unMEgIrmNISZWCN3gkn8C+70ArU=
APP_URL=https://coolify.klhoud.com
DB_USERNAME=coolify
DB_PASSWORD=NK7UZfGH6s+xK1FCWhZ16UIW5+XLSyJWUW/SAeiUqr0=
REDIS_PASSWORD=hFFgieL5zun4R259weXB5mwB+obiNqzgFbZ+/TybQwM=
PUSHER_APP_ID=a62f9819f9aa86b34b07973a11f6f844029c1a5a1cfc96e36ee93629ba0194f6
PUSHER_APP_KEY=904493523fc1e3b042fdac7ee119aa44220799fbbb0199259d911a1860ea3c19
PUSHER_APP_SECRET=5ec83d045498cfaeba51bc0bd6a84957a81892383c98a1a2f24e4a6f192f6387
ROOT_USERNAME=
ROOT_USER_EMAIL=
ROOT_USER_PASSWORD=
REGISTRY_URL=ghcr.io
DOCKER_ADDRESS_POOL_BASE=10.0.0.0/8
DOCKER_ADDRESS_POOL_SIZE=24
@@ -0,0 +1,90 @@
services:
coolify:
image: "${REGISTRY_URL:-ghcr.io}/coollabsio/coolify:${LATEST_IMAGE:-latest}"
volumes:
- type: bind
source: /data/coolify/source/.env
target: /var/www/html/.env
read_only: true
- /data/coolify/ssh:/var/www/html/storage/app/ssh
- /data/coolify/applications:/var/www/html/storage/app/applications
- /data/coolify/databases:/var/www/html/storage/app/databases
- /data/coolify/services:/var/www/html/storage/app/services
- /data/coolify/backups:/var/www/html/storage/app/backups
environment:
- APP_ENV=${APP_ENV:-production}
- PHP_MEMORY_LIMIT=${PHP_MEMORY_LIMIT:-256M}
- PHP_FPM_PM_CONTROL=${PHP_FPM_PM_CONTROL:-dynamic}
- PHP_FPM_PM_START_SERVERS=${PHP_FPM_PM_START_SERVERS:-1}
- PHP_FPM_PM_MIN_SPARE_SERVERS=${PHP_FPM_PM_MIN_SPARE_SERVERS:-1}
- PHP_FPM_PM_MAX_SPARE_SERVERS=${PHP_FPM_PM_MAX_SPARE_SERVERS:-10}
env_file:
- /data/coolify/source/.env
ports:
- "${APP_PORT:-8000}:8080"
expose:
- "${APP_PORT:-8000}"
healthcheck:
test: curl --fail http://127.0.0.1:8080/api/health || exit 1
interval: 5s
retries: 10
timeout: 2s
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
soketi:
condition: service_healthy
postgres:
volumes:
- coolify-db:/var/lib/postgresql/data
environment:
POSTGRES_USER: "${DB_USERNAME}"
POSTGRES_PASSWORD: "${DB_PASSWORD}"
POSTGRES_DB: "${DB_DATABASE:-coolify}"
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U ${DB_USERNAME}", "-d", "${DB_DATABASE:-coolify}" ]
interval: 5s
retries: 10
timeout: 2s
redis:
command: redis-server --save 20 1 --loglevel warning --requirepass ${REDIS_PASSWORD}
environment:
REDIS_PASSWORD: "${REDIS_PASSWORD}"
volumes:
- coolify-redis:/data
healthcheck:
test: redis-cli ping
interval: 5s
retries: 10
timeout: 2s
soketi:
image: '${REGISTRY_URL:-ghcr.io}/coollabsio/coolify-realtime:1.0.13'
ports:
- "${SOKETI_PORT:-6001}:6001"
- "6002:6002"
volumes:
- /data/coolify/ssh:/var/www/html/storage/app/ssh
environment:
APP_NAME: "${APP_NAME:-Coolify}"
SOKETI_DEBUG: "${SOKETI_DEBUG:-false}"
SOKETI_DEFAULT_APP_ID: "${PUSHER_APP_ID}"
SOKETI_DEFAULT_APP_KEY: "${PUSHER_APP_KEY}"
SOKETI_DEFAULT_APP_SECRET: "${PUSHER_APP_SECRET}"
SOKETI_HOST: "${SOKETI_HOST:-0.0.0.0}"
healthcheck:
test: [ "CMD-SHELL", "wget -qO- http://127.0.0.1:6001/ready && wget -qO- http://127.0.0.1:6002/ready || exit 1" ]
interval: 5s
retries: 10
timeout: 2s
volumes:
coolify-db:
name: coolify-db
coolify-redis:
name: coolify-redis
networks:
coolify:
external: true
@@ -0,0 +1,37 @@
services:
coolify:
container_name: coolify
restart: always
working_dir: /var/www/html
extra_hosts:
- host.docker.internal:host-gateway
networks:
- coolify
depends_on:
- postgres
- redis
- soketi
postgres:
image: postgres:15-alpine
container_name: coolify-db
restart: always
networks:
- coolify
redis:
image: redis:7-alpine
container_name: coolify-redis
restart: always
networks:
- coolify
soketi:
container_name: coolify-realtime
extra_hosts:
- host.docker.internal:host-gateway
restart: always
networks:
- coolify
networks:
coolify:
name: coolify
driver: bridge
external: false