Compare commits

...

29 Commits

Author SHA1 Message Date
forust 0bad0a817e fix: bad request
Revert "chore: compose cleanup:"

This reverts nextcloud service's changes from commit 45ce789f58.
2026-01-20 15:11:06 +01:00
forust 525fed3b92 Merge pull request 'chore/compose-cleanup' (#8) from chore/compose-cleanup into main
Reviewed-on: #8
2026-01-20 00:17:42 +01:00
forust fe5e5c5e35 fix: aborted connection to portainer 2026-01-20 00:08:18 +01:00
forust 72aa022048 fix: "http plaintext sent to https" 2026-01-20 00:05:10 +01:00
forust f18d4d9be4 chore: use volumes to store data of
- portainer
- headscale
- termix
- uptime-kuma
- dockmon
2026-01-19 23:58:26 +01:00
forust 45ce789f58 chore: compose cleanup:
- Remove TZ envs
- +- unified compose structure
- Minify where possible
- Remove <service>.internal routers
- Remove service specifications where possible
Affected services:
- adguardhome
- authentik
- cfddns
- checkmk
- dockmon
- downtify
- gitea
- glance
- headscale
- homepages
- metube
- nextcloud
- penpot
- portainer
- termix
- traefik
- uptime-kuma

TODO: Move data from directory to volumes
2026-01-19 23:33:50 +01:00
forust d7c05fd058 fix: use webinar links to detect duplicates, supress logspam from telegram bot 2026-01-19 17:01:23 +01:00
forust c13056fba1 Merge pull request 'feat/checkmk' (#7) from feat/checkmk into main
Reviewed-on: #7
2026-01-19 15:59:21 +01:00
forust 5fe8af82d5 Revert "fix: clean up traefik configuration and add redirect middleware"
This reverts commit dc7fe64fbc.
2026-01-19 11:18:36 +01:00
forust 6d97246997 fix: change checkmk container restart policy to 'unless-stopped' 2026-01-19 00:08:16 +01:00
forust 6970279311 fix: remove checkmk port for docker cmk agent, using external agent 2026-01-18 23:09:41 +01:00
forust 02f4e0ab42 chore: switch to named volumes for site storing 2026-01-18 22:39:48 +01:00
forust 4a25622552 Merge branch 'main' of ssh://gitssh.forust.xyz:2221/forust/homelab into feat/checkmk 2026-01-18 19:28:12 +01:00
forust 0138fbd276 fix: update middleware for dev router in glance compose file 2026-01-18 19:24:41 +01:00
forust 94b5f39207 make glance dashboard public again 2026-01-18 00:19:39 +01:00
forust 403e88d548 fix: update NEXTCLOUD_DATADIR path to match new hardware 2026-01-17 17:44:11 +01:00
forust d03a4844fb chore: remove unused tailscale setup 2026-01-17 15:38:27 +01:00
forust 48ff08529e Merge pull request 'feat: add group support for webinar notifier' (#5) from feat/edu-group into main
Reviewed-on: #5
2026-01-14 16:46:37 +01:00
forust 81592b6142 feat: add group support for webinar notifier 2026-01-13 00:24:04 +01:00
forust 9480576966 fix: update bots' code to match .env keys 2026-01-12 15:33:42 +01:00
forust 9b43a9bef4 feat: add traefik configuration for external fileservers 2026-01-09 14:48:42 +01:00
forust 2b03335af5 chore: shorten aio subdomain 2026-01-06 19:04:23 +01:00
forust 1f1e13ff39 WIP: fix: update checkmk configuration for correct routing 2026-01-01 00:25:17 +01:00
forust c80a6c5351 Merge branch 'main' of ssh://gitssh.forust.xyz:2221/forust/homelab into feat/checkmk 2025-12-31 21:19:42 +01:00
forust bfb21adff7 using local directory for storing chkmk data 2025-12-07 22:06:30 +01:00
forust 1c75382a6e fix: replace container_name to avoid misunderstandings 2025-12-07 04:14:56 +01:00
forust 9c5e037567 refactor: switch to official checkmk dockercompose 2025-12-07 04:10:32 +01:00
forust 9f784d2c31 chore: gitignore checkmk's files 2025-12-07 02:59:18 +01:00
forust a07e27bff6 feat: checkmk service 2025-12-07 02:44:12 +01:00
26 changed files with 299 additions and 270 deletions
+3 -1
View File
@@ -2,7 +2,8 @@
sync.ffs_lock sync.ffs_lock
.sync.ffs_db .sync.ffs_db
# Copyparty
*.hist/
# Volumes and data directories # Volumes and data directories
gitea/gitea-db/ gitea/gitea-db/
@@ -36,6 +37,7 @@ homepages/forust_files/.well-known/*
# Traefik files # Traefik files
traefik/letsencrypt/acme.json traefik/letsencrypt/acme.json
traefik/dynamic/fileservers.yml
traefik/logs/* traefik/logs/*
# SSL Certificates # SSL Certificates
+6 -12
View File
@@ -14,8 +14,6 @@ services:
- ./data/work:/opt/adguardhome/work - ./data/work:/opt/adguardhome/work
- ./data/conf:/opt/adguardhome/conf - ./data/conf:/opt/adguardhome/conf
- ./certs:/certs:ro - ./certs:/certs:ro
networks:
- proxy
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.docker.network=proxy" - "traefik.docker.network=proxy"
@@ -25,32 +23,28 @@ services:
- "traefik.http.routers.adguard.rule=Host(`dns.forust.xyz`) || Host(`adguard.forust.xyz`)" - "traefik.http.routers.adguard.rule=Host(`dns.forust.xyz`) || Host(`adguard.forust.xyz`)"
- "traefik.http.routers.adguard.entrypoints=websecure" - "traefik.http.routers.adguard.entrypoints=websecure"
- "traefik.http.routers.adguard.middlewares=security-headers@file" - "traefik.http.routers.adguard.middlewares=security-headers@file"
- "traefik.http.routers.adguard.service=adguard"
- "traefik.http.routers.adguard.tls=true" - "traefik.http.routers.adguard.tls=true"
# Local Router # Local Router
- "traefik.http.routers.adguard-local.rule=Host(`dns.workstation.internal`) || Host(`adguard.internal`) || Host(`adguard.workstation.internal`)" - "traefik.http.routers.adguard-local.rule=Host(`adguard.workstation.internal`) || Host(`dns.workstation.internal`)"
- "traefik.http.routers.adguard-local.entrypoints=websecure" - "traefik.http.routers.adguard-local.entrypoints=websecure"
- "traefik.http.routers.adguard-local.middlewares=security-headers@file" - "traefik.http.routers.adguard-local.middlewares=security-headers@file"
- "traefik.http.routers.adguard-local.service=adguard"
- "traefik.http.routers.adguard-local.tls=true" - "traefik.http.routers.adguard-local.tls=true"
# Dev Router # Dev Router
- "traefik.http.routers.adguard-dev.rule=Host(`dns.gigaforust.internal`) || Host(`adguard.gigaforust.internal`)" - "traefik.http.routers.adguard-dev.rule=Host(`adguard.gigaforust.internal`) Host(`dns.gigaforust.internal`)"
- "traefik.http.routers.adguard-dev.entrypoints=websecure" - "traefik.http.routers.adguard-dev.entrypoints=websecure"
- "traefik.http.routers.adguard-dev.middlewares=security-headers@file" - "traefik.http.routers.adguard-dev.middlewares=security-headers@file"
- "traefik.http.routers.adguard-dev.service=adguard"
- "traefik.http.routers.adguard-dev.tls=true" - "traefik.http.routers.adguard-dev.tls=true"
# DoH Router
# DoH
- "traefik.http.routers.dns.rule=(Host(`dns.forust.xyz`) && PathPrefix(`/dns-query`))" - "traefik.http.routers.dns.rule=(Host(`dns.forust.xyz`) && PathPrefix(`/dns-query`))"
- "traefik.http.routers.dns.entrypoints=websecure" - "traefik.http.routers.dns.entrypoints=websecure"
- "traefik.http.routers.dns.service=adguard"
- "traefik.http.routers.dns.tls.certresolver=letsencrypt" - "traefik.http.routers.dns.tls.certresolver=letsencrypt"
# Glance Metadata
- glance.name=adguard - glance.name=adguard
- glance.url=https://adguard.forust.xyz/ - glance.url=https://adguard.forust.xyz/
- glance.description=AdGuard Home is a network-wide software for blocking ads. - glance.description=AdGuard Home is a network-wide software for blocking ads.
networks:
- proxy
networks: networks:
proxy: proxy:
external: true external: true
+3 -8
View File
@@ -37,12 +37,12 @@ services:
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS} AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:?secret key required} AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:?secret key required}
volumes:
- ./media:/media
- ./custom-templates:/templates
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.docker.network=proxy" - "traefik.docker.network=proxy"
# Services
# - "traefik.http.services.authentik-server.loadbalancer.server.port=9443"
- "traefik.http.services.authentik-server.loadbalancer.server.port=9000" - "traefik.http.services.authentik-server.loadbalancer.server.port=9000"
# Prod Router # Prod Router
@@ -51,23 +51,18 @@ services:
- "traefik.http.routers.authentik-server.middlewares=security-headers@file" - "traefik.http.routers.authentik-server.middlewares=security-headers@file"
- "traefik.http.routers.authentik-server.service=authentik-server" - "traefik.http.routers.authentik-server.service=authentik-server"
- "traefik.http.routers.authentik-server.tls=true" - "traefik.http.routers.authentik-server.tls=true"
# Local Router # Local Router
- "traefik.http.routers.authentik-server-local.rule=Host(`auth.workstation.internal`) || Host(`auth-dashboard.internal`)" - "traefik.http.routers.authentik-server-local.rule=Host(`auth.workstation.internal`) || Host(`auth-dashboard.internal`)"
- "traefik.http.routers.authentik-server-local.entrypoints=websecure" - "traefik.http.routers.authentik-server-local.entrypoints=websecure"
- "traefik.http.routers.authentik-server-local.middlewares=security-headers@file" - "traefik.http.routers.authentik-server-local.middlewares=security-headers@file"
- "traefik.http.routers.authentik-server-local.service=authentik-server" - "traefik.http.routers.authentik-server-local.service=authentik-server"
- "traefik.http.routers.authentik-server-local.tls=true" - "traefik.http.routers.authentik-server-local.tls=true"
# Dev Router # Dev Router
- "traefik.http.routers.authentik-server-dev.rule=Host(`auth.gigaforust.internal`)" - "traefik.http.routers.authentik-server-dev.rule=Host(`auth.gigaforust.internal`)"
- "traefik.http.routers.authentik-server-dev.entrypoints=websecure" - "traefik.http.routers.authentik-server-dev.entrypoints=websecure"
- "traefik.http.routers.authentik-server-dev.middlewares=security-headers@file" - "traefik.http.routers.authentik-server-dev.middlewares=security-headers@file"
- "traefik.http.routers.authentik-server-dev.service=authentik-server" - "traefik.http.routers.authentik-server-dev.service=authentik-server"
- "traefik.http.routers.authentik-server-dev.tls=true" - "traefik.http.routers.authentik-server-dev.tls=true"
volumes:
- ./media:/media
- ./custom-templates:/templates
networks: networks:
- proxy - proxy
- authentik - authentik
+1 -1
View File
@@ -2,6 +2,7 @@ services:
cloudflare-ddns: cloudflare-ddns:
image: timothyjmiller/cloudflare-ddns:latest image: timothyjmiller/cloudflare-ddns:latest
container_name: cloudflare-ddns container_name: cloudflare-ddns
restart: unless-stopped
security_opt: security_opt:
- no-new-privileges:true - no-new-privileges:true
network_mode: 'host' network_mode: 'host'
@@ -10,4 +11,3 @@ services:
- PGID=1000 - PGID=1000
volumes: volumes:
- ./config.json:/config.json - ./config.json:/config.json
restart: unless-stopped
+2
View File
@@ -0,0 +1,2 @@
CMK_PASSWORD=password
TZ=Europe/Berlin
+42
View File
@@ -0,0 +1,42 @@
services:
checkmk:
image: "checkmk/check-mk-raw:2.4.0-latest"
container_name: "checkmk"
restart: unless-stopped
# ports:
# - 5000:5000
# - 6776:8000
volumes:
- sites:/omd/sites
tmpfs:
- /opt/omd/sites/cmk/tmp:uid=1000,gid=1000
environment:
- CMK_PASSWORD=${CMK_PASSWORD:-password}
- CMK_SITE_ID=cmk
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.services.checkmk.loadbalancer.server.port=5000"
# Prod Router
- "traefik.http.routers.checkmk.rule=Host(`cmk.forust.xyz`)"
- "traefik.http.routers.checkmk.entrypoints=websecure"
- "traefik.http.routers.checkmk.middlewares=security-headers@file"
- "traefik.http.routers.checkmk.tls=true"
# Local Router
- "traefik.http.routers.checkmk-local.rule=Host(`cmk.workstation.internal`)"
- "traefik.http.routers.checkmk-local.entrypoints=websecure"
- "traefik.http.routers.checkmk-local.middlewares=security-headers@file"
- "traefik.http.routers.checkmk-local.tls=true"
# Dev Router
- "traefik.http.routers.checkmk-dev.rule=Host(`cmk.gigaforust.internal`)"
- "traefik.http.routers.checkmk-dev.middlewares=security-headers@file"
- "traefik.http.routers.checkmk-dev.entrypoints=websecure"
- "traefik.http.routers.checkmk-dev.tls=true"
networks:
- proxy
networks:
proxy:
external: true
volumes:
sites:
+12 -16
View File
@@ -3,23 +3,22 @@ services:
image: darthnorse/dockmon:latest image: darthnorse/dockmon:latest
container_name: dockmon container_name: dockmon
restart: unless-stopped restart: unless-stopped
ports: # ports:
- 8000:443 # - 8000:443
environment:
- TZ=Europe/Bratislava
volumes: volumes:
- ./data:/app/data - data:/app/data
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
healthcheck: healthcheck:
test: [ "CMD", "curl", "-k", "-f", "https://localhost:443/health" ] test: [ "CMD", "curl", "-k", "-f", "https://localhost:443/health" ]
interval: 30s interval: 30s
timeout: 10s timeout: 10s
retries: 3 retries: 3
networks:
- proxy
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.docker.network=proxy" - "traefik.docker.network=proxy"
- "traefik.http.services.dockmon.loadbalancer.server.port=443"
- "traefik.http.services.dockmon.loadbalancer.server.scheme=https"
- "traefik.http.services.dockmon.loadbalancer.serverstransport=insecureTransport@file"
# Prod Router # Prod Router
- "traefik.http.routers.dockmon.rule=Host(`dockmon.forust.xyz`)" - "traefik.http.routers.dockmon.rule=Host(`dockmon.forust.xyz`)"
@@ -27,28 +26,25 @@ services:
- "traefik.http.routers.dockmon.middlewares=security-chain@file" - "traefik.http.routers.dockmon.middlewares=security-chain@file"
- "traefik.http.routers.dockmon.service=dockmon" - "traefik.http.routers.dockmon.service=dockmon"
- "traefik.http.routers.dockmon.tls=true" - "traefik.http.routers.dockmon.tls=true"
- "traefik.http.services.dockmon.loadbalancer.server.port=443"
- "traefik.http.services.dockmon.loadbalancer.server.scheme=https"
- "traefik.http.services.dockmon.loadbalancer.serverstransport=insecureTransport@file"
# Local Router # Local Router
- "traefik.http.routers.dockmon-local.rule=Host(`dockmon.workstation.internal`) || Host(`dockmon.internal`)" - "traefik.http.routers.dockmon-local.rule=Host(`dockmon.workstation.internal`)"
- "traefik.http.routers.dockmon-local.entrypoints=websecure" - "traefik.http.routers.dockmon-local.entrypoints=websecure"
- "traefik.http.routers.dockmon-local.middlewares=security-headers@file" - "traefik.http.routers.dockmon-local.middlewares=security-headers@file"
- "traefik.http.routers.dockmon-local.service=dockmon"
- "traefik.http.routers.dockmon-local.tls=true" - "traefik.http.routers.dockmon-local.tls=true"
# Dev Router # Dev Router
- "traefik.http.routers.dockmon-dev.rule=Host(`dockmon.gigaforust.internal`)" - "traefik.http.routers.dockmon-dev.rule=Host(`dockmon.gigaforust.internal`)"
- "traefik.http.routers.dockmon-dev.entrypoints=websecure" - "traefik.http.routers.dockmon-dev.entrypoints=websecure"
- "traefik.http.routers.dockmon-dev.middlewares=security-chain@file" - "traefik.http.routers.dockmon-dev.middlewares=security-chain@file"
- "traefik.http.routers.dockmon-dev.service=dockmon"
- "traefik.http.routers.dockmon-dev.tls=true" - "traefik.http.routers.dockmon-dev.tls=true"
# Glance Metadata
- glance.name=dockmon - glance.name=dockmon
- glance.url=https://dockmon.forust.xyz/ - glance.url=https://dockmon.forust.xyz/
- glance.description=Dockmon is a lightweight Docker container monitoring and management tool with a user-friendly web interface. - glance.description=Dockmon is a lightweight Docker container monitoring and management tool with a user-friendly web interface.
networks:
- proxy
volumes:
data:
networks: networks:
proxy: proxy:
external: true external: true
+3 -9
View File
@@ -4,36 +4,30 @@ services:
image: ghcr.io/henriquesebastiao/downtify:latest image: ghcr.io/henriquesebastiao/downtify:latest
# ports: # ports:
# - '7077:8000' # - '7077:8000'
volumes:
- ./Downtify_downloads:/downloads
labels: labels:
- traefik.enable=true - traefik.enable=true
- traefik.docker.network=proxy
- traefik.http.services.downtify.loadbalancer.server.port=8000 - traefik.http.services.downtify.loadbalancer.server.port=8000
# Prod Router # Prod Router
- traefik.http.routers.downtify.rule=Host(`downtify.forust.xyz`) - traefik.http.routers.downtify.rule=Host(`downtify.forust.xyz`)
- traefik.http.routers.downtify.entrypoints=websecure - traefik.http.routers.downtify.entrypoints=websecure
- traefik.http.routers.downtify.middlewares=security-chain@file - traefik.http.routers.downtify.middlewares=security-chain@file
- traefik.http.routers.downtify.service=downtify
- traefik.http.routers.downtify.tls=true - traefik.http.routers.downtify.tls=true
# Local Router # Local Router
- traefik.http.routers.downtify-local.rule=Host(`downtify.workstation.internal`) || Host(`downtify.internal`) - traefik.http.routers.downtify-local.rule=Host(`downtify.workstation.internal`) || Host(`downtify.internal`)
- traefik.http.routers.downtify-local.entrypoints=websecure - traefik.http.routers.downtify-local.entrypoints=websecure
- traefik.http.routers.downtify-local.middlewares=security-headers@file - traefik.http.routers.downtify-local.middlewares=security-headers@file
- traefik.http.routers.downtify-local.service=downtify
- traefik.http.routers.downtify-local.tls=true - traefik.http.routers.downtify-local.tls=true
# Dev Router # Dev Router
- traefik.http.routers.downtify-dev.rule=Host(`downtify.gigaforust.internal`) - traefik.http.routers.downtify-dev.rule=Host(`downtify.gigaforust.internal`)
- traefik.http.routers.downtify-dev.entrypoints=websecure - traefik.http.routers.downtify-dev.entrypoints=websecure
- traefik.http.routers.downtify-dev.middlewares=security-chain@file - traefik.http.routers.downtify-dev.middlewares=security-chain@file
- traefik.http.routers.downtify-dev.service=downtify
- traefik.http.routers.downtify-dev.tls=true - traefik.http.routers.downtify-dev.tls=true
networks: networks:
- proxy - proxy
volumes:
- ./Downtify_downloads:/downloads
networks: networks:
proxy: proxy:
external: true external: true
+20 -9
View File
@@ -12,15 +12,26 @@ logging.basicConfig(
) )
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# Load configuration # Load configuration (adapted to .env keys)
LOGIN = os.getenv('EDU_LOGIN') def _env(key, default=None):
PASSWORD = os.getenv('EDU_PASSWORD') v = os.getenv(key, default)
URL_LOGIN = os.getenv('EDU_URL_LOGIN', 'https://edu.edu.vn.ua/user/login') if isinstance(v, str) and len(v) >= 2 and ((v[0] == '"' and v[-1] == '"') or (v[0] == "'" and v[-1] == "'")):
URL_VERIFY = os.getenv('EDU_URL_VERIFY', 'https://edu.edu.vn.ua/course/userlist') return v[1:-1]
INTERVAL = int(os.getenv('PHPSESSID_INTERVAL', 10)) return v
USER_AGENT = os.getenv('USER_AGENT', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36')
REDIS_HOST = os.getenv('REDIS_HOST', 'redis') LOGIN = _env('KEEPER_LOGIN')
REDIS_PORT = int(os.getenv('REDIS_PORT', 6379)) PASSWORD = _env('KEEPER_PASSWORD')
EDU_BASE = _env('EDU_URL_BASE', 'https://edu.edu.vn.ua')
EDU_LOGIN_PATH = _env('EDU_URL_LOGIN', '/user/login')
EDU_COURSES_PATH = _env('EDU_URL_COURSES', '/course/userlist')
URL_LOGIN = f"{EDU_BASE.rstrip('/')}/{EDU_LOGIN_PATH.lstrip('/')}"
URL_VERIFY = f"{EDU_BASE.rstrip('/')}/{EDU_COURSES_PATH.lstrip('/')}"
INTERVAL = int(_env('KEEPER_INTERVAL', 10))
USER_AGENT = _env('USER_AGENT', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36')
REDIS_HOST = _env('REDIS_HOST', 'redis')
REDIS_PORT = int(_env('REDIS_PORT', 6379))
SUCCESS_FILE = '/tmp/last_success' SUCCESS_FILE = '/tmp/last_success'
+107 -31
View File
@@ -3,7 +3,8 @@ import logging
import redis import redis
import json import json
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup, ChatMember
from telegram.constants import ChatType
from telegram.ext import Application, CommandHandler, CallbackQueryHandler, ContextTypes from telegram.ext import Application, CommandHandler, CallbackQueryHandler, ContextTypes
from playwright.async_api import async_playwright from playwright.async_api import async_playwright
@@ -14,22 +15,36 @@ logging.basicConfig(
) )
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# Suppress HTTP request logs
logging.getLogger('urllib3').setLevel(logging.WARNING)
logging.getLogger('httpx').setLevel(logging.WARNING)
logging.getLogger('telegram.ext._application').setLevel(logging.WARNING)
# Load environment variables # Load environment variables
WEBINAR_URL = os.getenv('WEBINAR_URL', 'https://edu.edu.vn.ua/webinar/useractive') def _env(key, default=None):
WEBINAR_CHECK_INTERVAL = int(os.getenv('WEBINAR_CHECK_INTERVAL', 60)) v = os.getenv(key, default)
REDIS_HOST = os.getenv('REDIS_HOST', 'redis') if isinstance(v, str) and len(v) >= 2 and ((v[0] == '"' and v[-1] == '"') or (v[0] == "'" and v[-1] == "'")):
REDIS_PORT = int(os.getenv('REDIS_PORT', 6379)) return v[1:-1]
PLAYWRIGHT_WS = os.getenv('PLAYWRIGHT_WS', 'ws://playwright-service:3000/ws') return v
USER_AGENT = os.getenv('USER_AGENT', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36')
WEBINAR_TELEGRAM_TOKEN = os.getenv('WEBINAR_TELEGRAM_TOKEN') EDU_BASE = _env('EDU_URL_BASE', 'https://edu.edu.vn.ua')
ADMIN_ID = int(os.getenv('WEBINAR_ADMIN_ID', '0')) EDU_WEBINAR_PATH = _env('EDU_URL_WEBINAR', '/webinar/useractive')
WEBINAR_URL = f"{EDU_BASE.rstrip('/')}/{EDU_WEBINAR_PATH.lstrip('/')}"
WEBINAR_CHECK_INTERVAL = int(_env('WEBINAR_CHECK_INTERVAL', 60))
REDIS_HOST = _env('REDIS_HOST', 'redis')
REDIS_PORT = int(_env('REDIS_PORT', 6379))
PLAYWRIGHT_WS = _env('PLAYWRIGHT_WS', 'ws://playwright-service:3000/ws')
USER_AGENT = _env('USER_AGENT', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36')
WEBINAR_TELEGRAM_TOKEN = _env('WEBINAR_TELEGRAM_TOKEN')
ADMIN_ID = int(_env('WEBINAR_ADMIN_ID', '0'))
# Redis Keys # Redis Keys
KEY_WHITELIST = "bot:whitelist" KEY_WHITELIST = "bot:whitelist"
KEY_WHITELIST_ENABLED = "bot:whitelist_enabled" KEY_WHITELIST_ENABLED = "bot:whitelist_enabled"
KEY_SUBSCRIBERS = "bot:subscribers" KEY_SUBSCRIBERS = "bot:subscribers"
KEY_PHPSESSID = "EDU_PHPSESSID" KEY_PHPSESSID = "EDU_PHPSESSID"
KEY_WEBINAR_HISTORY = "bot:webinar_history" # Stores last 5 webinars KEY_WEBINAR_HISTORY = "bot:webinar_history" # Stores last 3 webinars
# Initialize Redis # Initialize Redis
try: try:
@@ -48,7 +63,7 @@ TRANSLATIONS = {
'welcome_admin': "\n\n👑 <b>Режим администратора активен</b>", 'welcome_admin': "\n\n👑 <b>Режим администратора активен</b>",
'access_denied': "⛔ Доступ запрещен. Вас нет в белом списке.", 'access_denied': "⛔ Доступ запрещен. Вас нет в белом списке.",
'help_title': "🤖 <b>Помощь по боту</b>\n\n", 'help_title': "🤖 <b>Помощь по боту</b>\n\n",
'help_commands': "/start - Подписаться на уведомления\n/help - Показать это сообщение\n/language - Сменить язык", 'help_commands': "/start - Подписаться на уведомления\n/stop - Отписаться от уведомлений\n/help - Показать это сообщение\n/language - Сменить язык",
'help_admin': "\n<b>Команды администратора:</b>\n/adduser [user_id] - Добавить пользователя в белый список\n/removeuser [user_id] - Удалить пользователя из белого списка\nИли используйте панель ниже для управления настройками.", 'help_admin': "\n<b>Команды администратора:</b>\n/adduser [user_id] - Добавить пользователя в белый список\n/removeuser [user_id] - Удалить пользователя из белого списка\nИли используйте панель ниже для управления настройками.",
'admin_only': "⛔ Только для администратора!", 'admin_only': "⛔ Только для администратора!",
'user_added': "✅ Пользователь {user_id} добавлен в белый список", 'user_added': "✅ Пользователь {user_id} добавлен в белый список",
@@ -79,13 +94,15 @@ TRANSLATIONS = {
'flag_ru': "🇷🇺 Русский", 'flag_ru': "🇷🇺 Русский",
'flag_uk': "🇺🇦 Українська", 'flag_uk': "🇺🇦 Українська",
'flag_en': "🇬🇧 English", 'flag_en': "🇬🇧 English",
'history_cleared': "✅ История вебинаров очищена",
'history_clear_failed': "❌ Ошибка при очистке истории",
}, },
'uk': { 'uk': {
'welcome': "👋 Привіт, {name}!\n\nЯ бот-сповіщувач про вебінари. Я повідомлятиму вас, коли з'явиться новий вебінар.\nВи підписані на сповіщення.", 'welcome': "👋 Привіт, {name}!\n\nЯ бот-сповіщувач про вебінари. Я повідомлятиму вас, коли з'явиться новий вебінар.\nВи підписані на сповіщення.",
'welcome_admin': "\n\n👑 <b>Режим адміністратора активний</b>", 'welcome_admin': "\n\n👑 <b>Режим адміністратора активний</b>",
'access_denied': "⛔ Доступ заборонено. Вас немає в білому списку.", 'access_denied': "⛔ Доступ заборонено. Вас немає в білому списку.",
'help_title': "🤖 <b>Довідка по боту</b>\n\n", 'help_title': "🤖 <b>Довідка по боту</b>\n\n",
'help_commands': "/start - Підписатися на сповіщення\n/help - Показати це повідомлення\n/language - Змінити мову", 'help_commands': "/start - Підписатися на сповіщення\n/stop - Відписатися від сповіщень\n/help - Показати це повідомлення\n/language - Змінити мову",
'help_admin': "\n<b>Команди адміністратора:</b>\n/adduser [user_id] - Додати користувача до білого списку\n/removeuser [user_id] - Видалити користувача з білого списку\nАбо використовуйте панель нижче для керування налаштуваннями.", 'help_admin': "\n<b>Команди адміністратора:</b>\n/adduser [user_id] - Додати користувача до білого списку\n/removeuser [user_id] - Видалити користувача з білого списку\nАбо використовуйте панель нижче для керування налаштуваннями.",
'admin_only': "⛔ Тільки для адміністратора!", 'admin_only': "⛔ Тільки для адміністратора!",
'user_added': "✅ Користувач {user_id} доданий до білого списку", 'user_added': "✅ Користувач {user_id} доданий до білого списку",
@@ -116,13 +133,15 @@ TRANSLATIONS = {
'flag_ru': "🇷🇺 Русский", 'flag_ru': "🇷🇺 Русский",
'flag_uk': "🇺🇦 Українська", 'flag_uk': "🇺🇦 Українська",
'flag_en': "🇬🇧 English", 'flag_en': "🇬🇧 English",
'history_cleared': "✅ Історія вебінарів очищена",
'history_clear_failed': "❌ Помилка при очищенні історії",
}, },
'en': { 'en': {
'welcome': "👋 Hello, {name}!\n\nI am the Webinar Checker Bot. I will notify you when a new webinar appears.\nYou have been subscribed to notifications.", 'welcome': "👋 Hello, {name}!\n\nI am the Webinar Checker Bot. I will notify you when a new webinar appears.\nYou have been subscribed to notifications.",
'welcome_admin': "\n\n👑 <b>Admin Mode Active</b>", 'welcome_admin': "\n\n👑 <b>Admin Mode Active</b>",
'access_denied': "⛔ Access denied. You are not on the whitelist.", 'access_denied': "⛔ Access denied. You are not on the whitelist.",
'help_title': "🤖 <b>Bot Help</b>\n\n", 'help_title': "🤖 <b>Bot Help</b>\n\n",
'help_commands': "/start - Subscribe to notifications\n/help - Show this message\n/language - Change language", 'help_commands': "/start - Subscribe to notifications\n/stop - Unsubscribe from notifications\n/help - Show this message\n/language - Change language",
'help_admin': "\n<b>Admin Commands:</b>\n/adduser [user_id] - Add user to whitelist\n/removeuser [user_id] - Remove user from whitelist\nOr use the panel below to manage settings.", 'help_admin': "\n<b>Admin Commands:</b>\n/adduser [user_id] - Add user to whitelist\n/removeuser [user_id] - Remove user from whitelist\nOr use the panel below to manage settings.",
'admin_only': "⛔ Admin only!", 'admin_only': "⛔ Admin only!",
'user_added': "✅ User {user_id} added to whitelist", 'user_added': "✅ User {user_id} added to whitelist",
@@ -153,6 +172,8 @@ TRANSLATIONS = {
'flag_ru': "🇷🇺 Русский", 'flag_ru': "🇷🇺 Русский",
'flag_uk': "🇺🇦 Українська", 'flag_uk': "🇺🇦 Українська",
'flag_en': "🇬🇧 English", 'flag_en': "🇬🇧 English",
'history_cleared': "✅ Webinar history cleared",
'history_clear_failed': "❌ Error clearing history",
} }
} }
@@ -203,6 +224,21 @@ def is_whitelisted(user_id: int) -> bool:
return redis_client.sismember(KEY_WHITELIST, str(user_id)) return redis_client.sismember(KEY_WHITELIST, str(user_id))
async def is_group_admin(update: Update, context: ContextTypes.DEFAULT_TYPE) -> bool:
"""Check if the user is an administrator in the group."""
user = update.effective_user
chat = update.effective_chat
if chat.type in [ChatType.PRIVATE, "private"]:
return True
try:
member = await context.bot.get_chat_member(chat.id, user.id)
return member.status in [ChatMember.OWNER, ChatMember.ADMINISTRATOR]
except Exception as e:
logger.error(f"Failed to check admin status: {e}")
return False
def get_admin_keyboard(user_id: int): def get_admin_keyboard(user_id: int):
"""Generate admin panel keyboard.""" """Generate admin panel keyboard."""
whitelist_enabled = redis_client.get(KEY_WHITELIST_ENABLED) != "0" whitelist_enabled = redis_client.get(KEY_WHITELIST_ENABLED) != "0"
@@ -221,19 +257,21 @@ def get_admin_keyboard(user_id: int):
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /start command.""" """Handle /start command."""
user = update.effective_user user = update.effective_user
logger.info(f"User {user.id} ({user.username}) started the bot.") chat = update.effective_chat
logger.info(f"User {user.id} ({user.username}) started the bot in chat {chat.id} ({chat.type}).")
# Check whitelist - MUST be the user executing the command
if not is_whitelisted(user.id): if not is_whitelisted(user.id):
await update.message.reply_text(t(user.id, 'access_denied')) await update.message.reply_text(t(user.id, 'access_denied'))
return return
# Add to subscribers # Add to subscribers (Chat ID!)
redis_client.sadd(KEY_SUBSCRIBERS, user.id) redis_client.sadd(KEY_SUBSCRIBERS, chat.id)
msg = t(user.id, 'welcome', name=user.first_name) msg = t(chat.id, 'welcome', name=user.first_name)
if user.id == ADMIN_ID: if user.id == ADMIN_ID and chat.type == "private":
msg += t(user.id, 'welcome_admin') msg += t(chat.id, 'welcome_admin')
await update.message.reply_text(msg, parse_mode='HTML', reply_markup=get_admin_keyboard(user.id)) await update.message.reply_text(msg, parse_mode='HTML', reply_markup=get_admin_keyboard(user.id))
else: else:
await update.message.reply_text(msg, parse_mode='HTML') await update.message.reply_text(msg, parse_mode='HTML')
@@ -241,19 +279,39 @@ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE): async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /help command.""" """Handle /help command."""
user_id = update.effective_user.id user_id = update.effective_user.id
msg = t(user_id, 'help_title') + t(user_id, 'help_commands') chat_id = update.effective_chat.id
msg = t(chat_id, 'help_title') + t(chat_id, 'help_commands')
if user_id == ADMIN_ID: if user_id == ADMIN_ID and update.effective_chat.type == "private":
msg += t(user_id, 'help_admin') msg += t(chat_id, 'help_admin')
await update.message.reply_text(msg, parse_mode='HTML', reply_markup=get_admin_keyboard(user_id)) await update.message.reply_text(msg, parse_mode='HTML', reply_markup=get_admin_keyboard(user_id))
else: else:
await update.message.reply_text(msg, parse_mode='HTML') await update.message.reply_text(msg, parse_mode='HTML')
async def stop_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /stop command (unsubscribe)."""
user = update.effective_user
chat = update.effective_chat
# Permission check: Whitelisted user OR Group Admin
if not (is_whitelisted(user.id) or await is_group_admin(update, context)):
await update.message.reply_text(t(chat.id, 'access_denied')) # Or specific "admin only" message
return
redis_client.srem(KEY_SUBSCRIBERS, chat.id)
await update.message.reply_text(t(chat.id, 'whitelist_disabled').replace(" whitelist", " notifications").replace("Білий список", "Сповіщення").replace("Белый список", "Уведомления") if chat.id else "Unsubscribed")
async def language_command(update: Update, context: ContextTypes.DEFAULT_TYPE): async def language_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /language command.""" """Handle /language command."""
user_id = update.effective_user.id user = update.effective_user
chat = update.effective_chat
# Permission check for groups
if not (is_whitelisted(user.id) or await is_group_admin(update, context)):
return
await update.message.reply_text( await update.message.reply_text(
t(user_id, 'select_language'), t(chat.id, 'select_language'),
parse_mode='HTML', parse_mode='HTML',
reply_markup=get_language_keyboard() reply_markup=get_language_keyboard()
) )
@@ -303,6 +361,21 @@ async def remove_user(update: Update, context: ContextTypes.DEFAULT_TYPE):
except ValueError: except ValueError:
await update.message.reply_text(t(admin_id, 'invalid_user_id')) await update.message.reply_text(t(admin_id, 'invalid_user_id'))
async def clear_history(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Clear webinar history (admin only)."""
admin_id = update.effective_user.id
if admin_id != ADMIN_ID:
await update.message.reply_text(t(admin_id, 'admin_only'))
return
try:
redis_client.delete(KEY_WEBINAR_HISTORY)
await update.message.reply_text(t(admin_id, 'history_cleared'))
logger.info("Admin cleared webinar history")
except Exception as e:
logger.error(f"Failed to clear history: {e}")
await update.message.reply_text(t(admin_id, 'history_clear_failed'))
# --- Admin Callbacks --- # --- Admin Callbacks ---
async def admin_callback(update: Update, context: ContextTypes.DEFAULT_TYPE): async def admin_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
@@ -363,9 +436,9 @@ async def language_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
# --- Webinar Checking Job --- # --- Webinar Checking Job ---
def get_webinar_key(name: str, url: str) -> str: def get_webinar_key(url: str) -> str:
"""Generate unique key for a webinar based on name and URL.""" """Generate unique key for a webinar based on URL."""
return f"{name}|{url}" return url
def get_stored_webinars() -> list: def get_stored_webinars() -> list:
"""Get list of stored webinar keys from Redis.""" """Get list of stored webinar keys from Redis."""
@@ -378,9 +451,9 @@ def get_stored_webinars() -> list:
return [] return []
def store_webinars(webinar_keys: list): def store_webinars(webinar_keys: list):
"""Store up to 5 most recent webinar keys in Redis.""" """Store up to 3 most recent webinar keys in Redis."""
# Keep only last 5 # Keep only last 3
webinar_keys = webinar_keys[-5:] webinar_keys = webinar_keys[-3:]
try: try:
redis_client.set(KEY_WEBINAR_HISTORY, json.dumps(webinar_keys)) redis_client.set(KEY_WEBINAR_HISTORY, json.dumps(webinar_keys))
logger.info(f"Stored {len(webinar_keys)} webinar(s) in history") logger.info(f"Stored {len(webinar_keys)} webinar(s) in history")
@@ -515,7 +588,7 @@ async def check_webinars_job(context: ContextTypes.DEFAULT_TYPE):
current_keys = [] current_keys = []
for webinar in current_webinars: for webinar in current_webinars:
key = get_webinar_key(webinar['name'], webinar['url']) key = get_webinar_key(webinar['url'])
current_keys.append(key) current_keys.append(key)
if key not in stored_keys: if key not in stored_keys:
@@ -535,6 +608,7 @@ async def check_webinars_job(context: ContextTypes.DEFAULT_TYPE):
for sub_id in subscribers: for sub_id in subscribers:
try: try:
# Build message in user's language # Build message in user's language
# sub_id comes from redis set as string, convert to int for translation lookup
webinar_items = "\n\n".join([ webinar_items = "\n\n".join([
t(int(sub_id), 'webinar_item', name=w['name'], url=w['url']) t(int(sub_id), 'webinar_item', name=w['name'], url=w['url'])
for w in new_webinars for w in new_webinars
@@ -569,10 +643,12 @@ def main():
# Handlers # Handlers
app.add_handler(CommandHandler("start", start)) app.add_handler(CommandHandler("start", start))
app.add_handler(CommandHandler("stop", stop_command))
app.add_handler(CommandHandler("help", help_command)) app.add_handler(CommandHandler("help", help_command))
app.add_handler(CommandHandler("language", language_command)) app.add_handler(CommandHandler("language", language_command))
app.add_handler(CommandHandler("adduser", add_user)) app.add_handler(CommandHandler("adduser", add_user))
app.add_handler(CommandHandler("removeuser", remove_user)) app.add_handler(CommandHandler("removeuser", remove_user))
app.add_handler(CommandHandler("clearhistory", clear_history))
# Callback handlers - language selection first, then admin panel # Callback handlers - language selection first, then admin panel
app.add_handler(CallbackQueryHandler(language_callback, pattern="^lang_")) app.add_handler(CallbackQueryHandler(language_callback, pattern="^lang_"))
+10 -16
View File
@@ -2,6 +2,7 @@ services:
server: server:
image: docker.gitea.com/gitea:1.25.1 image: docker.gitea.com/gitea:1.25.1
container_name: gitea container_name: gitea
restart: always
environment: environment:
- USER_UID=1000 - USER_UID=1000
- USER_GID=1000 - USER_GID=1000
@@ -24,10 +25,6 @@ services:
- GITEA__mailer__PROTOCOL=SMTP - GITEA__mailer__PROTOCOL=SMTP
- GITEA__service__REGISTER_EMAIL_CONFIRM=true - GITEA__service__REGISTER_EMAIL_CONFIRM=true
- GITEA__service__ENABLE_NOTIFY_MAIL=true - GITEA__service__ENABLE_NOTIFY_MAIL=true
restart: always
networks:
- gitea-db
- proxy
volumes: volumes:
- ./gitea-data:/data - ./gitea-data:/data
- /etc/timezone:/etc/timezone:ro - /etc/timezone:/etc/timezone:ro
@@ -35,36 +32,34 @@ services:
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.docker.network=proxy" - "traefik.docker.network=proxy"
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
# Prod Router # Prod Router
- "traefik.http.routers.gitea.rule=Host(`gitea.forust.xyz`)" - "traefik.http.routers.gitea.rule=Host(`gitea.forust.xyz`)"
- "traefik.http.routers.gitea.entrypoints=websecure" - "traefik.http.routers.gitea.entrypoints=websecure"
- "traefik.http.routers.gitea.middlewares=security-headers@file" - "traefik.http.routers.gitea.middlewares=security-headers@file"
- "traefik.http.routers.gitea.service=gitea"
- "traefik.http.routers.gitea.tls=true" - "traefik.http.routers.gitea.tls=true"
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
# Local Router # Local Router
- "traefik.http.routers.gitea-local.rule=Host(`gitea.workstation.internal`) || Host(`gitea.internal`)" - "traefik.http.routers.gitea-local.rule=Host(`gitea.workstation.internal`)"
- "traefik.http.routers.gitea-local.entrypoints=websecure" - "traefik.http.routers.gitea-local.entrypoints=websecure"
- "traefik.http.routers.gitea-local.middlewares=security-headers@file" - "traefik.http.routers.gitea-local.middlewares=security-headers@file"
- "traefik.http.routers.gitea-local.service=gitea"
- "traefik.http.routers.gitea-local.tls=true" - "traefik.http.routers.gitea-local.tls=true"
# Dev Router # Dev Router
- "traefik.http.routers.gitea-dev.rule=Host(`gitea.gigaforust.internal`)" - "traefik.http.routers.gitea-dev.rule=Host(`gitea.gigaforust.internal`)"
- "traefik.http.routers.gitea-dev.entrypoints=websecure" - "traefik.http.routers.gitea-dev.entrypoints=websecure"
- "traefik.http.routers.gitea-dev.middlewares=security-headers@file" - "traefik.http.routers.gitea-dev.middlewares=security-headers@file"
- "traefik.http.routers.gitea-dev.service=gitea"
- "traefik.http.routers.gitea-dev.tls=true" - "traefik.http.routers.gitea-dev.tls=true"
# SSH Router
- "traefik.tcp.services.gitea.loadbalancer.server.port=22"
- "traefik.tcp.routers.gitea.entrypoints=ssh" - "traefik.tcp.routers.gitea.entrypoints=ssh"
- "traefik.tcp.routers.gitea.rule=HostSNI(`*`)" - "traefik.tcp.routers.gitea.rule=HostSNI(`*`)"
- "traefik.tcp.services.gitea.loadbalancer.server.port=22"
ports: ports:
- "2221:22" - "2221:22"
networks:
- gitea-db
- proxy
depends_on: depends_on:
- db - db
db: db:
image: docker.io/library/postgres:14 image: docker.io/library/postgres:14
restart: always restart: always
@@ -72,11 +67,10 @@ services:
- POSTGRES_USER=gitea - POSTGRES_USER=gitea
- POSTGRES_PASSWORD=gitea - POSTGRES_PASSWORD=gitea
- POSTGRES_DB=gitea - POSTGRES_DB=gitea
networks:
- gitea-db
volumes: volumes:
- ./gitea-db/:/var/lib/postgresql/data - ./gitea-db/:/var/lib/postgresql/data
networks:
- gitea-db
networks: networks:
gitea-db: gitea-db:
external: false external: false
+4 -8
View File
@@ -12,29 +12,25 @@ services:
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.docker.network=proxy" - "traefik.docker.network=proxy"
# FIXME: traefik.services.glance.loadbalancer.server.port ??
# Prod Router # Prod Router
- "traefik.http.routers.glance.rule=Host(`glance.forust.xyz`)" - "traefik.http.routers.glance.rule=Host(`glance.forust.xyz`)"
- "traefik.http.routers.glance.entrypoints=websecure" - "traefik.http.routers.glance.entrypoints=websecure"
- "traefik.http.routers.glance.middlewares=security-chain@file" - "traefik.http.routers.glance.middlewares=security-headers@file"
- "traefik.http.routers.glance.tls=true" - "traefik.http.routers.glance.tls=true"
# Local Router # Local Router
- "traefik.http.routers.glance-local.rule=Host(`glance.workstation.internal`) || Host(`glance.internal`)" - "traefik.http.routers.glance-local.rule=Host(`glance.workstation.internal`)"
- "traefik.http.routers.glance-local.entrypoints=websecure" - "traefik.http.routers.glance-local.entrypoints=websecure"
- "traefik.http.routers.glance-local.middlewares=security-headers@file" - "traefik.http.routers.glance-local.middlewares=security-headers@file"
- "traefik.http.routers.glance-local.tls=true" - "traefik.http.routers.glance-local.tls=true"
# Dev Router # Dev Router
- "traefik.http.routers.glance-dev.rule=Host(`glance.gigaforust.internal`)" - "traefik.http.routers.glance-dev.rule=Host(`glance.gigaforust.internal`)"
- "traefik.http.routers.glance-dev.entrypoints=websecure" - "traefik.http.routers.glance-dev.entrypoints=websecure"
- "traefik.http.routers.glance-dev.middlewares=security-chain@file" - "traefik.http.routers.glance-dev.middlewares=security-headers@file"
- "traefik.http.routers.glance-dev.tls=true" - "traefik.http.routers.glance-dev.tls=true"
networks: networks:
- proxy - proxy
dns:
- 1.1.1.1
- 8.8.8.8
networks: networks:
proxy: proxy:
external: true external: true
+5 -10
View File
@@ -7,7 +7,7 @@ services:
- proxy - proxy
volumes: volumes:
- ./config:/etc/headscale - ./config:/etc/headscale
- ./data:/var/lib/headscale - data:/var/lib/headscale
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.docker.network=proxy" - "traefik.docker.network=proxy"
@@ -47,14 +47,9 @@ services:
- "traefik.http.routers.headscale-metrics-dev.entrypoints=websecure" - "traefik.http.routers.headscale-metrics-dev.entrypoints=websecure"
- "traefik.http.routers.headscale-metrics-dev.service=headscale-metrics" - "traefik.http.routers.headscale-metrics-dev.service=headscale-metrics"
- "traefik.http.routers.headscale-metrics-dev.tls=true" - "traefik.http.routers.headscale-metrics-dev.tls=true"
dns:
- 1.1.1.1
- 1.0.0.1
web: web:
image: goodieshq/headscale-admin:latest image: goodieshq/headscale-admin:latest
restart: unless-stopped restart: unless-stopped
networks:
- proxy
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "treafik.docker.network=proxy" - "treafik.docker.network=proxy"
@@ -64,21 +59,21 @@ services:
- "traefik.http.routers.headscale-ui.rule=Host(`hs.forust.xyz`) && PathPrefix(`/admin`)" - "traefik.http.routers.headscale-ui.rule=Host(`hs.forust.xyz`) && PathPrefix(`/admin`)"
- "traefik.http.routers.headscale-ui.entrypoints=websecure" - "traefik.http.routers.headscale-ui.entrypoints=websecure"
- "traefik.http.routers.headscale-ui.middlewares=security-chain@file" - "traefik.http.routers.headscale-ui.middlewares=security-chain@file"
- "traefik.http.routers.headscale-ui.service=headscale-ui"
- "traefik.http.routers.headscale-ui.tls=true" - "traefik.http.routers.headscale-ui.tls=true"
# Local Router # Local Router
- "traefik.http.routers.headscale-ui-local.rule=Host(`hs.workstation.internal`) && PathPrefix(`/admin`)" - "traefik.http.routers.headscale-ui-local.rule=Host(`hs.workstation.internal`) && PathPrefix(`/admin`)"
- "traefik.http.routers.headscale-ui-local.entrypoints=websecure" - "traefik.http.routers.headscale-ui-local.entrypoints=websecure"
- "traefik.http.routers.headscale-ui-local.middlewares=security-chain@file" - "traefik.http.routers.headscale-ui-local.middlewares=security-chain@file"
- "traefik.http.routers.headscale-ui-local.service=headscale-ui"
- "traefik.http.routers.headscale-ui-local.tls=true" - "traefik.http.routers.headscale-ui-local.tls=true"
# Dev Router # Dev Router
- "traefik.http.routers.headscale-ui-dev.rule=Host(`hs.gigaforust.internal`) && PathPrefix(`/admin`)" - "traefik.http.routers.headscale-ui-dev.rule=Host(`hs.gigaforust.internal`) && PathPrefix(`/admin`)"
- "traefik.http.routers.headscale-ui-dev.entrypoints=websecure" - "traefik.http.routers.headscale-ui-dev.entrypoints=websecure"
- "traefik.http.routers.headscale-ui-dev.middlewares=security-chain@file" - "traefik.http.routers.headscale-ui-dev.middlewares=security-chain@file"
- "traefik.http.routers.headscale-ui-dev.service=headscale-ui"
- "traefik.http.routers.headscale-ui-dev.tls=true" - "traefik.http.routers.headscale-ui-dev.tls=true"
networks:
- proxy
volumes:
data:
networks: networks:
proxy: proxy:
external: true external: true
+5 -21
View File
@@ -13,70 +13,54 @@ services:
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.docker.network=proxy" - "traefik.docker.network=proxy"
# Services
- "traefik.http.services.forust-homepage.loadbalancer.server.port=80" - "traefik.http.services.forust-homepage.loadbalancer.server.port=80"
# Prod Router # Prod Router
- "traefik.http.routers.forust-homepage.rule=Host(`forust.xyz`)" - "traefik.http.routers.forust-homepage.rule=Host(`forust.xyz`)"
- "traefik.http.routers.forust-homepage.entrypoints=websecure" - "traefik.http.routers.forust-homepage.entrypoints=websecure"
- "traefik.http.routers.forust-homepage.middlewares=security-headers@file" - "traefik.http.routers.forust-homepage.middlewares=security-headers@file"
- "traefik.http.routers.forust-homepage.service=forust-homepage"
- "traefik.http.routers.forust-homepage.tls=true" - "traefik.http.routers.forust-homepage.tls=true"
# Local Router # Local Router
- "traefik.http.routers.forust-homepage-local.rule=Host(`landing.workstation.internal`) || Host(`landing.internal`)" - "traefik.http.routers.forust-homepage-local.rule=Host(`landing.workstation.internal`)"
- "traefik.http.routers.forust-homepage-local.entrypoints=websecure" - "traefik.http.routers.forust-homepage-local.entrypoints=websecure"
- "traefik.http.routers.forust-homepage-local.middlewares=security-headers@file" - "traefik.http.routers.forust-homepage-local.middlewares=security-headers@file"
- "traefik.http.routers.forust-homepage-local.service=forust-homepage"
- "traefik.http.routers.forust-homepage-local.tls=true" - "traefik.http.routers.forust-homepage-local.tls=true"
# Dev Router # Dev Router
- "traefik.http.routers.forust-homepage-dev.rule=Host(`landing.gigaforust.internal`)" - "traefik.http.routers.forust-homepage-dev.rule=Host(`landing.gigaforust.internal`)"
- "traefik.http.routers.forust-homepage-dev.entrypoints=websecure" - "traefik.http.routers.forust-homepage-dev.entrypoints=websecure"
- "traefik.http.routers.forust-homepage-dev.middlewares=security-headers@file" - "traefik.http.routers.forust-homepage-dev.middlewares=security-headers@file"
- "traefik.http.routers.forust-homepage-dev.service=forust-homepage"
- "traefik.http.routers.forust-homepage-dev.tls=true" - "traefik.http.routers.forust-homepage-dev.tls=true"
xdfnx: xdfnx:
build: build:
context: . context: .
dockerfile: Dockerfile.xdfnx dockerfile: Dockerfile.xdfnx
restart: unless-stopped
# ports: # ports:
# - "8086:80" # - "8086:80"
restart: unless-stopped
volumes: volumes:
- ./xdfnx_files:/usr/share/nginx/html - ./xdfnx_files:/usr/share/nginx/html
networks:
- proxy
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.docker.network=proxy" - "traefik.docker.network=proxy"
# Services
- "traefik.http.services.xdfnx-homepage.loadbalancer.server.port=80" - "traefik.http.services.xdfnx-homepage.loadbalancer.server.port=80"
# Prod Router # Prod Router
- "traefik.http.routers.xdfnx.rule=Host(`xdfnx.cfd`)" - "traefik.http.routers.xdfnx.rule=Host(`xdfnx.cfd`)"
- "traefik.http.routers.xdfnx.entrypoints=websecure" - "traefik.http.routers.xdfnx.entrypoints=websecure"
- "traefik.http.routers.xdfnx.middlewares=security-headers@file" - "traefik.http.routers.xdfnx.middlewares=security-headers@file"
- "traefik.http.routers.xdfnx.service=xdfnx-homepage"
- "traefik.http.routers.xdfnx.tls=true" - "traefik.http.routers.xdfnx.tls=true"
# Local Router # Local Router
- "traefik.http.routers.xdfnx-local.rule=Host(`xdfnx.workstation.internal`) || Host(`xdfnx.internal`)" - "traefik.http.routers.xdfnx-local.rule=Host(`xdfnx.workstation.internal`)"
- "traefik.http.routers.xdfnx-local.entrypoints=websecure" - "traefik.http.routers.xdfnx-local.entrypoints=websecure"
- "traefik.http.routers.xdfnx-local.middlewares=security-headers@file" - "traefik.http.routers.xdfnx-local.middlewares=security-headers@file"
- "traefik.http.routers.xdfnx-local.service=xdfnx-homepage"
- "traefik.http.routers.xdfnx-local.tls=true" - "traefik.http.routers.xdfnx-local.tls=true"
# Dev Router # Dev Router
- "traefik.http.routers.xdfnx-dev.rule=Host(`xdfnx.gigaforust.internal`)" - "traefik.http.routers.xdfnx-dev.rule=Host(`xdfnx.gigaforust.internal`)"
- "traefik.http.routers.xdfnx-dev.entrypoints=websecure" - "traefik.http.routers.xdfnx-dev.entrypoints=websecure"
- "traefik.http.routers.xdfnx-dev.middlewares=security-headers@file" - "traefik.http.routers.xdfnx-dev.middlewares=security-headers@file"
- "traefik.http.routers.xdfnx-dev.service=xdfnx-homepage"
- "traefik.http.routers.xdfnx-dev.tls=true" - "traefik.http.routers.xdfnx-dev.tls=true"
networks:
- proxy
networks: networks:
proxy: proxy:
external: true external: true
+4 -10
View File
@@ -1,7 +1,7 @@
services: services:
metube: metube:
image: ghcr.io/alexta69/metube image: ghcr.io/alexta69/metube
# container_name: metube container_name: metube
restart: unless-stopped restart: unless-stopped
# ports: # ports:
# - "8081:8081" # - "8081:8081"
@@ -13,31 +13,25 @@ services:
volumes: volumes:
- ./MeTube_downloads:/downloads - ./MeTube_downloads:/downloads
labels: labels:
- traefik.enable=true - "traefik.enable=true"
- "traefik.docker.network=proxy" - "traefik.docker.network=proxy"
- "traefik.http.services.metube.loadbalancer.server.port=8081"
# Prod Router # Prod Router
- "traefik.http.routers.metube.rule=Host(`metube.forust.xyz`)" - "traefik.http.routers.metube.rule=Host(`metube.forust.xyz`)"
- "traefik.http.routers.metube.entrypoints=websecure" - "traefik.http.routers.metube.entrypoints=websecure"
- "traefik.http.routers.metube.middlewares=security-chain@file" - "traefik.http.routers.metube.middlewares=security-chain@file"
- "traefik.http.routers.metube.service=metube"
- "traefik.http.routers.metube.tls=true" - "traefik.http.routers.metube.tls=true"
- "traefik.http.services.metube.loadbalancer.server.port=8081"
# Local Router # Local Router
- "traefik.http.routers.metube-local.rule=Host(`metube.workstation.internal`) || Host(`metube.internal`)" - "traefik.http.routers.metube-local.rule=Host(`metube.workstation.internal`))"
- "traefik.http.routers.metube-local.entrypoints=websecure" - "traefik.http.routers.metube-local.entrypoints=websecure"
- "traefik.http.routers.metube-local.middlewares=security-headers@file" - "traefik.http.routers.metube-local.middlewares=security-headers@file"
- "traefik.http.routers.metube-local.service=metube"
- "traefik.http.routers.metube-local.tls=true" - "traefik.http.routers.metube-local.tls=true"
# Dev Router # Dev Router
- "traefik.http.routers.metube-dev.rule=Host(`metube.gigaforust.internal`)" - "traefik.http.routers.metube-dev.rule=Host(`metube.gigaforust.internal`)"
- "traefik.http.routers.metube-dev.entrypoints=websecure" - "traefik.http.routers.metube-dev.entrypoints=websecure"
- "traefik.http.routers.metube-dev.middlewares=security-chain@file" - "traefik.http.routers.metube-dev.middlewares=security-chain@file"
- "traefik.http.routers.metube-dev.service=metube"
- "traefik.http.routers.metube-dev.tls=true" - "traefik.http.routers.metube-dev.tls=true"
networks: networks:
- proxy - proxy
networks: networks:
+6 -13
View File
@@ -18,39 +18,32 @@ services:
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.docker.network=proxy" - "traefik.docker.network=proxy"
# AIO Services configuration # AIO Services configuration
- "traefik.http.services.nextcloud-aio.loadbalancer.server.port=8080" - "traefik.http.services.nextcloud-aio.loadbalancer.server.port=8080"
- "traefik.http.services.nextcloud-aio.loadbalancer.server.scheme=https" - "traefik.http.services.nextcloud-aio.loadbalancer.server.scheme=https"
- "traefik.http.services.nextcloud-aio.loadbalancer.serverstransport=insecureTransport@file" - "traefik.http.services.nextcloud-aio.loadbalancer.serverstransport=insecureTransport@file"
# Prod Router # Prod Router
# - "traefik.http.routers.nextcloud-aio.rule=Host(`nextcloud-aio.forust.xyz`)" # - "traefik.http.routers.nextcloud-aio.rule=Host(`naio.forust.xyz`)"
# - "traefik.http.routers.nextcloud-aio.entrypoints=websecure" # - "traefik.http.routers.nextcloud-aio.entrypoints=websecure"
# - "traefik.http.routers.nextcloud-aio.middlewares=security-headers" # - "traefik.http.routers.nextcloud-aio.middlewares=security-chain@file"
# - "traefik.http.routers.nextcloud-aio.service=nextcloud-aio" # - "traefik.http.routers.nextcloud-aio.service=nextcloud-aio"
# - "traefik.http.routers.nextcloud-aio.tls=true" # - "traefik.http.routers.nextcloud-aio.tls=true"
# Local Router # Local Router
- "traefik.http.routers.nextcloud-aio-local.rule=Host(`nextcloud-aio.workstation.internal`) || Host(`nextcloud-aio.internal`)" - "traefik.http.routers.nextcloud-aio-local.rule=Host(`naio.workstation.internal`)"
- "traefik.http.routers.nextcloud-aio-local.entrypoints=websecure" - "traefik.http.routers.nextcloud-aio-local.entrypoints=websecure"
- "traefik.http.routers.nextcloud-aio-local.middlewares=security-headers@file" - "traefik.http.routers.nextcloud-aio-local.middlewares=security-headers@file"
- "traefik.http.routers.nextcloud-aio-local.service=nextcloud-aio"
- "traefik.http.routers.nextcloud-aio-local.tls=true" - "traefik.http.routers.nextcloud-aio-local.tls=true"
# Dev Router # Dev Router
- "traefik.http.routers.nextcloud-aio-dev.rule=Host(`nextcloud-aio.gigaforust.internal`)" - "traefik.http.routers.nextcloud-aio-dev.rule=Host(`naio.gigaforust.internal`)"
- "traefik.http.routers.nextcloud-aio-dev.entrypoints=websecure" - "traefik.http.routers.nextcloud-aio-dev.entrypoints=websecure"
- "traefik.http.routers.nextcloud-aio-dev.middlewares=security-headers@file" - "traefik.http.routers.nextcloud-aio-dev.middlewares=security-headers@file"
- "traefik.http.routers.nextcloud-aio-dev.service=nextcloud-aio"
- "traefik.http.routers.nextcloud-aio-dev.tls=true" - "traefik.http.routers.nextcloud-aio-dev.tls=true"
# Glanceapp/glance config # Glance Metadata
- glance.name=Nextcloud - glance.name=Nextcloud
# - glance.icon=si:nextcloud
- glance.url=https://nextcloud.forust.xyz/ - glance.url=https://nextcloud.forust.xyz/
- glance.description=Nextcloud is a suite of client-server software for creating and using file hosting services. - glance.description=Nextcloud is a suite of client-server software for creating and using file hosting services.
environment: environment:
AIO_DISABLE_BACKUP_SECTION: false AIO_DISABLE_BACKUP_SECTION: false
APACHE_PORT: 11000 # Is needed when running behind a web server or reverse proxy (like Apache, Nginx, Caddy, Cloudflare Tunnel and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md APACHE_PORT: 11000 # Is needed when running behind a web server or reverse proxy (like Apache, Nginx, Caddy, Cloudflare Tunnel and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
@@ -59,7 +52,7 @@ services:
BORG_RETENTION_POLICY: --keep-within=7d --keep-weekly=4 --keep-monthly=6 # Backup retention See https://github.com/nextcloud/all-in-one#how-to-adjust-borgs-retention-policy BORG_RETENTION_POLICY: --keep-within=7d --keep-weekly=4 --keep-monthly=6 # Backup retention See https://github.com/nextcloud/all-in-one#how-to-adjust-borgs-retention-policy
COLLABORA_SECCOMP_DISABLED: false # Setting this to true allows to disable Collabora's Seccomp feature. See https://github.com/nextcloud/all-in-one#how-to-disable-collaboras-seccomp-feature COLLABORA_SECCOMP_DISABLED: false # Setting this to true allows to disable Collabora's Seccomp feature. See https://github.com/nextcloud/all-in-one#how-to-disable-collaboras-seccomp-feature
FULLTEXTSEARCH_JAVA_OPTIONS: "-Xms1024M -Xmx1024M" # adjust fulltextsearch java options. https://github.com/nextcloud/all-in-one#how-to-adjust-the-fulltextsearch-java-options FULLTEXTSEARCH_JAVA_OPTIONS: "-Xms1024M -Xmx1024M" # adjust fulltextsearch java options. https://github.com/nextcloud/all-in-one#how-to-adjust-the-fulltextsearch-java-options
NEXTCLOUD_DATADIR: /media/forust/nextcloud/ncdata # Allows to set the host directory for Nextcloud's datadir. ⚠️⚠️⚠️ Warning: do not set or adjust this value after the initial Nextcloud installation is done! See https://github.com/nextcloud/all-in-one#how-to-change-the-default-location-of-nextclouds-datadir NEXTCLOUD_DATADIR: /mnt/nextcloud/ncdata # Allows to set the host directory for Nextcloud's datadir. ⚠️⚠️⚠️ Warning: do not set or adjust this value after the initial Nextcloud installation is done! See https://github.com/nextcloud/all-in-one#how-to-change-the-default-location-of-nextclouds-datadir
NEXTCLOUD_MOUNT: /mnt/ # Allows the Nextcloud container to access the chosen directory on the host. See https://github.com/nextcloud/all-in-one#how-to-allow-the-nextcloud-container-to-access-directories-on-the-host NEXTCLOUD_MOUNT: /mnt/ # Allows the Nextcloud container to access the chosen directory on the host. See https://github.com/nextcloud/all-in-one#how-to-allow-the-nextcloud-container-to-access-directories-on-the-host
NEXTCLOUD_UPLOAD_LIMIT: 16G # https://github.com/nextcloud/all-in-one#how-to-adjust-the-upload-limit-for-nextcloud NEXTCLOUD_UPLOAD_LIMIT: 16G # https://github.com/nextcloud/all-in-one#how-to-adjust-the-upload-limit-for-nextcloud
NEXTCLOUD_MAX_TIME: 7200 # Max uploading time See https://github.com/nextcloud/all-in-one#how-to-adjust-the-max-execution-time-for-nextcloud NEXTCLOUD_MAX_TIME: 7200 # Max uploading time See https://github.com/nextcloud/all-in-one#how-to-adjust-the-max-execution-time-for-nextcloud
+2 -9
View File
@@ -103,32 +103,25 @@ services:
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.docker.network=proxy" - "traefik.docker.network=proxy"
- "traefik.http.services.penpot.loadbalancer.server.port=8080"
# Prod Router # Prod Router
- "traefik.http.routers.penpot.rule=Host(`penpot.forust.xyz`)" - "traefik.http.routers.penpot.rule=Host(`penpot.forust.xyz`)"
- "traefik.http.routers.penpot.entrypoints=websecure" - "traefik.http.routers.penpot.entrypoints=websecure"
- "traefik.http.routers.penpot.middlewares=security-headers@file" - "traefik.http.routers.penpot.middlewares=security-headers@file"
- "traefik.http.routers.penpot.service=penpot"
- "traefik.http.routers.penpot.tls=true" - "traefik.http.routers.penpot.tls=true"
- "traefik.http.services.penpot.loadbalancer.server.port=8080"
# Local Router # Local Router
- "traefik.http.routers.penpot-local.rule=Host(`penpot.workstation.internal`) || Host(`penpot.internal`)" - "traefik.http.routers.penpot-local.rule=Host(`penpot.workstation.internal`)"
- "traefik.http.routers.penpot-local.entrypoints=websecure" - "traefik.http.routers.penpot-local.entrypoints=websecure"
- "traefik.http.routers.penpot-local.middlewares=security-headers@file" - "traefik.http.routers.penpot-local.middlewares=security-headers@file"
- "traefik.http.routers.penpot-local.service=penpot"
- "traefik.http.routers.penpot-local.tls=true" - "traefik.http.routers.penpot-local.tls=true"
# Dev Router # Dev Router
- "traefik.http.routers.penpot-dev.rule=Host(`penpot.gigaforust.internal`)" - "traefik.http.routers.penpot-dev.rule=Host(`penpot.gigaforust.internal`)"
- "traefik.http.routers.penpot-dev.entrypoints=websecure" - "traefik.http.routers.penpot-dev.entrypoints=websecure"
- "traefik.http.routers.penpot-dev.middlewares=security-headers@file" - "traefik.http.routers.penpot-dev.middlewares=security-headers@file"
- "traefik.http.routers.penpot-dev.service=penpot"
- "traefik.http.routers.penpot-dev.tls=true" - "traefik.http.routers.penpot-dev.tls=true"
environment: environment:
<<: [ *penpot-flags, *penpot-http-body-size ] <<: [ *penpot-flags, *penpot-http-body-size ]
penpot-backend: penpot-backend:
image: "penpotapp/backend:${PENPOT_VERSION:-latest}" image: "penpotapp/backend:${PENPOT_VERSION:-latest}"
restart: always restart: always
+10 -19
View File
@@ -1,54 +1,45 @@
services: services:
portainer: portainer:
container_name: portainer
image: portainer/portainer-ce:latest image: portainer/portainer-ce:latest
container_name: portainer
restart: always restart: always
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
- ./portainer_data:/data - data:/data
ports: ports:
- 9443:9443 - 9443:9443
# - 8000:8000 # Remove if you do not intend to use Edge Agents # - 8000:8000 # Remove if you do not intend to use Edge Agents
networks:
- proxy
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.docker.network=proxy" - "traefik.docker.network=proxy"
- "traefik.http.services.portainer.loadbalancer.server.port=9443"
- "traefik.http.services.portainer.loadbalancer.server.scheme=https"
- "traefik.http.services.portainer.loadbalancer.serverstransport=insecureTransport@file"
# Prod Router # Prod Router
- "traefik.http.routers.portainer.rule=Host(`portainer.forust.xyz`)" - "traefik.http.routers.portainer.rule=Host(`portainer.forust.xyz`)"
- "traefik.http.routers.portainer.entrypoints=websecure" - "traefik.http.routers.portainer.entrypoints=websecure"
- "traefik.http.routers.portainer.middlewares=security-headers@file" - "traefik.http.routers.portainer.middlewares=security-headers@file"
- "traefik.http.routers.portainer.service=portainer"
- "traefik.http.routers.portainer.tls=true" - "traefik.http.routers.portainer.tls=true"
- "traefik.http.services.portainer.loadbalancer.server.port=9443"
- "traefik.http.services.portainer.loadbalancer.server.scheme=https"
- "traefik.http.services.portainer.loadbalancer.serverstransport=insecureTransport@file"
# Local Router # Local Router
- "traefik.http.routers.portainer-local.rule=Host(`portainer.workstation.internal`) || Host(`portainer.internal`)" - "traefik.http.routers.portainer-local.rule=Host(`portainer.workstation.internal`)"
- "traefik.http.routers.portainer-local.entrypoints=websecure" - "traefik.http.routers.portainer-local.entrypoints=websecure"
- "traefik.http.routers.portainer-local.middlewares=security-headers@file" - "traefik.http.routers.portainer-local.middlewares=security-headers@file"
- "traefik.http.routers.portainer-local.service=portainer"
- "traefik.http.routers.portainer-local.tls=true" - "traefik.http.routers.portainer-local.tls=true"
# Dev Router # Dev Router
- "traefik.http.routers.portainer-dev.rule=Host(`portainer.gigaforust.internal`)" - "traefik.http.routers.portainer-dev.rule=Host(`portainer.gigaforust.internal`)"
- "traefik.http.routers.portainer-dev.entrypoints=websecure" - "traefik.http.routers.portainer-dev.entrypoints=websecure"
- "traefik.http.routers.portainer-dev.middlewares=security-headers@file" - "traefik.http.routers.portainer-dev.middlewares=security-headers@file"
- "traefik.http.routers.portainer-dev.service=portainer"
- "traefik.http.routers.portainer-dev.tls=true" - "traefik.http.routers.portainer-dev.tls=true"
# Glance Metadata
- glance.name=Portainer - glance.name=Portainer
- glance.url=https://portainer.forust.xyz/ - glance.url=https://portainer.forust.xyz/
- glance.description=Portainer is a lightweight management UI which allows you to easily manage your Docker environments. - glance.description=Portainer is a lightweight management UI which allows you to easily manage your Docker environments.
networks:
- proxy
volumes: volumes:
portainer_data: data:
name: portainer_data
networks: networks:
default:
name: portainer_network
proxy: proxy:
external: true external: true
-1
View File
@@ -1 +0,0 @@
TS_AUTHKEY=tskey-auth-xxxxx-CNTRL
-21
View File
@@ -1,21 +0,0 @@
services:
tailscale:
image: tailscale/tailscale:latest
container_name: tailscale
network_mode: host
restart: unless-stopped
cap_add:
- NET_ADMIN
- NET_RAW
volumes:
- tailscale_data:/var/lib/tailscale
- /dev/net/tun:/dev/net/tun
environment:
- TS_AUTHKEY=${TS_AUTHKEY}
- TS_STATE_DIR=/var/lib/tailscale
- TS_HOSTNAME=forust-server
# - TS_EXTRA_ARGS=--advertise-tags=tag:container
volumes:
tailscale_data:
name: tailscale_data
+4 -12
View File
@@ -6,41 +6,33 @@ services:
# ports: # ports:
# - "3331:8080" # - "3331:8080"
volumes: volumes:
- ./termix-data:/app/data - data:/app/data
environment: environment:
PORT: "8080" PORT: "8080"
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.docker.network=proxy" - "traefik.docker.network=proxy"
- "traefik.http.services.termix.loadbalancer.server.port=8080"
# Prod Router # Prod Router
- "traefik.http.routers.termix.rule=Host(`termix.forust.xyz`)" - "traefik.http.routers.termix.rule=Host(`termix.forust.xyz`)"
- "traefik.http.routers.termix.entrypoints=websecure" - "traefik.http.routers.termix.entrypoints=websecure"
- "traefik.http.routers.termix.middlewares=security-headers@file" - "traefik.http.routers.termix.middlewares=security-headers@file"
- "traefik.http.routers.termix.service=termix"
- "traefik.http.routers.termix.tls=true" - "traefik.http.routers.termix.tls=true"
- "traefik.http.services.termix.loadbalancer.server.port=8080"
# Local Router # Local Router
- "traefik.http.routers.termix-local.rule=Host(`termix.workstation.internal`) || Host(`termix.internal`)" - "traefik.http.routers.termix-local.rule=Host(`termix.workstation.internal`)"
- "traefik.http.routers.termix-local.entrypoints=websecure" - "traefik.http.routers.termix-local.entrypoints=websecure"
- "traefik.http.routers.termix-local.middlewares=security-headers@file" - "traefik.http.routers.termix-local.middlewares=security-headers@file"
- "traefik.http.routers.termix-local.service=termix"
- "traefik.http.routers.termix-local.tls=true" - "traefik.http.routers.termix-local.tls=true"
# Dev Router # Dev Router
- "traefik.http.routers.termix-dev.rule=Host(`termix.gigaforust.internal`)" - "traefik.http.routers.termix-dev.rule=Host(`termix.gigaforust.internal`)"
- "traefik.http.routers.termix-dev.entrypoints=websecure" - "traefik.http.routers.termix-dev.entrypoints=websecure"
- "traefik.http.routers.termix-dev.middlewares=security-headers@file" - "traefik.http.routers.termix-dev.middlewares=security-headers@file"
- "traefik.http.routers.termix-dev.service=termix"
- "traefik.http.routers.termix-dev.tls=true" - "traefik.http.routers.termix-dev.tls=true"
networks: networks:
- proxy - proxy
networks: networks:
proxy: proxy:
external: true external: true
volumes: volumes:
termix-data: data:
driver: local
+9 -14
View File
@@ -19,11 +19,14 @@ services:
- "--entryPoints.web.address=:80" - "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443" - "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true" - "--entryPoints.websecure.http.tls=true"
- "--entryPoints.web.http.redirections.entryPoint.to=websecure"
- "--entryPoints.web.http.redirections.entryPoint.scheme=https"
- "--entryPoints.ssh.address=:2221" - "--entryPoints.ssh.address=:2221"
# Let's Encrypt # Let's Encrypt
- "--certificatesresolvers.letsencrypt.acme.email=${EMAIL}" - "--certificatesresolvers.letsencrypt.acme.email=${EMAIL}"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
# # STAGING # # STAGING
# - "--certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" # - "--certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
@@ -31,12 +34,12 @@ services:
# Cloudflare # Cloudflare
- "--entryPoints.web.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22" - "--entryPoints.web.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22"
- "--entryPoints.websecure.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22" - "--entryPoints.websecure.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22"
# # Logging # # Logging
# - "--log.level=INFO" # - "--log.level=INFO"
# - "--log.filePath=/var/log/traefik/traefik.log" # - "--log.filePath=/var/log/traefik/traefik.log"
# - "--accesslog=true" # - "--accesslog=true"
# - "--accesslog.filepath=/var/log/traefik/access.log" # - "--accesslog.filepath=/var/log/traefik/access.log"
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.docker.network=proxy" - "traefik.docker.network=proxy"
@@ -47,14 +50,12 @@ services:
- "traefik.http.routers.traefik-dashboard.middlewares=security-chain@file" - "traefik.http.routers.traefik-dashboard.middlewares=security-chain@file"
- "traefik.http.routers.traefik-dashboard.service=api@internal" - "traefik.http.routers.traefik-dashboard.service=api@internal"
- "traefik.http.routers.traefik-dashboard.tls=true" - "traefik.http.routers.traefik-dashboard.tls=true"
# Local Router # Local Router
- "traefik.http.routers.traefik-dashboard-local.rule=Host(`traefik.workstation.internal`) || Host(`traefik.internal`)" - "traefik.http.routers.traefik-dashboard-local.rule=Host(`traefik.workstation.internal`)"
- "traefik.http.routers.traefik-dashboard-local.entrypoints=websecure" - "traefik.http.routers.traefik-dashboard-local.entrypoints=websecure"
- "traefik.http.routers.traefik-dashboard-local.middlewares=security-headers@file" - "traefik.http.routers.traefik-dashboard-local.middlewares=security-headers@file"
- "traefik.http.routers.traefik-dashboard-local.service=api@internal" - "traefik.http.routers.traefik-dashboard-local.service=api@internal"
- "traefik.http.routers.traefik-dashboard-local.tls=true" - "traefik.http.routers.traefik-dashboard-local.tls=true"
# Dev Router # Dev Router
- "traefik.http.routers.traefik-dashboard-dev.rule=Host(`traefik.gigaforust.internal`)" - "traefik.http.routers.traefik-dashboard-dev.rule=Host(`traefik.gigaforust.internal`)"
- "traefik.http.routers.traefik-dashboard-dev.entrypoints=websecure" - "traefik.http.routers.traefik-dashboard-dev.entrypoints=websecure"
@@ -62,27 +63,21 @@ services:
- "traefik.http.routers.traefik-dashboard-dev.service=api@internal" - "traefik.http.routers.traefik-dashboard-dev.service=api@internal"
- "traefik.http.routers.traefik-dashboard-dev.tls=true" - "traefik.http.routers.traefik-dashboard-dev.tls=true"
# Glance Metadata
- glance.name=Traefik - glance.name=Traefik
- glance.url=https://traefik.forust.xyz/ - glance.url=https://traefik.forust.xyz/
- glance.description=Traefik is a modern reverse proxy and load balancer - glance.description=Traefik is a modern reverse proxy and load balancer
ports:
- "80:80"
- "443:443"
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro - /var/run/docker.sock:/var/run/docker.sock:ro
- ./dynamic:/etc/traefik/dynamic:ro - ./dynamic:/etc/traefik/dynamic:ro
- ./certs:/certs:ro - ./certs:/certs:ro
- ./logs:/var/log/traefik - ./logs:/var/log/traefik
- ./letsencrypt:/letsencrypt - ./letsencrypt:/letsencrypt
ports:
- "80:80"
- "443:443"
networks: networks:
- proxy - proxy
environment:
- TZ=Europe/Bratislava
networks: networks:
proxy: proxy:
external: true external: true
+23
View File
@@ -0,0 +1,23 @@
http:
routers:
fs1-public:
rule: "Host(`fs1.domain.xyz`)"
entrypoints:
- websecure
service: fs1
middlewares:
- security-chain@file
tls: {}
fs1-workstation:
rule: "Host(`fs1.workstation.internal`)"
entrypoints:
- websecure
service: fs1
tls: {}
services:
fs1:
loadBalancer:
servers:
- url: "http://127.0.0.1:3923" # Copyparty port example
+5
View File
@@ -1,5 +1,10 @@
http: http:
middlewares: middlewares:
# HTTPS Redirect
redirect-https:
redirectScheme:
scheme: https
permanent: true
# Cloudflare IP Whitelist # Cloudflare IP Whitelist
cloudflare-ipwhitelist: cloudflare-ipwhitelist:
ipWhiteList: ipWhiteList:
-15
View File
@@ -1,10 +1,4 @@
http: http:
middlewares:
redirect-https:
redirectScheme:
scheme: https
permanent: true
routers: routers:
acme-challenge-exempt: acme-challenge-exempt:
rule: "PathPrefix(`/.well-known/acme-challenge`)" rule: "PathPrefix(`/.well-known/acme-challenge`)"
@@ -12,12 +6,3 @@ http:
- web - web
service: noop@internal service: noop@internal
priority: 100 priority: 100
http-catchall:
rule: "HostRegexp(`{host:.+}`)"
entryPoints:
- web
middlewares:
- redirect-https
service: noop@internal
priority: 1
+6 -7
View File
@@ -1,34 +1,33 @@
services: services:
uptime-kuma: uptime-kuma:
image: louislam/uptime-kuma:2 image: louislam/uptime-kuma:2
restart: unless-stopped
container_name: uptime-kuma container_name: uptime-kuma
restart: unless-stopped
volumes: volumes:
- ./data:/app/data - data:/app/data
# ports: # ports:
# <Host Port>:<Container Port>
# - "3001:3001" # - "3001:3001"
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.docker.network=proxy" - "traefik.docker.network=proxy"
- "traefik.http.services.uptime-kuma.loadbalancer.server.port=3001"
# Prod Router # Prod Router
- "traefik.http.routers.uptime-kuma.rule=Host(`uptime.forust.xyz`)" - "traefik.http.routers.uptime-kuma.rule=Host(`uptime.forust.xyz`)"
- "traefik.http.routers.uptime-kuma.entrypoints=websecure" - "traefik.http.routers.uptime-kuma.entrypoints=websecure"
- "traefik.http.routers.uptime-kuma.tls=true" - "traefik.http.routers.uptime-kuma.tls=true"
- "traefik.http.services.uptime-kuma.loadbalancer.server.port=3001"
# Local Router # Local Router
- "traefik.http.routers.uptime-kuma-local.rule=Host(`uptime.workstation.internal`) || Host(`uptime.internal`)" - "traefik.http.routers.uptime-kuma-local.rule=Host(`uptime.workstation.internal`)"
- "traefik.http.routers.uptime-kuma-local.entrypoints=websecure" - "traefik.http.routers.uptime-kuma-local.entrypoints=websecure"
- "traefik.http.routers.uptime-kuma-local.tls=true" - "traefik.http.routers.uptime-kuma-local.tls=true"
# Dev Router # Dev Router
- "traefik.http.routers.uptime-kuma-dev.rule=Host(`uptime.gigaforust.internal`)" - "traefik.http.routers.uptime-kuma-dev.rule=Host(`uptime.gigaforust.internal`)"
- "traefik.http.routers.uptime-kuma-dev.entrypoints=websecure" - "traefik.http.routers.uptime-kuma-dev.entrypoints=websecure"
- "traefik.http.routers.uptime-kuma-dev.tls=true" - "traefik.http.routers.uptime-kuma-dev.tls=true"
networks: networks:
- proxy - proxy
volumes:
data:
networks: networks:
proxy: proxy:
external: true external: true