Match the Technitium canvas: palette, shell, KPI strips, framed tables
The live UI did not follow the canvas because its base layer differed: dark palette in hex (now the canvas oklch values), 13 px body text, flat Frame panels. - Tokens: canvas palette, 14 px body, 1.4 line height; Frame without `dense` gets the 3 px ring; Panel takes a description line. - Shell: 56 px brand button with version, 11 px group headings, user card at the foot, versions moved into the header status popover, Home / group / section crumbs, amber "Attention" status when blocking is off or paused. - New KpiStrip and PageTabs; Dashboard KPIs in three frames and a Refresh button. - Zones: KPI strip, tab with count, views, framed table with the canvas columns. - Apps: Installed / App Store tabs and a grid instead of cards (store inline). - Blocking: state banner and tab counts; one "Blocking" title. - Settings: actions in the header, label-and-help rows with the control on the right. - DHCP, Administration, DNS Client, Logs, Cache, About: subtitles, framed tables, KPI strips where the data exists; Login cover with the three-point list. - docs/compose.shnt.example.yaml: production compose with the console image. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ea98a33b25
commit
87281a87d3
53 files changed
+1011
-487
No files matched your search
@@ -0,0 +1,181 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:v3
|
||||
container_name: traefik
|
||||
restart: unless-stopped
|
||||
command:
|
||||
- "--providers.docker=true"
|
||||
- "--providers.docker.exposedbydefault=false"
|
||||
- "--providers.docker.network=dns-net"
|
||||
- "--providers.file.directory=/etc/traefik/dynamic"
|
||||
- "--providers.file.watch=true"
|
||||
|
||||
- "--entrypoints.web.address=:80"
|
||||
- "--entrypoints.websecure.address=:443"
|
||||
- "--entrypoints.websecure.http3"
|
||||
- "--entrypoints.dot.address=:853"
|
||||
- "--entrypoints.doq.address=:853/udp"
|
||||
- "--entrypoints.cluster.address=:53443"
|
||||
|
||||
- "--certificatesresolvers.myresolver.acme.dnschallenge=true"
|
||||
- "--certificatesresolvers.myresolver.acme.dnschallenge.provider=cloudflare"
|
||||
- "--certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53"
|
||||
- "--certificatesresolvers.myresolver.acme.dnschallenge.delaybeforecheck=60s"
|
||||
- "--certificatesresolvers.myresolver.acme.email=admin@shnt.top"
|
||||
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
|
||||
environment:
|
||||
- CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN}
|
||||
ports:
|
||||
- target: 80
|
||||
published: 80
|
||||
protocol: tcp
|
||||
mode: host
|
||||
- target: 443
|
||||
published: 443
|
||||
protocol: tcp
|
||||
mode: host
|
||||
- target: 443
|
||||
published: 443
|
||||
protocol: udp
|
||||
mode: host
|
||||
- target: 853
|
||||
published: 853
|
||||
protocol: tcp
|
||||
mode: host
|
||||
- target: 853
|
||||
published: 853
|
||||
protocol: udp
|
||||
mode: host
|
||||
- target: 53443
|
||||
published: 53443
|
||||
protocol: tcp
|
||||
mode: host
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- ./letsencrypt:/letsencrypt
|
||||
- ./traefik/dynamic:/etc/traefik/dynamic:ro
|
||||
networks:
|
||||
- dns-net
|
||||
|
||||
technitium-smart:
|
||||
image: technitium/dns-server:latest
|
||||
container_name: technitium-smart
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- dns-net
|
||||
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- NET_RAW
|
||||
- NET_BIND_SERVICE
|
||||
|
||||
environment:
|
||||
- DNS_SERVER_ADMIN_PASSWORD=${DNS_SERVER_ADMIN_PASSWORD}
|
||||
- DNS_SERVER_ENABLE_DNS_OVER_HTTP=true
|
||||
- DNS_SERVER_ENABLE_DNS_OVER_TLS=false
|
||||
- DNS_SERVER_WEB_SERVICE_ENABLE_HTTPS=true
|
||||
- DNS_SERVER_WEB_SERVICE_HTTPS_PORT=53443
|
||||
- DNS_SERVER_WEB_SERVICE_USE_SELF_SIGNED_CERT=true
|
||||
# Новая консоль: папку со статикой отдаёт том technitium-console (нужен Technitium 15.5+)
|
||||
- DNS_SERVER_WEB_SERVICE_WWW_FOLDER_PATH=/opt/technitium-console
|
||||
- TZ=Asia/Novosibirsk
|
||||
- ASPNETCORE_FORWARDEDHEADERS_ENABLED=true
|
||||
- DOTNET_SYSTEM_NET_SOCKETS_INLINE_RECEIVE=1
|
||||
|
||||
volumes:
|
||||
- technitium-data:/etc/dns
|
||||
- technitium-console:/opt/technitium-console:ro
|
||||
|
||||
# AXFR зоны кластера (TLSA). Если 53 уже слушает не этот контейнер — удалите блок.
|
||||
# Файрволом пускайте TCP/53 только с IP соседних нод.
|
||||
# ports:
|
||||
# - target: 53
|
||||
# published: 53
|
||||
# protocol: tcp
|
||||
# mode: host
|
||||
# - target: 53
|
||||
# published: 53
|
||||
# protocol: udp
|
||||
# mode: host
|
||||
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=dns-net"
|
||||
|
||||
- "traefik.http.middlewares.old-panel-headers.headers.customrequestheaders.X-Forwarded-Proto=https"
|
||||
- "traefik.http.middlewares.old-panel-headers.headers.customrequestheaders.X-Forwarded-Host=old.dns.shnt.top"
|
||||
|
||||
# DoH
|
||||
- "traefik.http.routers.doh.rule=(Host(`dns.shnt.top`) || HostRegexp(`^[a-z0-9-]+\\.dns\\.shnt\\.top$`) || Host(`ndns.shnt.top`) || HostRegexp(`^[a-z0-9-]+\\.ndns\\.shnt\\.top$`)) && PathPrefix(`/dns-query`)"
|
||||
- "traefik.http.routers.doh.entrypoints=websecure"
|
||||
- "traefik.http.routers.doh.tls.certresolver=myresolver"
|
||||
- "traefik.http.routers.doh.tls.domains[0].main=dns.shnt.top"
|
||||
- "traefik.http.routers.doh.tls.domains[0].sans=*.dns.shnt.top"
|
||||
- "traefik.http.routers.doh.tls.domains[1].main=ndns.shnt.top"
|
||||
- "traefik.http.routers.doh.tls.domains[1].sans=*.ndns.shnt.top"
|
||||
- "traefik.http.routers.doh.priority=1000"
|
||||
- "traefik.http.routers.doh.service=doh-svc"
|
||||
- "traefik.http.services.doh-svc.loadbalancer.server.port=8080"
|
||||
- "traefik.http.services.doh-svc.loadbalancer.server.scheme=http"
|
||||
|
||||
# Панель
|
||||
- "traefik.http.routers.panel-old.rule=Host(`dns.shnt.top`) || Host(`old.dns.shnt.top`) || Host(`ndns.shnt.top`) || HostRegexp(`^[a-z0-9-]+\\.ndns\\.shnt\\.top$`)"
|
||||
- "traefik.http.routers.panel-old.entrypoints=websecure"
|
||||
- "traefik.http.routers.panel-old.tls.certresolver=myresolver"
|
||||
- "traefik.http.routers.panel-old.tls.domains[0].main=dns.shnt.top"
|
||||
- "traefik.http.routers.panel-old.tls.domains[0].sans=*.dns.shnt.top"
|
||||
- "traefik.http.routers.panel-old.tls.domains[1].main=ndns.shnt.top"
|
||||
- "traefik.http.routers.panel-old.tls.domains[1].sans=*.ndns.shnt.top"
|
||||
- "traefik.http.routers.panel-old.priority=10"
|
||||
- "traefik.http.routers.panel-old.middlewares=old-panel-headers"
|
||||
- "traefik.http.routers.panel-old.service=panel-old-svc"
|
||||
- "traefik.http.services.panel-old-svc.loadbalancer.server.port=5380"
|
||||
|
||||
# DoT
|
||||
- "traefik.tcp.routers.dot.rule=HostSNI(`dns.shnt.top`) || HostSNIRegexp(`^.+\\.dns\\.shnt\\.top$`) || HostSNI(`ndns.shnt.top`) || HostSNIRegexp(`^.+\\.ndns\\.shnt\\.top$`)"
|
||||
- "traefik.tcp.routers.dot.entrypoints=dot"
|
||||
- "traefik.tcp.routers.dot.tls=true"
|
||||
- "traefik.tcp.routers.dot.tls.certresolver=myresolver"
|
||||
- "traefik.tcp.routers.dot.tls.domains[0].main=dns.shnt.top"
|
||||
- "traefik.tcp.routers.dot.tls.domains[0].sans=*.dns.shnt.top"
|
||||
- "traefik.tcp.routers.dot.tls.domains[1].main=ndns.shnt.top"
|
||||
- "traefik.tcp.routers.dot.tls.domains[1].sans=*.ndns.shnt.top"
|
||||
- "traefik.tcp.routers.dot.tls.options=dot@file"
|
||||
- "traefik.tcp.routers.dot.service=dot-svc"
|
||||
- "traefik.tcp.services.dot-svc.loadbalancer.server.port=538"
|
||||
- "traefik.tcp.services.dot-svc.loadbalancer.proxyprotocol.version=2"
|
||||
|
||||
# DoQ
|
||||
- "traefik.udp.routers.doq.entrypoints=doq"
|
||||
- "traefik.udp.routers.doq.service=doq-svc"
|
||||
- "traefik.udp.services.doq-svc.loadbalancer.server.port=8530"
|
||||
|
||||
# Кластер: TLS passthrough на Technitium :53443 (без certresolver и Proxy Protocol)
|
||||
- "traefik.tcp.routers.cluster.rule=HostSNI(`ndns.shnt.top`) || HostSNIRegexp(`^.+\\.ndns\\.shnt\\.top$`) || HostSNI(`dns.shnt.top`) || HostSNIRegexp(`^.+\\.dns\\.shnt\\.top$`)"
|
||||
- "traefik.tcp.routers.cluster.entrypoints=cluster"
|
||||
- "traefik.tcp.routers.cluster.tls.passthrough=true"
|
||||
- "traefik.tcp.routers.cluster.service=cluster-svc"
|
||||
- "traefik.tcp.services.cluster-svc.loadbalancer.server.port=53443"
|
||||
|
||||
# Копирует новую консоль в том technitium-console и завершается.
|
||||
# Без labels Traefik: наружу этот контейнер ничего не отдаёт.
|
||||
# Обновление: docker compose pull technitium-console && docker compose up -d technitium-console
|
||||
technitium-console:
|
||||
image: git.shx.one/denozord/technitium-console:latest
|
||||
container_name: technitium-console
|
||||
restart: "no"
|
||||
volumes:
|
||||
- technitium-console:/target
|
||||
networks:
|
||||
- dns-net
|
||||
|
||||
networks:
|
||||
dns-net:
|
||||
driver: bridge
|
||||
name: dns-net
|
||||
|
||||
volumes:
|
||||
technitium-data:
|
||||
technitium-console:
|
||||
Reference in new issue
Block a user