Compare commits

...

30 Commits

Author SHA1 Message Date
forust 258ed04f98 feat: miku 2025-11-26 14:23:56 +01:00
forust 7ee0a1e7a2 feat: repos added to forust homepage 2025-11-26 11:51:09 +01:00
forust 739915c451 feat: team avatars 2025-11-26 01:20:12 +01:00
forust 68b5467a37 chore: exclude team images from project 2025-11-26 01:19:50 +01:00
forust 61e6b2b5c7 chore: reformat discord username to unified style 2025-11-26 01:01:37 +01:00
forust 272666d2fd fix: container url forust-homepage 2025-11-26 00:44:58 +01:00
forust aca485836b fix: service names 2025-11-26 00:42:10 +01:00
forust 02671b9117 feat: traefik dynamic files for forust-homepage 2025-11-26 00:10:35 +01:00
forust 1c1170ca96 refactor: change names for forust-homepage 2025-11-26 00:09:12 +01:00
forust 3eab3b254a Merge branch 'main' into landing 2025-11-26 00:02:37 +01:00
forust 5d9fc18ba5 feat: docker deployment 2025-11-26 00:01:43 +01:00
forust 03d39f8a32 chore: separate docker files from nginx 2025-11-25 23:59:15 +01:00
forust 7b60630d76 feat: new landing page matching xrock style 2025-11-25 23:48:12 +01:00
forust cc20d848f8 chore: vv pass 2025-11-25 19:29:12 +01:00
forust 1040e4fdf7 chore: termix-data to gitignore 2025-11-20 03:44:50 +01:00
forust 7af5af0630 fix: Return glance service 2025-11-18 15:42:51 +01:00
forust 8f9be8a478 fix: Misplaced comment 2025-11-18 15:20:53 +01:00
forust d1adaa54b1 feat: Add routers for local access 2025-11-18 15:19:27 +01:00
forust b3b0d5b553 refactor: sepparate traefik production routers 2025-11-18 15:13:45 +01:00
forust d22ef0cb44 feat: Add routers for local testing 2025-11-18 15:04:06 +01:00
forust 7c29d74c72 refactor: Removed routers from dynamic. Use .bak for references 2025-11-18 14:47:59 +01:00
forust b2ae170ea0 refactor: Sepparate traefik middlewares 2025-11-18 14:45:30 +01:00
forust 2c2474165b refactor: Sepparate traefik tls configuration 2025-11-18 14:43:49 +01:00
forust 155bb8d02b refactor: Sepparate traefik services 2025-11-18 14:41:41 +01:00
forust ed1b41ca1d feat: Add termix ssh manager, traefik routers 2025-11-18 03:34:55 +01:00
forust 9bb5f070e3 chore: gitignore for termix 2025-11-18 03:34:34 +01:00
forust b238e9ccf2 chore: Env example 2025-11-18 03:23:57 +01:00
forust 09a05a5ad5 chore: remove commented docker labels 2025-11-18 02:34:55 +01:00
forust 5b05207985 refactor: Move uptime-kuma traefik labels to dynamic.yaml 2025-11-18 02:30:42 +01:00
forust 319cf0ea1f feat: Add demo landing page 2025-11-18 02:12:48 +01:00
17 changed files with 1476 additions and 315 deletions
+70
View File
@@ -0,0 +1,70 @@
#===============================
# Basic auth credentials
#===============================
#
#
#
#===============================
#===============================================
#BEGIN TRAEFIK ENVIRONMENT VARIABLES ===========
#===============================================
#===============================================
# General Traefik Environment Variables
#===============================================
HOST=hostname
EMAIL=your@email.here
CF_DNS_API_TOKEN=API_TOKEN_HERE
CF_EMAIL=your_cloudflare@email.here
TZ=Europe/Berlin
#===============================================
# Dockmon Traefik Configuration File
#===============================================
DOCKMON_APPNAME=dockmon
DOCKMON_SUBDOMEN=dockmon
#===============================================
# Dashboard Traefik Environment Variables
#===============================================
DASHBOARD_APPNAME=traefik
DASHBOARD_SUBDOMEN=traefik
#===============================================
# Watercrawl Traefik Environment Variables
#===============================================
WATERCRAWL_APPNAME=watercrawl
WATERCRAWL_SUBDOMEN=watercrawl
#===============================================
# n8n Traefik Environment Variables
#===============================================
N8N_APPNAME=n8n
N8N_SUBDOMEN=n8n
#===============================================
# Glance Traefik Environment Variables
#===============================================
GLANCE_APPNAME=glance
GLANCE_SUBDOMEN=glance
#===============================================
# AdGuard Traefik Environment Variables
#===============================================
ADGUARD_APPNAME=adguard
ADGUARD_SUBDOMEN=adguard
#===============================================
# Portainer Traefik Environment Variables
#===============================================
PORTAINER_APPNAME=portainer
PORTAINER_SUBDOMEN=portainer
#===============================================
# Nextcloud Traefik Environment Variables
#===============================================
NEXTCLOUD_APPNAME=nextcloud
NEXTCLOUD_SUBDOMEN=nextcloud
#===============================================
# Aio Traefik Environment Variables
#===============================================
NEXTCLOUD_AIO_APPNAME=nextcloud-aio
NEXTCLOUD_AIO_SUBDOMEN=nextcloud-aio
# END OF TRAEFIK ENVIRONMENT VARIABLES
#===============================================
+4
View File
@@ -17,6 +17,10 @@ dockmon/data/*
portainer/portainer_data/*
metube/MeTube_downloads
uptime-kuma/data/
termix/termix-data/*
# Homepage
homepage/files/assets/images/team/*
# Traefik files
traefik/letsencrypt/acme.json
+10
View File
@@ -0,0 +1,10 @@
# everyone use that
FROM nginx:alpine
RUN rm -rf /usr/share/nginx/html/*
COPY ./files /usr/share/nginx/html
EXPOSE 80
# Start
CMD ["nginx", "-g", "daemon off;"]
+14
View File
@@ -0,0 +1,14 @@
services:
forust-homepage:
build: .
ports:
- "8085:80"
restart: unless-stopped
volumes:
- ./files:/usr/share/nginx/html
networks:
- traefik-proxy
networks:
traefik-proxy:
external: true
+167
View File
@@ -0,0 +1,167 @@
/* hidden in a plain sight? */
:root {
--bg-color: #050505;
--text-color: #e0e0e0;
--accent: #ffffff;
--dim: #666666;
--font-mono: 'Courier New', Courier, monospace;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
font-family: var(--font-mono);
line-height: 1.6;
font-size: 16px;
padding: 2rem;
}
a {
color: var(--text-color);
text-decoration: none;
border-bottom: 1px solid var(--dim);
transition: all 0.2s;
}
a:hover {
background-color: var(--text-color);
color: var(--bg-color);
border-color: var(--text-color);
}
.container {
max-width: 800px;
margin: 0 auto;
}
/* TEXT */
h1 {
font-size: 2.5rem;
text-transform: uppercase;
letter-spacing: -2px;
margin-bottom: 0.5rem;
}
h2 {
font-size: 1.2rem;
margin-bottom: 1.5rem;
border-bottom: 1px solid var(--dim);
display: inline-block;
padding-right: 20px;
}
.subtitle {
color: var(--dim);
margin-bottom: 2rem;
}
hr {
border: 0;
border-top: 1px dashed var(--dim);
margin: 2rem 0;
}
.comment {
color: var(--dim);
font-size: 0.9rem;
margin-left: 10px;
}
/* SECTIONS */
section {
margin-bottom: 3rem;
}
/* LISTS */
ul {
list-style: none;
}
.link-list li {
margin-bottom: 0.8rem;
display: flex;
align-items: center;
gap: 15px;
}
/* STACK GRID */
.grid-2 {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
}
.skill-item {
display: flex;
justify-content: space-between;
margin-bottom: 0.5rem;
}
.level {
font-weight: bold;
}
.special .level {
color: var(--text-color);
text-shadow: 1px 0 0 red, -1px 0 0 blue;
}
/* my dudes */
.team-grid {
display: flex;
gap: 2rem;
flex-wrap: wrap;
margin-top: 1rem;
}
.member {
text-align: center;
width: 100px;
}
.avatar {
width: 80px;
height: 80px;
background-color: #222;
border: 2px solid var(--text-color);
margin: 0 auto 10px auto;
background-size: cover;
}
/* if no avatar added: */
.placeholder::before {
content: "?";
display: flex;
align-items: center;
justify-content: center;
height: 100%;
font-size: 2rem;
color: var(--dim);
}
/* REPOS */
.repo-list li {
margin-bottom: 1rem;
}
/* FOOTER */
footer {
text-align: center;
color: var(--dim);
font-size: 0.8rem;
/* flag{why-are-you-here?} */
margin-top: 4rem;
}
/* SMTH RESPONSIVE */
@media (max-width: 600px) {
.grid-2 {
grid-template-columns: 1fr;
gap: 0;
}
}
+165
View File
@@ -0,0 +1,165 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MrForust // XRock</title>
<script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
<div class="container">
<header>
<h1 class="glitch" data-text="MrForust">Mr-Forust</h1>
<p class="subtitle">> CTF Player / XRock_Team / Just Signal.</p>
</header>
<hr>
<section id="socials">
<h2>./socials</h2>
<ul class="link-list">
<li>
<i class="fab fa-github"></i>
<a href="https://github.com/mr-forust" target="_blank">github/mr-forust</a>
</li>
<li>
<i class="fas fa-flag"></i>
<a href="https://tryhackme.com/p/MrForust" target="_blank">tryhackme/MrForust</a>
</li>
<li>
<i class="fab fa-telegram-plane"></i>
<a href="https://t.me/MrForust" target="_blank">telegram/MrForust</a>
</li>
<li>
<i class="fab fa-discord"></i>
<span>discord/mr.forust</span>
</li>
<li>
<i class="fas fa-envelope"></i>
<a href="mailto:forust@forust.xyz">forust@forust.xyz</a>
</li>
</ul>
</section>
<section id="stack">
<h2>./skills_and_tools</h2>
<div class="grid-2">
<div>
<div class="skill-item">
<span>ArchLinux # btw</span>
<span class="level">[#######...]</span>
</div>
<div class="skill-item">
<span>Docker Compose</span> <span class="level">[#####.....]</span>
</div>
<div class="skill-item">
<span>Web Pentest</span> <span class="level">[#####.....]</span>
</div>
<div class="skill-item">
<span>Burpsuite</span> <span class="level">[#####.....]</span>
</div>
<div class="skill-item">
<span>Docker</span> <span class="level">[####......]</span>
</div>
<div class="skill-item">
<span>Steganography</span> <span class="level">[####......]</span>
</div>
</div>
<div>
<div class="skill-item">
<span>Cryptography</span> <span class="level">[####......]</span>
</div>
<div class="skill-item">
<span>OSINT</span> <span class="level">[####......]</span>
</div>
<div class="skill-item">
<span>Python</span> <span class="level">[###.......]</span>
</div>
<div class="skill-item">
<span>HTML</span> <span class="level">[###.......]</span>
</div>
<div class="skill-item">
<span>Bash</span> <span class="level">[##........]</span>
</div>
<div class="skill-item">
<span>Golang</span> <span class="level">[#.........]</span>
</div>
</div>
</div>
</section>
<section id="team">
<h2>./xrock_team</h2>
<p class="comment"># It's a select caste. Cybershamans. Cryptoanarchists. Shadows on the net..</p>
<div class="team-grid">
<div class="member">
<div class="avatar" style="background-image: url('assets/images/team/mrforust.jpg'); background-size: cover; background-position: center;"></div>
<a href="https://github.com/mr-forust" target="_blank">MrForust</a>
</div>
<div class="member">
<div class="avatar" style="background-image: url('assets/images/team/anna.jpg'); background-size: cover; background-position: center;"></div>
<a href="" target="_blank">Anna~</a>
</div>
<div class="member">
<div class="avatar" style="background-image: url('assets/images/team/chernuha.jpg'); background-size: cover; background-position: center;"></div>
<a href="https://chernuha.space" target="_blank">Chernuha</a>
</div>
<div class="member">
<div class="avatar" style="background-image: url('assets/images/team/hudan.jpg'); background-size: cover; background-position: center;"></div>
<a href="https://hudan.xyz" target="_blank">p1ngvi</a>
</div>
<div class="member">
<div class="avatar" style="background-image: url('assets/images/team/xdfnx.jpg'); background-size: cover; background-position: center;"></div>
<a href="" target="_blank">xdfnx</a>
</div>
</div>
</section>
<section id="repos">
<h2>./favorite_repos</h2>
<ul class="repo-list">
<li>
<a href="https://github.com/TDesktop-x64/tdesktop" target="_blank">TDesktop-x64/tdesktop</a>
<span class="comment">// unofficial telegram client with some additions</span>
</li>
<li>
<a href="https://github.com/traefik/traefik" target="_blank">traefik/traefik</a>
<span class="comment">// beloved reverse-proxy</span>
</li>
<li>
<a href="https://github.com/unhappychoice/gitlogue" target="_blank">unhappychoice/gitlogue</a>
<span class="comment">// nice git log visualizer</span>
</li>
<li>
<a href="https://github.com/mountain-loop/yaak" target="_blank">mountain-loop/yaak</a>
<span class="comment">// modern, fancy api client</span>
</li>
<li>
<a href="https://github.com/pear-devs/pear-desktop" target="_blank">pear-devs/pear-desktop</a>
<span class="comment">// music client with a lot of features</span>
</li>
<li>
<a href="https://github.com/epi052/feroxbuster" target="_blank">epi052/feroxbuster</a>
<span class="comment">// directory discovery</span>
</li>
</ul>
</section>
<footer>
<p>root@xrock:~$ cat <a href="miku.html">./miku</a></p>
<p>miku?</p>
<p>root@xrock:~$ shutdown -h now</p>
<p>&copy; XRock - Just Signal.</p>
</footer>
</div>
</body>
</html>
+73
View File
@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>miku?</title>
</head>
<body bgcolor="black" text="grey">
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⠋⠉⠉⠀⠀⠀⠀⠀⠀⠛⠘⠛⠛⠛⠿⠿⠿⠿⠿⣽⠙⣛⡛⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠋⠁⠀⠀⠀⠀⠀⢀⣀⣀⣀⣀⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠂⠈⠙⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢋⣰⢋⣴⠻⣿⡟⢹⡟⠋⠀⠀⠀⠀⢀⣠⣴⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣶⣶⣶⣶⣶⣶⣿⣿⣿⣷⣶⣶⣦⣤⣄⣀⠀⠀⠉⠛⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⡀⠏⣰⠟⠁⡰⢋⠀⠀⠀⠀⠀⢀⣠⣾⣿⣿⣿⡿⠟⠛⣛⣽⣯⣿⣽⣯⣿⣟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣖⡄⠀⠀⠉⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⣠⠾⠋⠀⢊⡴⠋⠀⠀⠀⣀⣴⣿⣿⣿⡿⠋⢀⣠⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⣿⣿⣽⣿⣯⣿⣯⣿⣽⣯⣿⢿⣷⣷⣄⠀⠀⠙⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⢠⠞⠁⠀⠀⣰⠋⠀⠀⢀⣤⣾⣿⣿⣿⠿⣋⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⣝⣛⡫⠷⣿⡿⣯⣿⢿⣺⣄⠀⠈⠋⠙⣿⡻⣧⠹⣏⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠁⠀⢀⡴⠋⠀⠀⢠⡾⠁⠀⢀⣴⣿⣿⣿⣿⣿⣿⣾⠿⠛⣩⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣭⣛⣿⣿⣻⣿⣷⣤⠀⠀⠘⢷⠘⣧⠹⣆⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠋⠀⢀⡰⠍⠀⠀⢀⣴⡟⠁⢀⣶⣿⣿⣿⣿⣿⣿⠟⣋⠴⢂⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡄⠀⠀⠀⠹⣦⠘⠀⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠿⠀⠀⢀⠀⠀⠀⢰⣾⠏⢀⣴⣾⣿⣿⡿⣻⡿⢛⣡⠞⣁⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⣻⣽⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⢠⡀⠁⠘⢧⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀⠀⠀⠀⠠⠀⠀⠀⣿⠏⣴⣿⣿⣿⡿⣋⣾⠟⣱⠋⢂⣶⣿⣿⣿⣿⣿⣿⡿⣯⣿⣽⢿⡾⣟⣿⡽⣾⢽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠱⠀⠀⠈⢧⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⡋⠀⠠⢀⠏⠀⠀⠀⠀⠀⠀⢋⣾⣿⣿⣿⣿⣷⠟⡡⠞⢁⣼⣿⣿⣿⣿⣿⢟⣿⢿⣽⣟⡷⣯⣟⡿⣽⢯⡿⣽⢊⢷⣻⣟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣽⣿⣟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡂⠀⠀⠀⢫⠄⠀⠘⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⡈⠁⡌⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⣿⣿⠟⢁⢮⡱⣳⢾⣟⠋⣿⣿⡿⠃⣼⢯⡟⣾⡽⣳⠶⣭⠿⣽⣛⡞⣷⡈⢎⢷⡹⣯⣟⣿⣿⣿⣿⣿⣿⡿⣿⣿⣿⣿⣿⣿⣯⣿⣿⣿⣿⣿⣿⣟⣿⣿⣿⣿⣿⣿⣿⣷⡆⠀⠀⠀⠫⡄⠀⠈⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⡔⠀⢈⠆⠀⠀⠀⣠⣾⣿⣿⣿⣿⢛⢋⡰⣋⢮⡱⢏⡾⠍⣰⣿⡿⠁⡼⣏⠷⡘⢼⣓⠧⡓⡜⣯⢳⣭⣛⢶⡁⢊⠶⣙⢧⡻⣷⣻⣯⣿⢿⣷⣿⢿⣯⣿⢿⣽⣾⢿⣳⣿⣽⡿⣿⣿⡿⣟⣾⣽⣻⢿⣿⣿⣿⣿⣧⠀⠀⠀⠄⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡧⠀⡘⠀⡀⠌⡐⠀⠀⣼⣿⣿⣿⣿⣿⠃⢀⠦⡓⢭⡲⢭⣓⠞⢠⣿⡟⢀⣼⢳⡍⠧⡑⠈⡝⠦⡑⡍⡖⣏⢶⡩⢞⠁⡄⠘⡱⢎⡵⢫⢷⣻⣽⣿⣻⣾⢿⣽⡾⣟⣯⡿⣟⣿⣳⣯⢿⡟⣿⣿⣟⡿⣞⡿⣯⣟⣿⢿⣿⣯⡀⠀⢀⠂⠀⠀⠟⡛⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⠠⠘⠰⢀⡘⠔⢀⣾⣿⣿⣿⣿⣿⠃⠀⡎⠵⣙⠶⣹⢣⡞⠁⣾⡿⢁⡾⣡⠗⡬⠑⢀⡆⡙⢆⠱⡘⠼⣘⠦⣝⢪⠀⣗⡀⠙⡼⣘⢏⡞⡵⣛⡾⣽⢯⣟⠾⡽⣭⢿⣹⢟⣷⡻⣎⢯⢳⡌⢿⣾⣟⣯⢳⡝⣺⠽⣻⣽⣻⡇⠀⠀⠀⠀⢰⡄⠸⡈⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠂⡍⡖⠀⠌⣠⣿⣿⣿⡿⣿⡿⠃⠀⡜⣌⠳⣬⢛⡴⢫⡜⢸⣿⠃⡼⣱⢃⠞⡠⢁⣾⠁⢹⠠⢃⢌⠣⡝⣚⢬⢣⠀⣿⣦⠀⠰⡩⠞⡼⣱⢫⡝⣧⢟⡾⢫⡕⣣⢏⢞⡹⢲⡝⡜⣊⠖⠲⠈⢿⣾⣻⠸⡜⣥⠫⣝⡷⣟⡧⠀⠀⠀⠀⠰⣃⠐⢠⠀⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢀⠱⢠⠄⠈⣴⣿⣿⣿⠟⣼⡿⢡⠃⡜⡰⢊⢷⡸⣍⢞⡣⠄⣿⣏⠴⣣⠧⣉⠎⢁⣼⣯⠇⠰⣉⠌⡄⠳⣌⠧⢎⢧⠀⣿⡽⣷⠀⠈⠽⡰⢣⠳⣜⢬⢫⡜⣳⠸⣑⢎⠎⡕⢣⠜⡰⢡⠎⣡⢃⠘⣿⣽⡆⢹⠰⣍⢲⡹⣟⣿⠀⠀⠀⢀⡃⠲⠀⢠⠂⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠄⡂⡜⢀⣾⣿⣿⣿⢋⣾⣟⢠⠃⡸⢰⡑⢯⡒⢷⣘⢮⡑⢸⣯⢏⡞⣡⠞⡤⠁⣾⠋⣾⠡⠐⡥⢂⠈⡱⣈⢮⡙⢦⠐⣏⠻⣿⣷⣤⠈⠱⣋⠳⣜⢪⡓⡼⣡⠳⣉⢎⢎⡙⠦⡙⡔⠣⢎⠔⡈⠆⢹⣯⣧⠈⡳⢌⠦⣱⣛⣮⠀⠀⠀⠆⡌⢡⠃⠄⢂⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠆⡑⢠⣾⣿⣿⡻⢃⣾⣿⠋⠆⠰⣁⠦⣙⠦⣏⠳⡜⢦⠁⣾⣏⠞⡴⢱⢊⠀⣼⢏⣾⣿⡅⠈⠴⠈⠐⢠⡑⢦⡙⣧⠈⣟⣦⠹⣿⣿⣄⠀⠉⠷⣌⠳⡜⣥⢃⠯⣜⣊⢦⡙⢦⠱⣌⠳⡌⢎⠱⡈⠄⢻⣿⡄⡹⢌⠲⡡⢞⡵⠀⠀⠀⡇⠄⡃⠥⢈⠄⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⡈⠂⣴⣟⠫⡍⠰⢁⣾⣿⠃⡜⢀⠣⣐⠣⣍⠞⣌⢳⢩⢚⠀⡿⣌⠏⡼⢡⠂⠰⣿⡾⢿⣿⣇⠀⠓⡄⡄⠂⡜⢢⡝⡶⠐⣸⣿⣷⡜⢿⣿⣷⡠⠘⢌⡳⢍⠶⣩⠞⡴⣊⢦⡙⢆⡳⢌⠣⡜⣌⠲⡁⠎⠈⣿⣷⡱⢋⡒⠥⣫⠖⠀⠠⢌⡓⠌⡰⢁⠎⡐⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠀⢀⡾⢋⡌⢣⠌⢁⣿⡿⠁⡜⠀⢢⠑⡄⠳⣈⠞⡌⢎⠦⡉⢸⡗⡭⢊⡵⠁⣰⣶⣤⣤⣌⡙⠉⠷⠈⠄⢣⠐⣈⠳⣜⣳⠀⣿⣿⣿⣿⣦⡙⣿⣷⡀⠈⠼⣩⠞⣥⢛⡴⣍⠶⣉⠦⣑⠮⣑⢮⣐⢣⠱⡈⠅⠸⣷⡏⡵⢘⡐⢧⣻⠀⡡⢂⡝⢠⠐⡩⠐⢠⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠂⡰⢋⠔⠣⠘⢠⠃⣾⡟⠄⡐⢀⡘⠄⠣⢌⠱⠠⢎⡐⢣⡘⠁⣾⢸⡱⢋⠄⣘⣿⣿⣿⣿⣿⣿⣿⡦⠀⠁⢸⡄⢠⢋⢾⣱⠠⣿⣿⣿⣿⣿⣿⣌⢻⣿⣤⠈⢱⡚⢦⡛⣶⡩⢞⢥⠓⣜⢢⡍⠶⣨⢆⢣⡑⠌⡀⢿⣷⢡⠣⡘⠦⣏⠔⡁⠢⣜⠠⠂⢥⠃⠄⠂⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠅⢀⠰⠌⡌⢁⠊⠄⣸⡟⠀⡐⠀⡄⢢⢉⠒⡌⢂⠇⢢⠘⢤⠘⢰⠋⣦⡙⠂⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⡄⠘⢸⣧⠀⡚⣼⢳⠀⣿⣿⣿⣿⣿⣿⣿⡷⢈⢁⣤⠀⠍⡧⡝⢦⠻⣍⢮⡙⣤⠣⡜⢳⡰⢎⠲⣌⠒⡀⠘⣿⣎⠱⣀⠛⡼⢐⡈⠔⣌⠂⡉⠔⡨⢈⠄⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠃⠈⠐⠈⠆⢠⠂⠌⡐⢰⡿⠂⡐⠀⠰⡈⠆⡌⠒⡌⢌⡘⠤⡉⢆⠁⣼⣙⢦⠙⣠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡀⠈⣿⡇⠘⡴⣻⠀⣹⣿⣿⣿⣿⣿⣿⣶⣾⣷⣿⡖⠀⠱⣩⠏⣝⢮⠳⡜⢤⠓⣍⠲⣱⢪⡑⢆⠣⡔⠁⢹⣎⠧⢠⠙⣞⠀⢎⠐⣌⠂⣁⠚⠄⢢⠀⢽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠗⢀⣠⣶⠁⠌⠂⡌⢀⠂⢠⡿⠁⠀⠀⠀⣎⠡⡘⢠⠃⢌⠢⠄⡃⠜⡠⢀⡿⣜⠋⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⢿⣿⡆⢱⢻⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⣄⠑⢮⡱⢎⠿⣜⠦⡙⢤⠛⣤⠓⡼⣈⠇⣆⠡⠀⢻⡜⡠⢙⡼⠈⠆⡌⣰⠡⠠⠘⡌⠠⠂⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⢛⣡⣴⣿⣿⡏⠐⢨⠀⠆⠠⠁⣼⠃⠀⠀⠀⡜⢄⠢⠑⡄⢊⠄⡃⠜⡠⢃⠔⠰⣯⠍⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣾⣿⣿⣀⠹⡇⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡦⡀⠹⢎⡝⣮⢧⠙⣢⠙⣤⠛⣔⢣⡚⢤⢃⠅⡈⠞⠤⡁⢞⡥⠘⡄⢲⠀⡅⢣⠐⡡⠁⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⡈⠄⡘⢠⠁⢸⠇⠀⠀⠀⣼⠱⡈⠄⡡⠐⠌⢂⡘⠤⠑⠢⠀⣼⠇⠀⠀⠉⠙⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⣀⠉⢞⡬⣛⣇⠰⣉⠦⡹⢌⡖⡍⣆⠫⡔⡀⢈⠱⢈⠺⣄⠱⣌⠲⢁⠰⢀⠇⠄⡡⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠠⠐⢡⡘⠤⢀⡏⠀⠀⠀⣸⡱⢂⡁⠂⠄⡑⠈⡄⠰⡈⢡⠁⠐⡟⢀⣶⣤⣄⣀⠀⠀⠈⠙⠿⣿⣿⡙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⢀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡈⠲⡝⡾⣇⠈⡖⣩⠲⣌⠳⣌⢳⣜⡰⠀⠄⠊⣜⣣⢘⡧⡘⠄⢂⠡⢊⡐⠐⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠠⣉⠐⢆⠂⡼⠀⠀⠀⣼⢣⢇⠃⠠⢈⠐⠠⠁⢄⠃⠤⠁⠌⡀⢡⣿⣿⣿⣿⣿⣿⣷⣦⣄⠀⠀⠙⠻⢷⣬⣙⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⣿⣿⣿⣿⠿⠟⠛⠛⠁⠀⠘⠵⣻⡄⠸⣄⠳⣌⠳⣌⠧⣿⢰⢃⠘⡀⠰⣧⢸⠲⡍⠂⡌⢐⡃⢄⡉⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⢂⠤⡙⡄⢰⠁⠀⠀⢬⡷⣩⠎⡄⠁⠄⡈⠄⡁⢂⠌⠄⣉⠰⠀⢠⣿⡟⠉⠉⠉⠉⠀⠁⠈⠁⠀⠀⠀⠀⠈⣹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⢡⣶⠾⠟⠋⠉⠀⠀⠀⢀⣀⣀⣠⣤⣤⡀⠓⠋⡀⢨⠓⣌⠳⣌⢳⡌⢠⡋⠄⠀⠐⣽⢸⠣⡅⢃⠐⢂⡅⢂⠰⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⡌⢂⡜⠀⠃⠀⠀⡜⢲⡝⠂⣁⡀⠈⡀⠄⡐⠐⡠⢈⠂⢄⠒⠀⠈⣿⣷⣀⣠⣤⣤⣶⣶⣶⣶⣶⣶⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⠁⠀⠀⠀⠀⠀⠶⠾⣿⣿⣿⣿⣿⣿⣿⣿⠄⠀⠱⠀⡹⢄⣛⠈⣁⡘⢂⣇⠈⠆⠀⢘⣯⠃⡜⣀⠊⢄⡒⠈⡔⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⡐⢌⠒⠆⡈⠀⢠⠘⣌⢻⠌⣸⣿⠇⠀⢀⠐⠠⢁⡐⠠⠌⠂⢌⠀⠀⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣦⣤⣄⣀⠀⠀⠀⠉⠙⠻⢿⣿⡏⠀⠐⡀⠅⢀⠣⠎⠐⣿⣧⡀⢺⡀⠌⢡⠘⣮⠑⡌⠤⠈⡔⢨⢁⠰⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⡰⢈⢜⡂⠀⢀⡎⠴⡨⡇⢰⣿⣿⡁⠀⠀⠌⡐⠠⠀⡡⠘⡈⠤⠀⠀⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣄⣀⣠⣿⡟⠀⡈⠄⡐⠌⡄⢀⠩⠀⢿⣿⡄⠠⡇⠈⠄⠢⣝⠢⠜⡠⢃⡐⢃⠄⢊⠁⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠠⡐⠡⡸⠀⢠⢃⡜⢰⠱⠇⣼⣿⣿⠄⠀⠈⠄⠠⠁⠠⢂⠡⡐⠐⡀⢠⣶⡎⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⠠⠀⢂⠄⠃⠀⣬⣂⠀⢼⣿⣧⠀⢳⠈⠌⢡⢘⡇⡱⠄⡃⠌⡆⡘⠤⠁⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⡰⢁⠣⡅⡘⢄⠺⡄⢣⠛⢰⣿⣿⣿⠀⠀⠌⠠⠁⣴⣆⠁⢂⠔⠡⠀⣿⣿⣿⡸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠀⠀⡅⠀⢠⣄⡀⢈⣿⣿⣄⠈⣿⣿⣄⠈⠧⡘⢀⠎⡖⢱⡈⠔⡡⢚⡀⢆⡁⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡯⠀⡔⢡⢊⡵⢈⠜⣸⠐⣣⠁⣾⣿⣿⠿⠀⠀⠌⢀⣾⣿⡏⠀⠌⡠⢁⠀⠻⣿⣿⣷⡜⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠿⠿⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢋⣄⠀⡘⠀⠠⠘⢻⡻⣿⣿⣿⣿⠆⣿⣿⣧⠀⢃⠆⡡⢂⢝⠢⠜⡠⢁⠧⡈⢄⠒⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠰⡈⢆⣩⠆⣅⠚⣤⠙⡄⠸⣽⣿⣿⠁⠀⠀⣠⣿⣿⡿⠰⠀⢂⡁⢂⠀⣆⡈⠻⣿⣿⣦⡹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⣻⢖⡶⣹⢖⡶⣤⠦⠄⣹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⣡⣿⡟⠠⠁⣀⠃⢀⢸⣿⣿⣿⣿⣿⡇⢿⣿⣿⡄⠈⢆⠡⢂⠌⣇⠓⠤⡉⢖⠡⠊⡌⢈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠅⢢⠑⡌⡲⢌⡄⣋⠴⣉⠀⣩⣿⣿⡏⠀⢀⣴⣿⣿⣿⢁⣿⡅⢀⠒⠠⢀⣿⣷⣆⡈⠛⠿⠛⠛⠻⠿⠿⠿⢿⣿⣿⣿⣿⣷⡈⠻⣜⣧⣻⡜⡧⠋⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⣋⣴⣿⡿⠀⠀⠐⠤⠁⣾⣇⢹⣿⡿⢿⣿⣿⢸⣿⣿⣯⠀⢨⠂⡅⢊⡼⡘⠤⡑⢎⠰⢡⠘⡀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⢢⡉⠴⣙⠤⡘⢤⡓⠌⢠⣾⣿⣿⠀⣠⣾⣿⣿⣿⠇⣾⣿⣯⠀⠌⡡⠠⣿⣿⣿⣿⣦⣄⣀⠀⠂⠀⠀⠀⠀⠀⠀⠀⠉⠛⢿⣷⣬⣌⣁⣭⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⣋⣥⣾⣿⣿⣿⢃⡆⠀⢩⢀⣾⣿⣿⡌⢿⣿⣎⣿⣿⡄⣿⣿⣿⡆⢀⠳⣸⠠⡹⢄⠣⡘⢼⢀⠣⡘⡀⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡷⢀⠣⡘⢔⡫⢰⡉⢦⠍⠂⣸⣿⣿⡿⠁⣾⡟⣽⣿⡟⣰⣿⣿⣿⡀⢂⠡⢐⣿⣿⣿⣿⣿⣿⣿⣷⣤⠀⠀⠀⠋⠀⠀⠂⠀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠋⣁⣀⣀⣉⣙⣛⣻⣿⣧⣞⠀⠨⢀⣾⣿⣿⣿⣿⡘⣿⣿⡜⣿⣷⠸⣿⣿⣷⡀⠱⢸⠅⣟⠄⢣⠑⢮⠠⢃⠴⠁⢺⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢈⣒⣉⠆⠛⣀⣈⣐⢃⣴⣿⣿⣿⠅⢘⣿⣽⢿⡿⢠⣿⣿⣿⣿⣧⠀⠆⢈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣶⢢⣤⡠⢤⣤⣤⡴⢿⣿⣿⣿⣿⣿⣿⡿⠿⣛⣭⠇⣠⡴⣹⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⢠⣾⣿⣿⣿⣿⣿⣧⢹⣿⣷⣽⣿⡆⢿⣿⣿⣷⡄⢚⣉⣈⠋⠠⣍⣺⠀⠉⠦⣉⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠠⠚⣃⣋⣰⣿⣿⣿⣟⣡⣿⣿⣿⣿⣿⣿⣿⡤⣶⢀⣾⣿⣿⣿⣿⣿⣂⠨⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣬⠛⡓⢦⡙⠻⣿⣷⣬⣍⣛⣭⣵⣶⣾⡿⢋⣡⠞⣉⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⢀⣾⣿⣿⣿⣿⣿⣿⣿⡆⢩⣦⣛⣿⣿⣾⣿⣿⣿⣧⡙⢿⣿⣯⡑⣈⣑⣋⠳⢢⡀⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⡄⢰⣿⣿⣿⣷⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡔⡌⢿⣽⣿⣿⣿⣿⣿⣿⠄⠠⣿⣿⣿⣿⣿⣿⣿⣿⡿⢃⡿⣷⣶⠉⢢⡽⣷⣬⣙⠻⢿⣿⣿⠟⢋⣡⣴⢟⣡⡾⣽⣦⢿⣝⡻⣿⣿⣿⣿⣿⣿⠛⢀⣾⣿⣿⣿⣿⣿⣿⣿⡿⠻⠉⣄⣾⣿⣿⣿⣿⣿⣿⣿⣿⣼⣿⣿⣷⡘⣿⣿⡗⠀⢷⡀⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣇⢸⡁⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣮⢽⠃⠙⢿⣿⣿⣿⣷⠀⢿⣿⣿⣿⣿⡿⠛⠁⣶⢏⣼⣿⣿⣷⣦⣿⣿⣿⣿⡗⢢⡙⣡⢾⣿⣿⣿⣿⣿⣿⣿⣿⣷⣟⣿⡈⠻⠿⣿⣿⣿⣷⣾⣿⣿⣿⣿⣿⡿⠟⠡⡄⣊⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡗⠠⣸⠇⢹⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⠇⠸⣷⡀⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣀⠸⣦⣈⠻⢿⣿⣧⣿⣿⣿⣿⣿⠀⠘⡇⢻⣼⣿⣿⣿⣿⣿⣿⣿⣿⠿⢿⣦⠙⢹⠏⣿⣿⣿⣿⣿⣿⠟⢿⣿⣿⣿⠀⠳⣀⢻⣿⣿⣿⣿⣿⣿⣿⠿⢋⣤⡞⢠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠀⣰⡿⢀⢸⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⡏⠀⠀⠙⢷⡄⠹⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⠀⠈⠙⢷⣆⡙⢿⣿⣿⣿⣿⣿⠁⢠⣆⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⠗⣀⣄⣤⣤⣌⡐⢼⣿⣿⡿⠁⢰⡦⢙⠿⡿⢀⣃⠈⣿⣿⣿⣿⣿⣿⠛⣡⡶⠟⠁⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠋⢀⣼⠟⠀⠠⠈⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⡟⠀⠀⠀⠀⠈⠛⢷⣄⡙⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡗⠀⠀⠀⠀⠙⢷⣆⠹⣿⣿⡿⠃⠄⣸⡆⠀⢻⣿⣿⣿⣿⣿⣿⡟⠁⢰⡿⣯⢿⡽⣯⢿⡀⢻⣿⠁⢠⣧⣶⡏⣰⠁⢸⣇⠀⠈⣿⣿⣿⠏⢀⣶⠟⠁⠀⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠉⣀⣴⠿⠉⠀⠀⠀⠁⠸⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠉⠻⢶⣄⡙⠛⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⠀⠀⠀⠀⠀⠀⠙⣷⡌⠻⣧⠐⣰⣿⣷⠀⠈⢿⣿⣿⣿⡿⠋⡁⠔⢺⠿⣽⢫⡽⣯⣟⠲⠄⡙⠿⣦⣍⡛⣰⠏⠀⣿⣿⡄⠀⢨⡿⠃⣴⡟⠁⠀⠀⠀⠀⠀⠀⠙⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠏⢁⣁⣴⠞⠋⠁⠀⠀⠀⠀⠀⠀⠀⢹⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠷⣦⣄⡉⠛⠻⢿⣿⣿⣿⣿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣄⠁⣰⣾⣿⣿⣧⠀⠈⠉⢉⣀⣴⡾⣷⡀⠈⢻⣓⣯⣙⡳⠃⣀⣶⣌⣐⠠⢠⡉⢀⠀⣶⡿⣿⣿⣄⠘⠁⣼⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⢯⢿⣿⡿⡿⠻⠛⢉⣀⣤⡾⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣿⣿⣿⣿⣿
⣿⣿⣿⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠙⠻⠶⣤⡈⠉⠙⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⢁⠂⠀⣿⠀⠙⣿⣿⣽⣿⣿⣿⣷⣾⡿⣷⣻⢷⣻⠀⢠⣟⡾⣽⢣⠀⣾⣿⣿⣻⣷⣶⣶⣿⣯⣿⣷⢿⣿⡟⠀⢸⠃⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⢀⣠⡴⠚⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣿⣿⣿⣿
⣿⣿⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠙⠲⢍⡖⣆⠦⠤⠤⠤⢠⣄⡌⣤⢤⣤⣙⠖⢠⣿⣿⣻⣾⣿⣿⣿⣷⣿⣳⣽⣻⣿⠇⢸⣞⡽⣽⢫⠐⠿⣿⣷⣿⣿⣿⣿⣿⣿⣿⣿⣾⣿⡃⠐⣮⣤⢤⠤⣤⠤⣄⠤⠤⢤⢒⡤⢎⡜⠣⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿
⣿⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠓⠉⠓⠾⠜⠻⠞⠙⠁⣰⣾⣿⣿⣽⣿⣿⣿⣿⣿⣷⣿⣞⣿⣿⠀⢸⣎⣟⢮⣏⠀⢺⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣀⠙⠋⠛⠲⠛⠜⠉⠛⠈⠁⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣿⣿⣿
⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢺⠀⣿⣿⣿⣿⣷⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⣿⠀⢸⡮⣝⡞⡼⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⢸⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⣿
⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⡿⣼⡹⣜⡱⠂⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡅⠈⢸⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣿
⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⡿⢃⠀⡿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢠⢳⢧⡝⢦⡹⡁⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠄⢈⠻⣿⣧⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡰⢻⣿⣿⠇⠀⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⢰⣋⢶⡹⢎⡵⣁⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⣝⢿⣿⣿⡄⠈⠰⣿⣿⣿⣦⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣰⣿⣿⡘⣿⠅⠠⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠸⡜⡶⣩⢳⢎⡵⢸⣿⣿⣿⡏⠹⠿⠿⠟⠻⠛⡟⠻⠟⠀⣿⣿⣷⡀⠠⠙⣿⡏⣸⣿⣶⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⣿⡇⠝⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠂⢼⡹⣱⢏⡾⣘⠖⠘⣿⣿⣿⣿⣦⣉⣉⣭⣭⣤⣭⣤⣈⣸⣿⣿⣿⣧⠀⠘⢿⢀⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⠀⠊⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⢧⡛⡽⢪⠵⣩⠞⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠹⣿⣿⣿⣿⣆⠈⠀⢸⣿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣾⣿⣿⣿⣿⣿⣿⣿⡿⠂⠀⢸⣿⣿⣿⣟⡳⢯⣛⠿⣻⢿⡿⣿⠻⣟⣿⣿⣿⣿⠀⣎⠵⣩⢳⡙⢦⢫⠄⢻⣿⣿⣿⣿⢿⣻⡟⣿⢫⠟⡵⢪⢇⣹⣿⣿⣿⣿⡇⢈⠹⣿⣿⣿⣿⣿⣿⣿⣷⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀⣠⣾⢿⣿⡗⢮⡑⢣⠘⡬⢑⠮⡑⢎⡱⢎⡞⡽⢹⡃⠀⡎⢧⠣⢧⣝⢣⢏⠆⡸⣏⠿⣱⢎⢳⡘⡜⢢⢋⡜⢌⡑⢊⠴⢻⣿⣿⣿⡇⠈⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
</body>
</html>
+21
View File
@@ -0,0 +1,21 @@
services:
termix:
image: ghcr.io/lukegus/termix:latest
container_name: termix
restart: unless-stopped
ports:
- "3331:8080"
volumes:
- ./termix-data:/app/data
environment:
PORT: "8080"
networks:
- traefik-proxy
networks:
traefik-proxy:
external: true
volumes:
termix-data:
driver: local
+328
View File
@@ -0,0 +1,328 @@
http:
routers:
# Traefik Dashboard (ADMIN, local only)
traefik-dashboard:
rule: "Host(`traefik.workstation`)"
entryPoints:
- websecure
service: api@internal
middlewares:
# - auth
- security-headers
tls: {}
# Nextcloud AIO Interface (ADMIN, local is better)
nextcloud-aio:
rule: "Host(`nextcloud-aio.workstation`)"
entryPoints:
- websecure
service: nextcloud-aio
middlewares:
- security-headers
tls: {}
# Termix (public (account required))
termix:
rule: "Host(`termix.forust.xyz`)"
entryPoints:
- websecure
service: termix
middlewares:
- security-headers
tls: {}
# MeTube
metube:
rule: "Host(`metube.forust.xyz`)"
entryPoints:
- websecure
service: metube
middlewares:
- metube-auth
- security-headers
tls: {}
# Portainer (public (account required))
portainer:
rule: "Host(`portainer.forust.xyz`)"
entryPoints:
- websecure
service: portainer
middlewares:
- security-headers
tls: {}
# Uptime Kuma
uptime-kuma:
rule: "Host(`uptime.forust.xyz`)"
entryPoints:
- websecure
service: uptime-kuma
tls: {}
# AdGuard Home (public (account required))
adguard:
rule: "Host(`adguard.forust.xyz`)"
entryPoints:
- websecure
service: adguard
middlewares:
- security-headers
tls: {}
# Nextcloud Main (public (account required))
nextcloud:
rule: "Host(`nextcloud.forust.xyz`)"
entrypoints:
- websecure
service: nextcloud
middlewares:
- nextcloud-chain
tls: {}
# Dockmon (public (account required))
dockmon:
rule: "Host(`dockmon.forust.xyz`)"
entryPoints:
- websecure
service: dockmon
middlewares:
# - dockmon-auth
- security-headers
tls: {}
# Gitea (public (account required))
gitea:
rule: "Host(`gitea.forust.xyz`)"
entryPoints:
- websecure
- ssh
service: gitea
middlewares:
- security-headers
tls: {}
# # Glance (local only)
# glance:
# rule: "Host(`glance.workstation`)"
# entryPoints:
# - websecure
# service: glance
# middlewares:
# - security-headers
# tls: {}
# Watercrawl (local only)
watercrawl:
rule: "Host(`watercrawl.workstation`)"
entryPoints:
- websecure
service: watercrawl
middlewares:
- security-headers
tls: {}
# N8N (local only)
n8n:
rule: "Host(`n8n.workstation`)"
entryPoints:
- websecure
service: n8n
middlewares:
- security-headers
tls: {}
services:
# Portainer
portainer:
loadBalancer:
servers:
- url: "https://portainer:9443"
serversTransport: insecureTransport
# AdGuard Home
adguard:
loadBalancer:
servers:
- url: "http://adguardhome:3000"
# Nextcloud AIO Interface
nextcloud-aio:
loadBalancer:
servers:
- url: "https://nextcloud-aio-mastercontainer:8080"
serversTransport: insecureTransport
# Nextcloud Main
nextcloud:
loadBalancer:
servers:
- url: "http://nextcloud-aio-apache:11000"
# Uptime Kuma
uptime-kuma:
loadBalancer:
servers:
- url: "http://uptime-kuma:3001"
# Termix
termix:
loadBalancer:
servers:
- url: "http://termix:8080"
# Dockmon
dockmon:
loadBalancer:
servers:
- url: "https://dockmon:443"
serversTransport: insecureTransport
# # Glance
# glance:
# loadBalancer:
# servers:
# - url: "http://glance:8080"
# Watercrawl
watercrawl:
loadBalancer:
servers:
- url: "http://nginx:80"
# N8N
n8n:
loadBalancer:
servers:
- url: "http://n8n:5678"
# Gitea
gitea:
loadBalancer:
servers:
- url: "http://gitea:3000"
# MeTube
metube:
loadBalancer:
servers:
- url: "http://metube:8081"
serversTransports:
insecureTransport:
insecureSkipVerify: true
middlewares:
# HTTPS Redirect
redirect-https:
redirectScheme:
scheme: https
permanent: true
# Metube Basic Auth
metube-auth:
basicAuth:
users:
- "admin:$2y$05$3Q6gyLFW3NFNp4C6elnyfupntqB6VNB/tcIAeo8NEzvaqPxOjN0iC"
# - "jeepik:$2y$05$tIKrmhd7SYOe6yImRRAfpen7hpVdF8PnSbgBTCDZ.GI0Djx.Le2bq"
realm: "MeTube Access"
# Basic Auth Traefik Dashboard
auth:
basicAuth:
users:
- "admin:$$apr1$$57E60OUM$$JoYwmLr/uZKaTy6U4IQd9."
# - "jeepik:$2y$05$Q8QqJwSjpycVYONyk4id/.rDFApW9oL8tycRMlGttNySsDv71Rnsu"
# - "vv:"
realm: "Traefik Dashboard"
# Basic Auth Dockmon
dockmon-auth:
basicAuth:
users:
- "admin:$$apr1$$.bCpmIHl$$dxPEKdw5aZLAwo8wUz52b1"
realm: "Dockmon Access"
# Cloudflare IP Whitelist
cloudflare-ipwhitelist:
ipWhiteList:
sourceRange:
- "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"
# Security Headers
security-headers:
headers:
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 31536000
customFrameOptionsValue: "SAMEORIGIN"
customResponseHeaders:
X-Content-Type-Options: "nosniff"
Referrer-Policy: "strict-origin-when-cross-origin"
# Nextcloud specific headers
nextcloud-secure-headers:
headers:
hostsProxyHeaders:
- "X-Forwarded-Host"
- "X-Forwarded-Proto"
referrerPolicy: "same-origin"
customFrameOptionsValue: "SAMEORIGIN"
# Rate limiting
rate-limit:
rateLimit:
average: 100
burst: 50
period: 1m
# Nextcloud chain
nextcloud-chain:
chain:
middlewares:
- nextcloud-secure-headers
- security-headers
# TLS Configuration
tls:
certificates:
# Cloudflare Origin CA *.forust.xyz
- certFile: /certs/cloudflare.pem
keyFile: /certs/cloudflare.key
# Local certificate
- certFile: /certs/workstation+1.pem
keyFile: /certs/workstation+1-key.pem
stores:
default:
defaultCertificate:
# Fallback local certificate
certFile: /certs/workstation+1.pem
keyFile: /certs/workstation+1-key.pem
options:
default:
minVersion: VersionTLS12
sniStrict: true
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
-309
View File
@@ -1,313 +1,4 @@
http:
routers:
# Traefik Dashboard (ADMIN, local only)
traefik-dashboard:
rule: "Host(`traefik.workstation`)"
entryPoints:
- websecure
service: api@internal
middlewares:
# - auth
- security-headers
tls: {}
# Nextcloud AIO Interface (ADMIN, local is better)
nextcloud-aio:
rule: "Host(`nextcloud-aio.workstation`)"
entryPoints:
- websecure
service: nextcloud-aio
middlewares:
- security-headers
tls: {}
# MeTube
metube:
rule: "Host(`metube.forust.xyz`)"
entryPoints:
- websecure
service: metube
middlewares:
- metube-auth
- security-headers
tls: {}
# Portainer (public (account required))
portainer:
rule: "Host(`portainer.forust.xyz`)"
entryPoints:
- websecure
service: portainer
middlewares:
- security-headers
tls: {}
# # Uptime Kuma
# uptime-kuma:
# rule: "Host(`uptime-kuma.forust.xyz`)"
# entryPoints:
# - websecure
# service: uptime-kuma
# # middlewares:
# # - security-headers
# tls: {}
# AdGuard Home (public (account required))
adguard:
rule: "Host(`adguard.forust.xyz`)"
entryPoints:
- websecure
service: adguard
middlewares:
- security-headers
tls: {}
# Nextcloud Main (public (account required))
nextcloud:
rule: "Host(`nextcloud.forust.xyz`)"
entrypoints:
- websecure
service: nextcloud
middlewares:
- nextcloud-chain
tls: {}
# Dockmon (public (account required))
dockmon:
rule: "Host(`dockmon.forust.xyz`)"
entryPoints:
- websecure
service: dockmon
middlewares:
# - dockmon-auth
- security-headers
tls: {}
# Gitea (public (account required))
gitea:
rule: "Host(`gitea.forust.xyz`)"
entryPoints:
- websecure
- ssh
service: gitea
middlewares:
- security-headers
tls: {}
# # Glance (local only)
# glance:
# rule: "Host(`glance.workstation`)"
# entryPoints:
# - websecure
# service: glance
# middlewares:
# - security-headers
# tls: {}
# Watercrawl (local only)
watercrawl:
rule: "Host(`watercrawl.workstation`)"
entryPoints:
- websecure
service: watercrawl
middlewares:
- security-headers
tls: {}
# N8N (local only)
n8n:
rule: "Host(`n8n.workstation`)"
entryPoints:
- websecure
service: n8n
middlewares:
- security-headers
tls: {}
services:
# Portainer
portainer:
loadBalancer:
servers:
- url: "https://portainer:9443"
serversTransport: insecureTransport
# AdGuard Home
adguard:
loadBalancer:
servers:
- url: "http://adguardhome:3000"
# Nextcloud AIO Interface
nextcloud-aio:
loadBalancer:
servers:
- url: "https://nextcloud-aio-mastercontainer:8080"
serversTransport: insecureTransport
# Nextcloud Main
nextcloud:
loadBalancer:
servers:
- url: "http://nextcloud-aio-apache:11000"
# # Uptime Kuma
# uptime-kuma:
# loadBalancer:
# servers: "http://uptime-kuma:3001"
# Dockmon
dockmon:
loadBalancer:
servers:
- url: "https://dockmon:443"
serversTransport: insecureTransport
# # Glance
# glance:
# loadBalancer:
# servers:
# - url: "http://glance:8080"
# Watercrawl
watercrawl:
loadBalancer:
servers:
- url: "http://nginx:80"
# N8N
n8n:
loadBalancer:
servers:
- url: "http://n8n:5678"
# Gitea
gitea:
loadBalancer:
servers:
- url: "http://gitea:3000"
# MeTube
metube:
loadBalancer:
servers:
- url: "http://metube:8081"
serversTransports:
insecureTransport:
insecureSkipVerify: true
middlewares:
# HTTPS Redirect
redirect-https:
redirectScheme:
scheme: https
permanent: true
# Metube Basic Auth
metube-auth:
basicAuth:
users:
- "admin:$2y$05$3Q6gyLFW3NFNp4C6elnyfupntqB6VNB/tcIAeo8NEzvaqPxOjN0iC"
# - "jeepik:$2y$05$tIKrmhd7SYOe6yImRRAfpen7hpVdF8PnSbgBTCDZ.GI0Djx.Le2bq"
realm: "MeTube Access"
# Basic Auth Traefik Dashboard
auth:
basicAuth:
users:
- "admin:$$apr1$$57E60OUM$$JoYwmLr/uZKaTy6U4IQd9."
# - "jeepik:$2y$05$Q8QqJwSjpycVYONyk4id/.rDFApW9oL8tycRMlGttNySsDv71Rnsu"
# - "vv:"
realm: "Traefik Dashboard"
# Basic Auth Dockmon
dockmon-auth:
basicAuth:
users:
- "admin:$$apr1$$.bCpmIHl$$dxPEKdw5aZLAwo8wUz52b1"
realm: "Dockmon Access"
# Cloudflare IP Whitelist
cloudflare-ipwhitelist:
ipWhiteList:
sourceRange:
- "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"
# Security Headers
security-headers:
headers:
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 31536000
customFrameOptionsValue: "SAMEORIGIN"
customResponseHeaders:
X-Content-Type-Options: "nosniff"
Referrer-Policy: "strict-origin-when-cross-origin"
# Nextcloud specific headers
nextcloud-secure-headers:
headers:
hostsProxyHeaders:
- "X-Forwarded-Host"
- "X-Forwarded-Proto"
referrerPolicy: "same-origin"
customFrameOptionsValue: "SAMEORIGIN"
# Rate limiting
rate-limit:
rateLimit:
average: 100
burst: 50
period: 1m
# Nextcloud chain
nextcloud-chain:
chain:
middlewares:
- nextcloud-secure-headers
- security-headers
# TLS Configuration
tls:
certificates:
# Cloudflare Origin CA *.forust.xyz
- certFile: /certs/cloudflare.pem
keyFile: /certs/cloudflare.key
# Local certificate
- certFile: /certs/workstation+1.pem
keyFile: /certs/workstation+1-key.pem
stores:
default:
defaultCertificate:
# Fallback local certificate
certFile: /certs/workstation+1.pem
keyFile: /certs/workstation+1-key.pem
options:
default:
minVersion: VersionTLS12
sniStrict: true
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
+90
View File
@@ -0,0 +1,90 @@
http:
middlewares:
# HTTPS Redirect
redirect-https:
redirectScheme:
scheme: https
permanent: true
# Metube Basic Auth
metube-auth:
basicAuth:
users:
- "admin:$2y$05$3Q6gyLFW3NFNp4C6elnyfupntqB6VNB/tcIAeo8NEzvaqPxOjN0iC"
# - "jeepik:$2y$05$tIKrmhd7SYOe6yImRRAfpen7hpVdF8PnSbgBTCDZ.GI0Djx.Le2bq"
- "vv:$2y$05$JdT8AGUO9bd.E/PiCmKaoOJS1RFlXkrrmZ5mJ4f8/a1bEW39L3FbS"
realm: "MeTube Access"
# Basic Auth Traefik Dashboard
auth:
basicAuth:
users:
- "admin:$$apr1$$57E60OUM$$JoYwmLr/uZKaTy6U4IQd9."
# - "jeepik:$2y$05$Q8QqJwSjpycVYONyk4id/.rDFApW9oL8tycRMlGttNySsDv71Rnsu"
# - "vv:"
realm: "Traefik Dashboard"
# Basic Auth Dockmon
dockmon-auth:
basicAuth:
users:
- "admin:$$apr1$$.bCpmIHl$$dxPEKdw5aZLAwo8wUz52b1"
realm: "Dockmon Access"
# Cloudflare IP Whitelist
cloudflare-ipwhitelist:
ipWhiteList:
sourceRange:
- "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"
# Security Headers
security-headers:
headers:
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 31536000
customFrameOptionsValue: "SAMEORIGIN"
customResponseHeaders:
X-Content-Type-Options: "nosniff"
Referrer-Policy: "strict-origin-when-cross-origin"
# Nextcloud specific headers
nextcloud-secure-headers:
headers:
hostsProxyHeaders:
- "X-Forwarded-Host"
- "X-Forwarded-Proto"
referrerPolicy: "same-origin"
customFrameOptionsValue: "SAMEORIGIN"
# Rate limiting
rate-limit:
rateLimit:
average: 100
burst: 50
period: 1m
# Nextcloud chain
nextcloud-chain:
chain:
middlewares:
- nextcloud-secure-headers
- security-headers
+143
View File
@@ -0,0 +1,143 @@
http:
routers:
# Traefik Dashboard (dev access. local only)
traefik-dashboard-dev:
rule: "Host(`traefik.gigaforust`)"
entryPoints:
- websecure
service: api@internal
middlewares:
# - auth
- security-headers
tls: {}
# Nextcloud AIO Interface (dev access. local only)
nextcloud-aio-dev:
rule: "Host(`nextcloud-aio.gigaforust`)"
entryPoints:
- websecure
service: nextcloud-aio
middlewares:
- security-headers
tls: {}
# Termix (dev access, (account required))
termix-dev:
rule: "Host(`termix.gigaforust`)"
entryPoints:
- websecure
service: termix
middlewares:
- security-headers
tls: {}
# MeTube (dev access, (auth required))
metube-dev:
rule: "Host(`metube.gigaforust`)"
entryPoints:
- websecure
service: metube
middlewares:
- metube-auth
- security-headers
tls: {}
# Portainer (dev acess, (account required))
portainer-dev:
rule: "Host(`portainer.gigaforust`)"
entryPoints:
- websecure
service: portainer
middlewares:
- security-headers
tls: {}
# Uptime Kuma (dev access, (account required))
uptime-kuma-dev:
rule: "Host(`uptime.gigaforust`)"
entryPoints:
- websecure
service: uptime-kuma
tls: {}
# AdGuard Home (dev access, (account required))
adguard-dev:
rule: "Host(`adguard.gigaforust`)"
entryPoints:
- websecure
service: adguard
middlewares:
- security-headers
tls: {}
# Nextcloud Main (public (account required))
nextcloud-dev:
rule: "Host(`nextcloud.gigaforust`)"
entrypoints:
- websecure
service: nextcloud
middlewares:
- nextcloud-chain
tls: {}
# Dockmon (dev access (account required))
dockmon-dev:
rule: "Host(`dockmon.gigaforust`)"
entryPoints:
- websecure
service: dockmon
middlewares:
- security-headers
tls: {}
# Gitea (dev access (account required))
gitea-dev:
rule: "Host(`gitea.gigaforust`)"
entryPoints:
- websecure
- ssh
service: gitea
middlewares:
- security-headers
tls: {}
# Glance (dev access, local only)
glance-dev:
rule: "Host(`glance.gigaforust`)"
entryPoints:
- websecure
service: glance
middlewares:
- security-headers
tls: {}
# Watercrawl (dev access, local only)
watercrawl-dev:
rule: "Host(`watercrawl.gigaforust`)"
entryPoints:
- websecure
service: watercrawl
middlewares:
- security-headers
tls: {}
# N8N (local only)
n8n-dev:
rule: "Host(`n8n.gigaforust`)"
entryPoints:
- websecure
service: n8n
middlewares:
- security-headers
tls: {}
# Landing Page (public)
forust-homepage-dev:
rule: "Host(`landing.gigaforust`)"
entryPoints:
- websecure
service: forust-homepage
middlewares:
- security-headers
tls: {}
+143
View File
@@ -0,0 +1,143 @@
http:
routers:
# Traefik Dashboard (local access, ADMIN, local only)
traefik-dashboard-local:
rule: "Host(`traefik.workstation`)"
entryPoints:
- websecure
service: api@internal
middlewares:
# - auth
- security-headers
tls: {}
# Nextcloud AIO Interface (local access. ADMIN, local only)
nextcloud-aio-local:
rule: "Host(`nextcloud-aio.workstation`)"
entryPoints:
- websecure
service: nextcloud-aio
middlewares:
- security-headers
tls: {}
# Termix (local access, (account required))
termix-local:
rule: "Host(`termix.workstation`)"
entryPoints:
- websecure
service: termix
middlewares:
- security-headers
tls: {}
# MeTube (local access, (auth required))
metube-local:
rule: "Host(`metube.workstation`)"
entryPoints:
- websecure
service: metube
middlewares:
- metube-auth
- security-headers
tls: {}
# Portainer (dev acess, (account required))
portainer-local:
rule: "Host(`portainer.workstation`)"
entryPoints:
- websecure
service: portainer
middlewares:
- security-headers
tls: {}
# Uptime Kuma (local access, (account required))
uptime-kuma-local:
rule: "Host(`uptime.workstation`)"
entryPoints:
- websecure
service: uptime-kuma
tls: {}
# AdGuard Home (local access, (account required))
adguard-local:
rule: "Host(`adguard.workstation`)"
entryPoints:
- websecure
service: adguard
middlewares:
- security-headers
tls: {}
# Nextcloud Main (public (account required))
nextcloud-local:
rule: "Host(`nextcloud.workstation`)"
entrypoints:
- websecure
service: nextcloud
middlewares:
- nextcloud-chain
tls: {}
# Dockmon (local access (account required))
dockmon-local:
rule: "Host(`dockmon.workstation`)"
entryPoints:
- websecure
service: dockmon
middlewares:
- security-headers
tls: {}
# Gitea (local access (account required))
gitea-local:
rule: "Host(`gitea.workstation`)"
entryPoints:
- websecure
- ssh
service: gitea
middlewares:
- security-headers
tls: {}
# Glance (local access)
glance-local:
rule: "Host(`glance.workstation`)"
entryPoints:
- websecure
service: glance
middlewares:
- security-headers
tls: {}
# Watercrawl (local access)
watercrawl-local:
rule: "Host(`watercrawl.workstation`)"
entryPoints:
- websecure
service: watercrawl
middlewares:
- security-headers
tls: {}
# N8N (local only)
n8n-local:
rule: "Host(`n8n.workstation`)"
entryPoints:
- websecure
service: n8n
middlewares:
- security-headers
tls: {}
# Landing Page (local access)
forust-homepage-local:
rule: "Host(`landing.workstation`)"
entryPoints:
- websecure
service: forust-homepage
middlewares:
- security-headers
tls: {}
+142
View File
@@ -0,0 +1,142 @@
http:
routers:
# Traefik Dashboard (ADMIN, without subdomeain)
traefik-dashboard:
rule: "Host(`traefik.forust.xyz`)"
entryPoints:
- websecure
service: api@internal
middlewares:
- auth
- security-headers
tls: {}
# Nextcloud AIO Interface (ADMIN, without subdomeain)
nextcloud-aio:
rule: "Host(`nextcloud-aio.forust.xyz`)"
entryPoints:
- websecure
service: nextcloud-aio
middlewares:
- security-headers
tls: {}
# Termix (public (account required))
termix:
rule: "Host(`termix.forust.xyz`)"
entryPoints:
- websecure
service: termix
middlewares:
- security-headers
tls: {}
# MeTube (public (auth required))
metube:
rule: "Host(`metube.forust.xyz`)"
entryPoints:
- websecure
service: metube
middlewares:
- metube-auth
- security-headers
tls: {}
# Portainer (public (account required))
portainer:
rule: "Host(`portainer.forust.xyz`)"
entryPoints:
- websecure
service: portainer
middlewares:
- security-headers
tls: {}
# Uptime Kuma (public (account required))
uptime-kuma:
rule: "Host(`uptime.forust.xyz`)"
entryPoints:
- websecure
service: uptime-kuma
tls: {}
# AdGuard Home (public (account required))
adguard:
rule: "Host(`adguard.forust.xyz`)"
entryPoints:
- websecure
service: adguard
middlewares:
- security-headers
tls: {}
# Nextcloud Main (public (account required))
nextcloud:
rule: "Host(`nextcloud.forust.xyz`)"
entrypoints:
- websecure
service: nextcloud
middlewares:
- nextcloud-chain
tls: {}
# Dockmon (public (account required))
dockmon:
rule: "Host(`dockmon.forust.xyz`)"
entryPoints:
- websecure
service: dockmon
middlewares:
- security-headers
tls: {}
# Gitea (public (account required))
gitea:
rule: "Host(`gitea.forust.xyz`)"
entryPoints:
- websecure
- ssh
service: gitea
middlewares:
- security-headers
tls: {}
# Glance (public, without subdomain)
glance:
rule: "Host(`glance.forust.xyz`)"
entryPoints:
- websecure
service: glance
middlewares:
- security-headers
tls: {}
# Watercrawl (public, without subdomain)
watercrawl:
rule: "Host(`watercrawl.fourst.xyz`)"
entryPoints:
- websecure
service: watercrawl
middlewares:
- security-headers
tls: {}
# N8N (public, without subdomain)
n8n:
rule: "Host(`n8n.forust.xyz`)"
entryPoints:
- websecure
service: n8n
middlewares:
- security-headers
tls: {}
# Landing Page (public)
forust-homepage:
rule: "Host(`forust.xyz`)"
entryPoints:
- websecure
service: forust-homepage
middlewares:
- security-headers
tls: {}
+80
View File
@@ -0,0 +1,80 @@
http:
services:
# Portainer
portainer:
loadBalancer:
servers:
- url: "https://portainer:9443"
serversTransport: insecureTransport
# AdGuard Home
adguard:
loadBalancer:
servers:
- url: "http://adguardhome:3000"
# Nextcloud AIO Interface
nextcloud-aio:
loadBalancer:
servers:
- url: "https://nextcloud-aio-mastercontainer:8080"
serversTransport: insecureTransport
# Nextcloud Main
nextcloud:
loadBalancer:
servers:
- url: "http://nextcloud-aio-apache:11000"
# Uptime Kuma
uptime-kuma:
loadBalancer:
servers:
- url: "http://uptime-kuma:3001"
# Termix
termix:
loadBalancer:
servers:
- url: "http://termix:8080"
# Dockmon
dockmon:
loadBalancer:
servers:
- url: "https://dockmon:443"
serversTransport: insecureTransport
# Glance
glance:
loadBalancer:
servers:
- url: "http://glance:8080"
# Watercrawl
watercrawl:
loadBalancer:
servers:
- url: "http://nginx:80"
# N8N
n8n:
loadBalancer:
servers:
- url: "http://n8n:5678"
# Gitea
gitea:
loadBalancer:
servers:
- url: "http://gitea:3000"
# MeTube
metube:
loadBalancer:
servers:
- url: "http://metube:8081"
# Landing Page
forust-homepage:
loadBalancer:
servers:
- url: "http://forust-homepage:80"
+25
View File
@@ -0,0 +1,25 @@
# TLS Configuration
tls:
certificates:
# Cloudflare Origin CA *.forust.xyz
- certFile: /certs/cloudflare.pem
keyFile: /certs/cloudflare.key
# Local certificate
- certFile: /certs/workstation+1.pem
keyFile: /certs/workstation+1-key.pem
stores:
default:
defaultCertificate:
# Fallback local certificate
certFile: /certs/workstation+1.pem
keyFile: /certs/workstation+1-key.pem
options:
default:
minVersion: VersionTLS12
sniStrict: true
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
-5
View File
@@ -10,11 +10,6 @@ services:
- "3001:3001"
labels:
- "traefik.enable=true"
- "traefik.http.routers.uptime-kuma.rule=Host(`uptime-kuma.forust.xyz`)"
- "traefik.http.routers.uptime-kuma.entrypoints=websecure"
- "traefik.http.routers.uptime-kuma.tls=true"
# - "traefik.http.routers.uptime-kuma.tls.certresolver=myresolver"
- "traefik.http.services.uptime-kuma.loadBalancer.server.port=3001"
networks:
- traefik-proxy
networks: