feat/checkmk #7

Merged
forust merged 12 commits from feat/checkmk into main 2026-01-19 14:59:21 +00:00
17 changed files with 320 additions and 83 deletions
Showing only changes of commit 4a25622552 - Show all commits
+13 -8
View File
@@ -2,17 +2,12 @@
sync.ffs_lock
.sync.ffs_db
# Environment
.env
.env.anna
.env.forust
.env.*
!.env.*example
# Copyparty
*.hist/
# Volumes and data directories
gitea/gitea-db/
gitea/gitea-data/*
gitea/*runner/*
n8n/n8n-data/*
n8n/n8n-node-data/*
adguardhome/data/*
@@ -24,6 +19,8 @@ termix/termix-data/*
cfddns/config.json
checkmk/checkmk/*
downtify/Downtify_downloads
headscale/config/*
headscale/data/*
# Steaming services files
streaming/jellyfin/*
@@ -36,10 +33,11 @@ streaming/prowlarr/*
# Homepage
homepages/forust_files/assets/images/team/*
homepages/forust_files/.well-known/*
# Traefik files
traefik/letsencrypt/acme.json
traefik/dynamic/fileservers.yml
traefik/logs/*
# SSL Certificates
@@ -87,3 +85,10 @@ replacements.txt
# Temp files
edu_master/temp/
temp/*
# Environment
.env
.env.anna
.env.forust
.env.*
!*example
+1 -1
View File
@@ -9,7 +9,7 @@ services:
- "853:853/tcp" # DNS over TLS
# - "67:67/udp" # DHCP
# - "68:68/tcp" # DHCP
- "3000:3000/tcp"
# - "3000:3000/tcp"
volumes:
- ./data/work:/opt/adguardhome/work
- ./data/conf:/opt/adguardhome/conf
+3 -3
View File
@@ -26,9 +26,9 @@ services:
command: server
container_name: authentik-server
restart: unless-stopped
ports:
- ${PORT_HTTP:-9000}:9000
- ${PORT_HTTPS:-9443}:9443
# ports:
# - ${PORT_HTTP:-9000}:9000
# - ${PORT_HTTPS:-9443}:9443
env_file:
- .env
environment:
+20 -9
View File
@@ -12,15 +12,26 @@ logging.basicConfig(
)
logger = logging.getLogger(__name__)
# Load configuration
LOGIN = os.getenv('EDU_LOGIN')
PASSWORD = os.getenv('EDU_PASSWORD')
URL_LOGIN = os.getenv('EDU_URL_LOGIN', 'https://edu.edu.vn.ua/user/login')
URL_VERIFY = os.getenv('EDU_URL_VERIFY', 'https://edu.edu.vn.ua/course/userlist')
INTERVAL = int(os.getenv('PHPSESSID_INTERVAL', 10))
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')
REDIS_PORT = int(os.getenv('REDIS_PORT', 6379))
# Load configuration (adapted to .env keys)
def _env(key, default=None):
v = os.getenv(key, default)
if isinstance(v, str) and len(v) >= 2 and ((v[0] == '"' and v[-1] == '"') or (v[0] == "'" and v[-1] == "'")):
return v[1:-1]
return v
LOGIN = _env('KEEPER_LOGIN')
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'
+72 -23
View File
@@ -3,7 +3,8 @@ import logging
import redis
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 playwright.async_api import async_playwright
@@ -15,14 +16,23 @@ logging.basicConfig(
logger = logging.getLogger(__name__)
# Load environment variables
WEBINAR_URL = os.getenv('WEBINAR_URL', 'https://edu.edu.vn.ua/webinar/useractive')
WEBINAR_CHECK_INTERVAL = int(os.getenv('WEBINAR_CHECK_INTERVAL', 60))
REDIS_HOST = os.getenv('REDIS_HOST', 'redis')
REDIS_PORT = int(os.getenv('REDIS_PORT', 6379))
PLAYWRIGHT_WS = os.getenv('PLAYWRIGHT_WS', 'ws://playwright-service:3000/ws')
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')
ADMIN_ID = int(os.getenv('WEBINAR_ADMIN_ID', '0'))
def _env(key, default=None):
v = os.getenv(key, default)
if isinstance(v, str) and len(v) >= 2 and ((v[0] == '"' and v[-1] == '"') or (v[0] == "'" and v[-1] == "'")):
return v[1:-1]
return v
EDU_BASE = _env('EDU_URL_BASE', 'https://edu.edu.vn.ua')
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
KEY_WHITELIST = "bot:whitelist"
@@ -48,7 +58,7 @@ TRANSLATIONS = {
'welcome_admin': "\n\n👑 <b>Режим администратора активен</b>",
'access_denied': "⛔ Доступ запрещен. Вас нет в белом списке.",
'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Или используйте панель ниже для управления настройками.",
'admin_only': "⛔ Только для администратора!",
'user_added': "✅ Пользователь {user_id} добавлен в белый список",
@@ -85,7 +95,7 @@ TRANSLATIONS = {
'welcome_admin': "\n\n👑 <b>Режим адміністратора активний</b>",
'access_denied': "⛔ Доступ заборонено. Вас немає в білому списку.",
'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Або використовуйте панель нижче для керування налаштуваннями.",
'admin_only': "⛔ Тільки для адміністратора!",
'user_added': "✅ Користувач {user_id} доданий до білого списку",
@@ -122,7 +132,7 @@ TRANSLATIONS = {
'welcome_admin': "\n\n👑 <b>Admin Mode Active</b>",
'access_denied': "⛔ Access denied. You are not on the whitelist.",
'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.",
'admin_only': "⛔ Admin only!",
'user_added': "✅ User {user_id} added to whitelist",
@@ -203,6 +213,21 @@ def is_whitelisted(user_id: int) -> bool:
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):
"""Generate admin panel keyboard."""
whitelist_enabled = redis_client.get(KEY_WHITELIST_ENABLED) != "0"
@@ -221,19 +246,21 @@ def get_admin_keyboard(user_id: int):
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /start command."""
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):
await update.message.reply_text(t(user.id, 'access_denied'))
return
# Add to subscribers
redis_client.sadd(KEY_SUBSCRIBERS, user.id)
# Add to subscribers (Chat 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:
msg += t(user.id, 'welcome_admin')
if user.id == ADMIN_ID and chat.type == "private":
msg += t(chat.id, 'welcome_admin')
await update.message.reply_text(msg, parse_mode='HTML', reply_markup=get_admin_keyboard(user.id))
else:
await update.message.reply_text(msg, parse_mode='HTML')
@@ -241,19 +268,39 @@ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /help command."""
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:
msg += t(user_id, 'help_admin')
if user_id == ADMIN_ID and update.effective_chat.type == "private":
msg += t(chat_id, 'help_admin')
await update.message.reply_text(msg, parse_mode='HTML', reply_markup=get_admin_keyboard(user_id))
else:
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):
"""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(
t(user_id, 'select_language'),
t(chat.id, 'select_language'),
parse_mode='HTML',
reply_markup=get_language_keyboard()
)
@@ -535,6 +582,7 @@ async def check_webinars_job(context: ContextTypes.DEFAULT_TYPE):
for sub_id in subscribers:
try:
# 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([
t(int(sub_id), 'webinar_item', name=w['name'], url=w['url'])
for w in new_webinars
@@ -569,6 +617,7 @@ def main():
# Handlers
app.add_handler(CommandHandler("start", start))
app.add_handler(CommandHandler("stop", stop_command))
app.add_handler(CommandHandler("help", help_command))
app.add_handler(CommandHandler("language", language_command))
app.add_handler(CommandHandler("adduser", add_user))
-1
View File
@@ -1,7 +1,6 @@
GITEA_POSTGRES_USER=
GITEA_POSTGRES_PASSWORD=
GITEA_POSTGRES_DB=gitea
BASIC-RUNNER_TOKEN=
GITEA_SMTP_PASS=
MAILER_ADDR=
SERVICE_EMAIL=email.used.by.services@domain.tld
-19
View File
@@ -65,25 +65,6 @@ services:
depends_on:
- db
runner:
image: gitea/act_runner:0.2.11
container_name: gitea-runner
restart: always
depends_on:
- server
env_file:
- .env
networks:
- gitea-db
environment:
- GITEA_INSTANCE_URL=http://server:3000
- GITEA_RUNNER_REGISTRATION_TOKEN=${BASIC-RUNNER_TOKEN}
- GITEA_RUNNER_NAME=basic-runner
- GITEA_RUNNER_LABELS=docker:docker://node:20-bookworm,ubuntu-latest:docker://node:20-bookworm
volumes:
- ./gitea-runner:/data
- /var/run/docker.sock:/var/run/docker.sock
db:
image: docker.io/library/postgres:14
restart: always
+2 -2
View File
@@ -16,7 +16,7 @@ services:
# Prod Router
- "traefik.http.routers.glance.rule=Host(`glance.forust.xyz`)"
- "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"
# Local Router
@@ -28,7 +28,7 @@ services:
# Dev Router
- "traefik.http.routers.glance-dev.rule=Host(`glance.gigaforust.internal`)"
- "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"
networks:
- proxy
+84
View File
@@ -0,0 +1,84 @@
services:
server:
image: headscale/headscale:latest
restart: unless-stopped
command: serve
networks:
- proxy
volumes:
- ./config:/etc/headscale
- ./data:/var/lib/headscale
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.services.headscale.loadbalancer.server.port=8080"
- "traefik.http.services.headscale-metrics.loadbalancer.server.port=9090"
## SERVICE
# Prod Router
- "traefik.http.routers.headscale.rule=Host(`hs.forust.xyz`)"
- "traefik.http.routers.headscale.entrypoints=websecure"
- "traefik.http.routers.headscale.service=headscale"
- "traefik.http.routers.headscale.tls=true"
# Local Router
- "traefik.http.routers.headscale-local.rule=Host(`hs.workstation.internal`)"
- "traefik.http.routers.headscale-local.entrypoints=websecure"
- "traefik.http.routers.headscale-local.service=headscale"
- "traefik.http.routers.headscale-local.tls=true"
# Dev Router
- "traefik.http.routers.headscale-dev.rule=Host(`hs.gigaforust.internal`)"
- "traefik.http.routers.headscale-dev.entrypoints=websecure"
- "traefik.http.routers.headscale-dev.service=headscale"
- "traefik.http.routers.headscale-dev.tls=true"
## METRICS
# Prod Router
- "traefik.http.routers.headscale-metrics.rule=Host(`hs.forust.xyz`) && PathPrefix(`/metrics`)"
- "traefik.http.routers.headscale-metrics.entrypoints=websecure"
- "traefik.http.routers.headscale-metrics.service=headscale-metrics"
- "traefik.http.routers.headscale-metrics.tls=true"
# Local Router
- "traefik.http.routers.headscale-metrics-local.rule=Host(`hs.workstation.internal`) && PathPrefix(`/metrics`)"
- "traefik.http.routers.headscale-metrics-local.entrypoints=websecure"
- "traefik.http.routers.headscale-metrics-local.service=headscale-metrics"
- "traefik.http.routers.headscale-metrics-local.tls=true"
# Dev Router
- "traefik.http.routers.headscale-metrics-dev.rule=Host(`hs.gigaforust.internal`) && PathPrefix(`/metrics`)"
- "traefik.http.routers.headscale-metrics-dev.entrypoints=websecure"
- "traefik.http.routers.headscale-metrics-dev.service=headscale-metrics"
- "traefik.http.routers.headscale-metrics-dev.tls=true"
dns:
- 1.1.1.1
- 1.0.0.1
web:
image: goodieshq/headscale-admin:latest
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "treafik.docker.network=proxy"
- "traefik.http.services.headscale-ui.loadbalancer.server.port=80"
# Prod Router
- "traefik.http.routers.headscale-ui.rule=Host(`hs.forust.xyz`) && PathPrefix(`/admin`)"
- "traefik.http.routers.headscale-ui.entrypoints=websecure"
- "traefik.http.routers.headscale-ui.middlewares=security-chain@file"
- "traefik.http.routers.headscale-ui.service=headscale-ui"
- "traefik.http.routers.headscale-ui.tls=true"
# Local Router
- "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.middlewares=security-chain@file"
- "traefik.http.routers.headscale-ui-local.service=headscale-ui"
- "traefik.http.routers.headscale-ui-local.tls=true"
# Dev Router
- "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.middlewares=security-chain@file"
- "traefik.http.routers.headscale-ui-dev.service=headscale-ui"
- "traefik.http.routers.headscale-ui-dev.tls=true"
networks:
proxy:
external: true
+79
View File
@@ -0,0 +1,79 @@
# https://wiki.serversatho.me/en/headscale
# # Prod server_url
# server_url: https://hs.example.com
# # Local server_url
# server_url: https://hs.internal_domain.internal
# # Dev server_url
# server_url: https://hs.dev_internal_domain.internal
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 127.0.0.1:9090
grpc_listen_addr: 127.0.0.1:50443
grpc_allow_insecure: false
noise:
private_key_path: /var/lib/headscale/noise_private.key
prefixes:
v4: 100.64.0.0/10
v6: fd7a:115c:a1e0::/48
allocation: sequential
derp:
server:
enabled: true
region_id: 999
region_code: "headscale"
region_name: "Headscale Embedded DERP"
stun_listen_addr: "0.0.0.0:3478"
private_key_path: /var/lib/headscale/derp_server_private.key
automatically_add_embedded_derp_region: true
ipv4: 1.2.3.4
ipv6: 2001:db8::1
urls:
- https://controlplane.tailscale.com/derpmap/default
paths: []
auto_update_enabled: true
update_frequency: 24h
disable_check_updates: false
ephemeral_node_inactivity_timeout: 30m
database:
type: sqlite
debug: false
gorm:
prepare_stmt: true
parameterized_queries: true
skip_err_record_not_found: true
slow_threshold: 1000
sqlite:
path: /var/lib/headscale/db.sqlite
write_ahead_log: true
wal_autocheckpoint: 1000
acme_url: https://acme-v02.api.letsencrypt.org/directory
acme_email: ""
tls_letsencrypt_hostname: ""
tls_letsencrypt_cache_dir: /var/lib/headscale/cache
tls_letsencrypt_challenge_type: HTTP-01
tls_letsencrypt_listen: ":http"
tls_cert_path: ""
tls_key_path: ""
log:
format: text
level: info
policy:
mode: database
path: ""
dns:
magic_dns: true
base_domain: example.com
nameservers:
global:
- 1.1.1.1
- 1.0.0.1
- 2606:4700:4700::1111
- 2606:4700:4700::1001
split: {}
search_domains: []
extra_records: []
unix_socket: /var/run/headscale/headscale.sock
unix_socket_permission: "0770"
logtail:
enabled: false
randomize_client_port: false
+4 -5
View File
@@ -3,8 +3,8 @@ services:
build:
context: .
dockerfile: Dockerfile.forust
ports:
- "8085:80"
# ports:
# - "8085:80"
restart: unless-stopped
volumes:
- ./forust_files:/usr/share/nginx/html
@@ -42,8 +42,8 @@ services:
build:
context: .
dockerfile: Dockerfile.xdfnx
ports:
- "8086:80"
# ports:
# - "8086:80"
restart: unless-stopped
volumes:
- ./xdfnx_files:/usr/share/nginx/html
@@ -77,7 +77,6 @@ services:
- "traefik.http.routers.xdfnx-dev.service=xdfnx-homepage"
- "traefik.http.routers.xdfnx-dev.tls=true"
networks:
proxy:
external: true
+8 -1
View File
@@ -41,7 +41,14 @@
</li>
<li>
<i class="fas fa-envelope"></i>
<a href="mailto:forust@forust.xyz">forust@forust.xyz</a>
<a href="mailto:forust@forust.xyz">mail/contact@forust.xyz</a>
</li>
<li>
<i class="fa-solid fa-key"></i>
<a href=".well-known/pgp-key.asc">security/PGP Key</a>
</li>
<li>
<p class="comment"># PGP Key Fingerprint: A777 7CB7 D9C4 0A97 443D CCF0 7A3D A455 F820 5B82</p>
</li>
</ul>
</section>
+5 -5
View File
@@ -25,21 +25,21 @@ services:
- "traefik.http.services.nextcloud-aio.loadbalancer.serverstransport=insecureTransport@file"
# 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.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.tls=true"
# 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`) || Host(`nextcloud-aio.internal`)"
- "traefik.http.routers.nextcloud-aio-local.entrypoints=websecure"
- "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"
# 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.middlewares=security-headers@file"
- "traefik.http.routers.nextcloud-aio-dev.service=nextcloud-aio"
@@ -59,7 +59,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
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
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_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
+2 -2
View File
@@ -86,8 +86,8 @@ services:
penpot-frontend:
image: "penpotapp/frontend:${PENPOT_VERSION:-latest}"
restart: always
ports:
- 9001:8080
# ports:
# - 9001:8080
volumes:
- penpot_assets:/opt/data/assets
+2 -2
View File
@@ -3,8 +3,8 @@ services:
image: ghcr.io/lukegus/termix:latest
container_name: termix
restart: unless-stopped
ports:
- "3331:8080"
# ports:
# - "3331:8080"
volumes:
- ./termix-data:/app/data
environment:
+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
+2 -2
View File
@@ -5,9 +5,9 @@ services:
container_name: uptime-kuma
volumes:
- ./data:/app/data
ports:
# ports:
# <Host Port>:<Container Port>
- "3001:3001"
# - "3001:3001"
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"