This commit is contained in:
Mike McFetridge
2026-07-20 09:22:40 -04:00
parent be7f1096eb
commit 3173f33e38
25 changed files with 1241 additions and 1 deletions
+4
View File
@@ -0,0 +1,4 @@
PUID=1000
PGID=1000
# TZ for container timezone
TZ=America/New_York
+3
View File
@@ -0,0 +1,3 @@
---
+385
View File
@@ -0,0 +1,385 @@
@import url('https://fonts.googleapis.com/css2?family=Fira+Code&family=Orbitron:wght@500;700;900&family=Poppins:wght@300;400;500;600&family=Rajdhani:wght@500;600;700&display=swap');
/* APPLY STYLING AND THEME VARIABLES GLOBALLY & ON ACTIVE THEMES */
:root, .dark, .theme-gray, .theme-slate, .theme-zinc {
font-family: 'Poppins', sans-serif;
/* DRACULA & CYBERPUNK COLOR SYSTEM */
--dracula-background: #181923;
--dracula-background-dark: #0f1015;
--dracula-foreground: #2d3142;
--dracula-text: #f8f8f2;
--dracula-slate: #6272a4;
--dracula-cyan: #8be9fd;
--dracula-green: #50fa7b;
--dracula-orange: #ffb86c;
--dracula-pink: #ff79c6;
--dracula-purple: #bd93f9;
--dracula-red: #ff5555;
--dracula-yellow: #f1fa8c;
/* Theme preset colors (RGB values for Tailwind transparency support) */
--color-50: 249 250 251;
--color-100: 243 244 246;
--color-200: 248 248 242; /* Text Color */
--color-300: 209 213 219;
--color-400: 156 163 175;
--color-500: 107 114 128;
--color-600: 75 85 99;
--color-700: 45 49 66;
--color-800: 24 25 35; /* Main container background */
--color-900: 15 16 21; /* Core background */
--color-logo-start: 189 147 249;
--color-logo-stop: 139 233 253;
--standard-bg: rgba(45, 49, 66, 0.45);
/* INFO WIDGET COLORS */
--info-widgets: var(--dracula-cyan);
--resource-bar-bg: rgba(98, 114, 164, 0.2);
--resource-bar-fg: var(--dracula-cyan);
--widget-border: rgba(139, 233, 253, 0.2);
/* SERVICES COLORS */
--service-group: var(--dracula-purple);
--service-name: var(--dracula-text);
--service-description: #a9b1d6;
--service-block-bg: rgba(15, 16, 21, 0.7);
--service-block-text: var(--dracula-pink);
/* BOOKMARKS COLORS */
--bookmark-group: var(--dracula-purple);
--bookmark-icon-bg: rgba(189, 147, 249, 0.15);
--bookmark-icon: var(--dracula-purple);
--bookmark-name: var(--dracula-text);
/* ALL CARD COLORS (GLASSMORPHISM DEFAULT) */
--card-color: rgba(30, 32, 48, 0.55);
--card-color-hover: rgba(40, 44, 68, 0.8);
/* FOOTER COLORS */
--footer-items: var(--dracula-purple);
--scrollbar-fg: var(--dracula-purple);
--scrollbar-bg: var(--dracula-background-dark);
}
/* ==========================================
* FUTURISTIC SCIFI HUD OVERLAY
* ========================================== */
body {
background-color: #0c0d12 !important;
position: relative;
overflow-x: hidden;
}
body::before {
content: "";
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background:
linear-gradient(rgba(12, 13, 18, 0.75), rgba(12, 13, 18, 0.85)),
linear-gradient(90deg, rgba(139, 233, 253, 0.02) 1px, transparent 1px),
linear-gradient(rgba(139, 233, 253, 0.02) 1px, transparent 1px);
background-size: 100% 100%, 50px 50px, 50px 50px;
pointer-events: none;
z-index: -1;
animation: gridPan 120s linear infinite;
}
/* Add a neon scanline effect */
body::after {
content: "";
position: fixed;
top: 0; left: 0; width: 100%; height: 100%;
background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.25) 50%), linear-gradient(90deg, rgba(255, 0, 0, 0.06), rgba(0, 255, 0, 0.02), rgba(0, 0, 255, 0.06));
background-size: 100% 4px, 6px 100%;
pointer-events: none;
z-index: 9999;
opacity: 0.15;
}
@keyframes gridPan {
from { background-position: 0 0, 0 0, 0 0; }
to { background-position: 0 0, 1000px 1000px, 1000px 1000px; }
}
/* ==========================================
* TYPOGRAPHY & TITLE STYLES
* ========================================== */
.service-group-name, .bookmark-group-name, #widgets-title {
font-family: 'Orbitron', sans-serif !important;
font-weight: 700 !important;
letter-spacing: 0.15em !important;
text-transform: uppercase !important;
text-shadow: 0 0 10px rgba(189, 147, 249, 0.6) !important;
color: var(--dracula-purple) !important;
}
.service-name {
font-family: 'Rajdhani', sans-serif !important;
font-weight: 700 !important;
font-size: 1.15rem !important;
letter-spacing: 0.03em !important;
color: var(--dracula-text) !important;
}
.service-description {
font-family: 'Poppins', sans-serif !important;
font-size: 0.8rem !important;
color: #a9b1d6 !important;
}
/* ==========================================
* GLASSMORPHISM CARDS & ANIMATIONS
* ========================================== */
.service-card, li.bookmark > a, #information-widgets, #dracula-calendar {
background: var(--card-color) !important;
backdrop-filter: blur(14px) !important;
-webkit-backdrop-filter: blur(14px) !important;
border: 1px solid rgba(255, 255, 255, 0.06) !important;
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4) !important;
transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1) !important;
position: relative;
overflow: hidden;
}
/* Hover base styling */
.service-card:hover, li.bookmark > a:hover {
transform: translateY(-4px) scale(1.02);
background: var(--card-color-hover) !important;
border-color: rgba(139, 233, 253, 0.4) !important;
box-shadow: 0 12px 40px 0 rgba(0, 0, 0, 0.6), 0 0 15px rgba(139, 233, 253, 0.2) !important;
}
/* Subtle corner tech border lines for hover */
.service-card::after {
content: "";
position: absolute;
top: 0; left: 0; width: 4px; height: 4px;
border-top: 2px solid transparent;
border-left: 2px solid transparent;
transition: all 0.3s;
}
.service-card:hover::after {
border-top-color: var(--dracula-cyan);
border-left-color: var(--dracula-cyan);
width: 15px; height: 15px;
}
/* Service Images */
.service img {
border-radius: 20%;
border: 1px solid rgba(255, 255, 255, 0.1);
padding: 2px;
background: rgba(0, 0, 0, 0.2);
transition: all 0.4s;
}
.service-card:hover img {
transform: rotate(5deg) scale(1.05);
border-color: rgba(139, 233, 253, 0.4);
}
/* ==========================================
* PULSING STATUS / ONLINE DOTS
* ========================================== */
.bg-green-500, .bg-emerald-500, .text-green-500, .text-emerald-500 {
position: relative;
background-color: var(--dracula-green) !important;
box-shadow: 0 0 10px var(--dracula-green) !important;
}
/* Create glowing animation rings */
.bg-green-500::after, .bg-emerald-500::after {
content: "";
position: absolute;
top: -2px; left: -2px; right: -2px; bottom: -2px;
border-radius: 50%;
border: 1.5px solid var(--dracula-green);
animation: statusPulse 2s infinite ease-out;
opacity: 0;
pointer-events: none;
}
@keyframes statusPulse {
0% { transform: scale(1); opacity: 0.8; }
100% { transform: scale(2.4); opacity: 0; }
}
.bg-red-500, .text-red-500 {
position: relative;
background-color: var(--dracula-red) !important;
box-shadow: 0 0 10px var(--dracula-red) !important;
}
.bg-red-500::after {
content: "";
position: absolute;
top: -2px; left: -2px; right: -2px; bottom: -2px;
border-radius: 50%;
border: 1.5px solid var(--dracula-red);
animation: statusPulse 2s infinite ease-out;
opacity: 0;
pointer-events: none;
}
/* ==========================================
* WIDGET & SCROLLBAR CUSTOMS
* ========================================== */
#information-widgets {
border-color: var(--widget-border) !important;
margin-bottom: 2rem;
}
#information-widgets * {
font-family: 'Rajdhani', sans-serif !important;
font-weight: 600;
color: var(--info-widgets) !important;
}
.resource-usage {
background-color: var(--resource-bar-bg) !important;
border: 1px solid rgba(255, 255, 255, 0.05);
border-radius: 4px;
height: 8px !important;
overflow: hidden;
}
.resource-usage > div {
background: linear-gradient(90deg, var(--dracula-cyan), var(--dracula-purple)) !important;
box-shadow: 0 0 8px rgba(139, 233, 253, 0.6);
height: 100%;
}
.service-block {
background: var(--service-block-bg) !important;
border-radius: 6px;
border: 1px solid rgba(255, 255, 255, 0.05) !important;
}
.service-block .uppercase {
color: var(--service-block-text) !important;
font-family: 'Orbitron', sans-serif;
font-size: 0.7rem;
letter-spacing: 0.08em;
}
.service-block .font-thin {
color: var(--dracula-text) !important;
font-family: 'Fira Code', monospace;
}
/* Bookmarks styling */
.bookmark-icon {
background-color: var(--bookmark-icon-bg) !important;
border: 1px solid rgba(189, 147, 249, 0.2);
}
.bookmark-icon > div > div {
background: var(--bookmark-icon) !important;
}
.bookmark-name {
font-family: 'Poppins', sans-serif !important;
font-weight: 500;
}
/* Calendar widget tweaks */
#dracula-calendar .flex.justify-between.flex-wrap span {
color: var(--dracula-purple) !important;
font-family: 'Rajdhani', sans-serif;
font-weight: 700;
}
#footer svg {
color: var(--footer-items) !important;
filter: drop-shadow(0 0 5px rgba(189, 147, 249, 0.5));
}
* {
--scrollbar-thumb: var(--scrollbar-fg);
--scrollbar-track: var(--scrollbar-bg);
}
/* Custom styling for the search input widget */
#search-input, .search-container input {
background: rgba(15, 23, 42, 0.6) !important;
border: 1px solid rgba(56, 189, 248, 0.3) !important;
color: #e2e8f0 !important;
font-family: 'Courier New', Courier, monospace !important;
border-radius: 8px !important;
backdrop-filter: blur(8px) !important;
}
#search-input:focus, .search-container input:focus {
border-color: rgba(56, 189, 248, 0.8) !important;
box-shadow: 0 0 15px rgba(56, 189, 248, 0.4) !important;
outline: none !important;
}
/* ==========================================
* CUSTOM COLOR INTEGRATION BY ID
* ========================================== */
/* Setup distinct neon glow values on hover for individual service IDs */
#blue:hover .service-card { border-color: #6272a4 !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(98, 114, 164, 0.45) !important; }
#yellow:hover .service-card { border-color: #f1fa8c !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(241, 250, 140, 0.45) !important; }
#red:hover .service-card { border-color: #ff5555 !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(255, 85, 85, 0.45) !important; }
#cyan:hover .service-card { border-color: #8be9fd !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(139, 233, 253, 0.45) !important; }
#purple:hover .service-card { border-color: #bd93f9 !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(189, 147, 249, 0.45) !important; }
#white:hover .service-card { border-color: #f8f8f2 !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(248, 248, 242, 0.45) !important; }
#gold:hover .service-card { border-color: #ffd700 !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(255, 215, 0, 0.45) !important; }
#green:hover .service-card { border-color: #50fa7b !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(80, 250, 123, 0.45) !important; }
#lime:hover .service-card { border-color: #a3e635 !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(163, 230, 53, 0.45) !important; }
#cobalt:hover .service-card { border-color: #3b82f6 !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(59, 130, 246, 0.45) !important; }
#gray:hover .service-card { border-color: #9ca3af !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(156, 163, 175, 0.45) !important; }
#crimson:hover .service-card { border-color: #dc143c !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(220, 20, 60, 0.45) !important; }
#lavender:hover .service-card { border-color: #e6e6fa !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(230, 230, 250, 0.45) !important; }
#teal:hover .service-card { border-color: #008080 !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(0, 128, 128, 0.45) !important; }
#violet:hover .service-card { border-color: #7c3aed !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(124, 58, 237, 0.45) !important; }
#aqua:hover .service-card { border-color: #00ffff !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(0, 255, 255, 0.45) !important; }
#navy:hover .service-card { border-color: #000080 !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(0, 0, 128, 0.45) !important; }
#beige:hover .service-card { border-color: #f5f5dc !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(245, 245, 220, 0.45) !important; }
#slate:hover .service-card { border-color: #708090 !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(112, 128, 144, 0.45) !important; }
#burgundy:hover .service-card { border-color: #800020 !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(128, 0, 32, 0.45) !important; }
#emerald:hover .service-card { border-color: #50c878 !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(80, 200, 120, 0.45) !important; }
#salmon:hover .service-card { border-color: #fa8072 !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(250, 128, 114, 0.45) !important; }
#jade:hover .service-card { border-color: #00a86b !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(0, 168, 107, 0.45) !important; }
#indigo:hover .service-card { border-color: #4b0082 !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(75, 0, 130, 0.45) !important; }
#charcoal:hover .service-card { border-color: #36454f !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(54, 69, 79, 0.45) !important; }
#cerulean:hover .service-card { border-color: #007ba7 !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(0, 123, 167, 0.45) !important; }
#rose:hover .service-card { border-color: #ff007f !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(255, 0, 127, 0.45) !important; }
#coral:hover .service-card { border-color: #ff7f50 !important; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(255, 127, 80, 0.45) !important; }
/* Keep active indicators styled cleanly inside the cards */
#blue:hover .service-card::after { border-top-color: #6272a4; border-left-color: #6272a4; }
#yellow:hover .service-card::after { border-top-color: #f1fa8c; border-left-color: #f1fa8c; }
#red:hover .service-card::after { border-top-color: #ff5555; border-left-color: #ff5555; }
#cyan:hover .service-card::after { border-top-color: #8be9fd; border-left-color: #8be9fd; }
#purple:hover .service-card::after { border-top-color: #bd93f9; border-left-color: #bd93f9; }
#white:hover .service-card::after { border-top-color: #f8f8f2; border-left-color: #f8f8f2; }
#gold:hover .service-card::after { border-top-color: #ffd700; border-left-color: #ffd700; }
#green:hover .service-card::after { border-top-color: #50fa7b; border-left-color: #50fa7b; }
#lime:hover .service-card::after { border-top-color: #a3e635; border-left-color: #a3e635; }
#cobalt:hover .service-card::after { border-top-color: #3b82f6; border-left-color: #3b82f6; }
#gray:hover .service-card::after { border-top-color: #9ca3af; border-left-color: #9ca3af; }
#crimson:hover .service-card::after { border-top-color: #dc143c; border-left-color: #dc143c; }
#lavender:hover .service-card::after { border-top-color: #e6e6fa; border-left-color: #e6e6fa; }
#teal:hover .service-card::after { border-top-color: #008080; border-left-color: #008080; }
#violet:hover .service-card::after { border-top-color: #7c3aed; border-left-color: #7c3aed; }
#aqua:hover .service-card::after { border-top-color: #00ffff; border-left-color: #00ffff; }
#navy:hover .service-card::after { border-top-color: #000080; border-left-color: #000080; }
#beige:hover .service-card::after { border-top-color: #f5f5dc; border-left-color: #f5f5dc; }
#slate:hover .service-card::after { border-top-color: #708090; border-left-color: #708090; }
#burgundy:hover .service-card::after { border-top-color: #800020; border-left-color: #800020; }
#emerald:hover .service-card::after { border-top-color: #50c878; border-left-color: #50c878; }
#salmon:hover .service-card::after { border-top-color: #fa8072; border-left-color: #fa8072; }
#jade:hover .service-card::after { border-top-color: #00a86b; border-left-color: #00a86b; }
#indigo:hover .service-card::after { border-top-color: #4b0082; border-left-color: #4b0082; }
#charcoal:hover .service-card::after { border-top-color: #36454f; border-left-color: #36454f; }
#cerulean:hover .service-card::after { border-top-color: #007ba7; border-left-color: #007ba7; }
#rose:hover .service-card::after { border-top-color: #ff007f; border-left-color: #ff007f; }
#coral:hover .service-card::after { border-top-color: #ff7f50; border-left-color: #ff7f50; }
Binary file not shown.
+10
View File
@@ -0,0 +1,10 @@
---
# For configuration options and examples, please see:
# https://gethomepage.dev/configs/docker/
# my-docker:
# host: 127.0.0.1
# port: 2375
# my-docker:
# socket: /var/run/docker.sock
+2
View File
@@ -0,0 +1,2 @@
---
# sample kubernetes config
View File
+5
View File
@@ -0,0 +1,5 @@
---
# pve:
# url: https://proxmox.host.or.ip:8006
# token: username@pam!Token ID
# secret: secret
+392
View File
@@ -0,0 +1,392 @@
---
######################################### HOME TAB SERVICES ######################################################################
- Infrastructure:
- Proxmox 1: # Main Virt Server
id: blue
tab: Home
href: https://192.168.2.1:8006
icon: proxmox.png
description: Virtual Server 1
widget:
type: proxmox
url: https://192.168.2.1:8006
username: api@pam!homepage
password: faca2bd5-e6df-4192-85ce-928fccde4623
node: pve
fields: ["vms", "lxc", "resources.cpu", "resources.mem"]
- Proxmox 2:
id: yellow
tab: Home
href: https://192.168.2.2:8006
icon: proxmox.png
description: Virtual Server 2
widget:
type: proxmox
url: https://192.168.2.2:8006
username: api@pam!homepage
password: 1b2fa246-a994-4f93-ab4d-1c91a4aea614
node: pve
fields: ["vms", "lxc", "resources.cpu", "resources.mem"]
- Authentik:
id: red
tab: Home
href: https://auth.mikemcfetridge.com
icon: authentik.png
description: Authentik SSO
widget:
type: authentik
url: https://192.168.2.6:9543
key: NW5ldUK8qDRY91ny67dE6ckWCMXThF9nwj6EZw7pKbS5FzXx5wouAo4sC19n
version: 2
- Dockhand:
id: cyan
tab: Home
href: http://192.168.2.6:3200
icon: dockhand.png
description: Dockhand
widget:
type: dockhand
url: http://192.168.2.6:3200
username: mmcfetridge
password: "!Sucyetat123"
fields: ["running", "total", "pending_updates", "paused"]
- Mailcow:
id: cyan
tab: Home
href: https://216.144.227.142/admin
icon: mailcow.png
description: mailcow
widget:
type: mailcow
url: https://mail.mmcfetridge.net
key: 2C3DAF-9DA97F-22FF12-851295-2A7E37
############################################## APPS TAB Services ###########################################################
- Applications:
- Immich:
id: white
tab: Home
href: https://immich.mikemcfetridge.com
icon: immich.png
description: Photos Server
widget:
type: immich
url: http://192.168.2.6:2283
key: "MLbcal27A67J6FZV1PIb3AdMsRf8xZC1uruOLB7js"
fields: ["users", "photos", "storage"]
version: 2
- MySpeed:
id: lime
tab: Home
icon: myspeed.png
href: http://192.168.2.6:5216
widget:
type: myspeed
url: http://192.168.2.6:5216
password: "!Sucyetat123" # only required if password is set
- mealie:
id: cobalt
tab: Home
icon: mealie.png
href: http://192.168.2.7:9200/
widget:
type: mealie
url: http://192.168.2.7:9200
key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb25nX3Rva2VuIjp0cnVlLCJpZCI6ImVhNDAxMTIzLTg1ZGItNDZhMi04Y2M1LTEzYmVmNGM2ZjgxMCIsIm5hbWUiOiJIb21lcGFnZSIsImludGVncmF0aW9uX2lkIjoiZ2VuZXJpYyIsImV4cCI6MTk0MDE1NTE4NX0.NgpovwuA-FGjt6f6q5kInmmIUadjXRCEpoowfRnYhHE
version: 2 # only required if version > 1, defaults to 1
- Nextcloud:
id: gold
tab: Home
href: https://next.mcfetridge.us
icon: nextcloud.png
description: Nextcloud Server
widget:
type: nextcloud
url: https://next.mcfetridge.us
username: mmcfetridge
password: "!Sucyetat123"
- MyGitea:
id: navy
tab: Home
icon: gitea.png
href: https://mygitea.mikemcfetridge.com/
widget:
type: gitea
url: https://mygitea.mikemcfetridge.com/
key: 1ba8eac5698e4e1ea9461b814635e5220b707767
- Gitea:
id: navy
tab: Home
icon: gitea.png
href: https://gitea.mikemcfetridge.com/
widget:
type: gitea
url: https://gitea.mikemcfetridge.com/
key: 10db6351209bc8cd900f6b03064e5a4f3f971eb3
- BookStack:
id: slate
tab: Home
icon: bookstack.png
href: https://book.mikemcfetridge.com/
############################################## MEDIA TAB Services ###########################################################
- Media downloader:
- Calendar:
id: gray
tab: Media
name: Calendar
widget:
type: calendar
view: agenda
maxEvents: 6
firstDayInWeek: sunday
integrations:
- type: sonarr
service_group: Media downloader
service_name: Sonarr
- type: radarr
service_group: Media downloader
service_name: Radarr
- Gluetun:
id: jade
tab: System
href: http://192.168.2.8:8000
icon: gluetun.png
description: Media VPN Server
widget:
type: gluetun
url: http://192.168.2.8:8000
fields: ["public_ip", "region", "country"]
version: 2 # optional, default is 1
- Sonarr:
id: crimson
tab: Media
href: http://192.168.2.8:8989
icon: sonarr.png
description: TV Show Service
widget:
type: sonarr
url: http://192.168.2.8:8989
key: b4227fd07fd046f094d620b88d92e494
fields: ["wanted", "queued", "series"]
- Radarr:
id: lavender
tab: Media
href: http://192.168.2.8:7878
icon: radarr.png
description: Movie Service
widget:
type: radarr
url: http://192.168.2.8:7878
key: 9b0e1202f7b94907ba92a1ea23304fa4
fields: ["wanted", "missing", "queued", "movies"]
- Qbittorrent:
id: teal
tab: Media
href: http://192.168.2.8:8080
icon: qbittorrent.png
description: Download Client
widget:
type: qbittorrent
url: http://192.168.2.8:8080
username: admin
password: "!Sucyetat123"
- Media Apps:
- Jellyfin:
id: violet
tab: Media
href: http://192.168.2.8:8096
icon: jellyfin.png
description: Movies & TV Shows
widget:
type: jellyfin
url: http://192.168.2.8:8096
key: ffe8e2b31fd24464ac779121e920ac25
enableBlocks: true
enableNowPlaying: true
- Jellyseerr:
id: aqua
tab: Media
href: http://192.168.2.8:5055
icon: jellyseerr.png
description: Movie/show Database
widget:
type: jellyseerr
url: http://192.168.2.8:5055
key: MTc4MzM0NDc0OTI1OWY1YzJkYWJkLTA0OWEtNDY0NS05ZTMwLTI3NjFkZjYxNjdhZQ==
fields: ["pending", "approved", "available"]
- Navidrome:
id: navy
tab: Media
icon: navidrome.png
href: http://192.168.2.8:4533
widget:
type: navidrome
url: http://192.168.2.8:4533
user: mmcfetridge
token: 05dee16046666bb05d98291b9c6e39d3
salt: 50c05a
- AudioBookShelf:
id: beige
tab: Media
href: http://192.168.2.8:13378
icon: audiobookshelf.png
description: Index Server
widget:
type: audiobookshelf
url: http://192.168.2.8:13378
key: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXlJZCI6IjU1MzViZDFiLTI3NGUtNGNjOC1iMWZkLTNiZWFiNjg0NDQ1YiIsIm5hbWUiOiJob21lcGFnZSIsInR5cGUiOiJhcGkiLCJpYXQiOjE3ODM0NjE1NjJ9.BYvicD24tA3lEx_ktwmf6Igme6dpLj1SUrc0Y9ISBMs"
fields: ["podcasts", "books"]
##################################### Network & System TAB Services ##############################################################
- Network:
- Pi-hole:
id: slate
tab: Network
href: http://192.168.2.5/admin/login
icon: pi-hole.png
widget:
type: pihole
url: http://192.168.2.5
version: 6
key: "!Sucyetat123"
fields: ["queries", "blocked", "blocked_percent", "gravity"]
- Nginx Proxy Manager:
id: emerald
tab: Network
href: http://192.168.2.12:81
icon: nginx-proxy-manager.png
description: Nginx Proxy Manager
widget:
type: npm
url: http://192.168.2.12:81
username: mmcfetridg@aol.com
password: "!Sucyetat123"
fields: ["enabled", "disabled", "total"]
- Pangolin:
id: salmon
tab: Network
icon: pangolin.png
href: https://app.pangolin.net
description: External network
widget:
type: pangolin
url: https://api.pangolin.net
key: "w3f8ong2hz7a3da.dappsg2veyo36my5ibsmrmnzd2c2626lyrok7inn"
org: org_lsxd0ocafwikxgs
fields: ["sites", "resources", "targets"]
######################################## System TAB Services ######################################################################
- Systems:
- Public IP:
icon: mdi-web
href: https://whatismyipaddress.com/
widget:
type: customapi
url: https://api.ipify.org?format=json
refreshInterval: 3600000 # Refreshes once an hour (in milliseconds)
method: GET
mappings:
- field: ip
label: WAN IP
format: text
- Technitium:
id: burgundy
tab: Network
href: http://192.168.2.3:5380
icon: technitium.png
description: Technitium DNS Server
widget:
type: technitium
url: http://192.168.2.3:5380
key: 03348d06cd472fbd091d8232b1c13321ff70a8628dad7b0c23dd4512a18fb34b
range: LastDay
fields: ["totalQueries", "totalAuthoritative", "totalCached", "totalServerFailure"]
- PatchMon:
id: cyan
tab: Network
href: https://patch.mikemcfetridge.com
description: PatchMon Statistics
icon: https://patch.mikemcfetridge.com/assets/logo_square_default.svg
widget:
type: customapi
url: https://patch.mikemcfetridge.com/api/v1/gethomepage/stats
headers:
Authorization: Basic cGF0Y2htb25fYWVfYzJlZGUxODcyNzI4NDU0MTM1ZWI5ZWE3ZThkYmY1MTY6MzdlMDdlNjM4YjFiMjUzYjIyYWFjMWQ3ODA0ZTdhODExZTM0ZTMzNGM0MDczMjI5YWQwN2EwYjIzODU2NDhhOQ==
mappings:
- field: total_hosts
label: Total Hosts
- field: hosts_needing_updates
label: Needs Updates
- field: security_updates
label: Security Updates
############################################## Bookmark TAB Services #############################################################
- Bookmarks:
- Github:
id: indigo
tab: Bookmarks
abbr: GH
href: https://github.com
icon: github-light.png
description: GitHub
- Linkwarden:
id: charcoal
tab: Bookmarks
href: https://lw.mikemcfetridge.com
icon: linkwarden.png
description: Web Bookmarker
widget:
type: linkwarden
url: http://192.168.2.10:3000
key: "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..ZLJgig_ol-n3i1tv.vhWCnMSHVd81bdidL85-imXKpxGC0U3mHlvmkQyIJqJvcFRRJVBAasw9C0cmfSXVPq08HT-B-3zUAmftnPRymPHMJCkfo8pv_XBbEPneIFH-n59_dg26.qcXSK2REP3M_Vdgp0aOqcA"
fields: ["links", "collections"]
- Semaphore:
id: cerulean
tab: Bookmarks
icon: semaphore.png
href: http://192.168.2.7:3020
description: CI/CD Automation
- Wg-Easy:
id: rose
tab: Bookmarks
icon: wireguard.png
href: http://192.168.2.7:10086
description: Wireguard VPN
- YouTube:
id: coral
tab: Bookmarks
icon: youtube.png
href: https://youtube.com/
description: Video Platform
#
+55
View File
@@ -0,0 +1,55 @@
---
title: Miker's Homepage
description: Here is my awesome homepage
background:
image: https://backiee.com/static/wallpapers/1000x563/412861.webp
blur: sm
saturate: 50
brightness: 75
opacity: 75
theme: dark
color: slate
layout:
Infrastructure:
icon: mdi-folder-network
tab: Home
header: true
columns: 3
Applications:
icon: mdi-application
tab: Home
header: true
columns: 3
Media downloader:
icon: mdi-multimedia
tab: Media
header: true
columns: 3
Media Apps:
icon: mdi-movie
tab: Media
header: true
columns: 3
Network:
tab: System
icon: mdi-switch
header: true
columns: 3
Systems:
tab: System
icon: mdi-television
header: true
columns: 3
Bookmarks:
tab: Bookmarks
icon: mdi-baby
style: row
columns: 4
fiveColumns: true
useEqualHeights: true
showStats: true
+42
View File
@@ -0,0 +1,42 @@
# Homepage Widgets Configuration
# Organized by System, Environment, and Search
- logo:
icon: wireguard.svg # optional
- resources:
cpu: true
memory: true
disk: /
cputemp: true
tempmin: 0
tempmax: 100
uptime: true
units: imperial
refresh: 3000
diskUnits: bytes
network: true
- openmeteo:
label: Bealeton
latitude: 38.5718
longitude: -77.7639
timezone: America/New_York
units: imperial
cache: 5
format:
maximumFractionDigits: 1
- datetime:
text_size: sm
format:
dateStyle: short
timeStyle: short
hour12: true
timeZone: 'America/New_York'
# /config/widgets.yaml
- search:
provider: google # google, duckduckgo, bing, baidu, brave or custom
focus: true # Optional, will set focus to the search bar on page load
showSearchSuggestions: true # Optional, will show search suggestions. Defaults to false
target: _blank # One of _self, _blank, _parent or _top
+30
View File
@@ -0,0 +1,30 @@
services:
homepage:
image: ghcr.io/gethomepage/homepage:latest
container_name: homepage
environment:
HOMEPAGE_ALLOWED_HOSTS: "*" # required, may need port.
PUID: 1000
PGID: 1000
DOCKER_HOST: tcp://socket-proxy:2375
ports:
- 3100:3000
volumes:
- /opt/Docker-Deployments/Homepage/config:/app/config # Make sure your local config directory exists
- /opt/Docker-Deployments/Homepage/images:/app/public/images
- /var/run/docker.sock:/var/run/docker.sock:ro # optional, for docker integrations
networks:
- external
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000"]
interval: 10s
retries: 3
timeout: 10s
start_period: 30s
networks:
external:
external: true # Tells Compose not to create this network
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

+58
View File
@@ -0,0 +1,58 @@
services:
db:
image: 'jc21/mariadb-aria:latest'
container_name: npm-db
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=rhDGjilZm6XEMJ
- MYSQL_DATABASE=npm
- MYSQL_USER=npm
- MYSQL_PASSWORD=rhDGjilZm6XEMJ
- MARIADB_AUTO_UPGRADE=1
volumes:
- /opt/Docker-Deployments/NginxProxyManager/data/mysql:/var/lib/mysql
networks:
- internal
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u$MYSQL_USER", "-p$MYSQL_PASSWORD"]
interval: 20s
timeout: 5s
retries: 5
start_period: 30s
nginx-proxy-manager:
image: 'jc21/nginx-proxy-manager:latest'
container_name: nginx-proxy-manager
restart: unless-stopped
environment:
- TZ=America/New_York
- DB_MYSQL_HOST=db
- DB_MYSQL_PORT=3306
- DB_MYSQL_USER=npm
- DB_MYSQL_PASSWORD=rhDGjilZm6XEMJ
- DB_MYSQL_NAME=npm
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- /opt/Docker-Deployments/NginxProxyManager/data/npm:/data
- /opt/Docker-Deployments/NginxProxyManager/data/letsencrypt:/etc/letsencrypt
- /opt/Docker-Deployments/NginxProxyManager/logs:/data/logs
depends_on:
- db
networks:
- internal
- external
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:81/api/status"]
interval: 20s
timeout: 5s
retries: 5
start_period: 40s
networks:
internal:
external: true
external:
external: true
+1 -1
View File
@@ -1,2 +1,2 @@
# Docker-02 # Docker-Deployments
+17
View File
@@ -0,0 +1,17 @@
services:
sencho:
image: saelix/sencho:latest
container_name: sencho
restart: unless-stopped
ports:
- "1852:1852"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /opt/Docker-Deployments/Sencho/data:/app/data
# Change this line so the container path matches the host path:
- /opt/Docker-Deployments:/opt/Docker-Deployments
environment:
- COMPOSE_DIR=/opt/Docker-Deployments
- DATA_DIR=/app/data
+17
View File
@@ -0,0 +1,17 @@
TZ=America/New_York
WATCHTOWER_CLEANUP=true
WATCHTOWER_INCLUDE_RESTARTING=true
WATCHTOWER_ROLLING_RESTARTING=true
WATCHTOWER_SCHEDULE=0 0 4 * * *
WATCHTOWER_INCLUDE_STOPPED=true
WATCHTOWER_NOTIFICATIONS=email
WATCHTOWER_NOTIFICATIONS_HOSTNAME=Docker-Deply # Add Server Name or IP Address
WATCHTOWER_NOTIFICATION_EMAIL_FROM=miker@mmcfetridge.net
WATCHTOWER_NOTIFICATION_EMAIL_TO=miker@mmcfetridge.net
WATCHTOWER_NOTIFICATION_EMAIL_SERVER=mail.mmcfetridge.net
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=465
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=miker@mmcfetridge.net
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=!Sucyetat123
WATCHTOWER_NOTIFICATION_EMAIL_DELAY=2
PUID=1000
PGID=1000
+36
View File
@@ -0,0 +1,36 @@
services:
watchtower:
image: containrrr/watchtower
container_name: watchtower
restart: unless-stopped
env_file: .env
environment:
- DOCKER_API_VERSION=1.44
- TZ=America/New_York
- PUID:=1000 # Reference PUID from .env
- PGID=1000 # Reference PGID from .env
- WATCHTOWER_CLEANUP=true
- WATCHTOWER_INCLUDE_RESTARTING=true
- WATCHTOWER_ROLLING_RESTARTING=true
- WATCHTOWER_SCHEDULE=0 0 4 * * *
- WATCHTOWER_INCLUDE_STOPPED=true
- WATCHTOWER_NOTIFICATIONS=email
- WATCHTOWER_NOTIFICATIONS_HOSTNAME=Docker-Deployment # Add Server Name or IP Address
- WATCHTOWER_NOTIFICATION_EMAIL_FROM=miker@mmcfetridge.net
- WATCHTOWER_NOTIFICATION_EMAIL_TO=miker@mmcfetridge.net
- WATCHTOWER_NOTIFICATION_EMAIL_SERVER=mail.mmcfetridge.net
- WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=465
- WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=miker@mmcfetridge.net
- WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=!Sucyetat123
- WATCHTOWER_NOTIFICATION_EMAIL_DELAY=2
security_opt:
- no-new-privileges:true
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
networks:
- external
networks:
external:
external: true # Tells Compose not to create this network
+48
View File
@@ -0,0 +1,48 @@
name: Validate and Deploy Homelab
on:
push:
branches: [ "main" ]
jobs:
test-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository Code
uses: actions/checkout@v4
- name: Verify Compose File Validity
env:
DB_ROOT_PASSWORD: ${{ secrets.MYSQL_ROOT_PASSWORD }}
DB_PASSWORD: ${{ secrets.MYSQL_PASSWORD }}
run: docker compose config
# --- DEPLOYMENT PHASE ---
- name: Set up SSH Private Key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
# Scan the host key to prevent SSH hanging on a manual confirmation prompt
ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts
- name: Create Remote Docker Context
run: |
# Define a remote endpoint pointing to your live server over SSH
docker context create homelab-target \
--docker "host=ssh://${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}"
- name: Deploy Containers to Live Server
env:
# Pass your production secrets to the live deployment step
DB_ROOT_PASSWORD: ${{ secrets.MYSQL_ROOT_PASSWORD }}
DB_PASSWORD: ${{ secrets.MYSQL_PASSWORD }}
run: |
echo "Switching Docker context to live server..."
docker context use homelab-target
echo "Pulling latest images and starting services remotely..."
# The --project-directory . flag ensures it reads the docker-compose file fetched by Git
docker compose --project-directory . up -d --remove-orphans
+54
View File
@@ -0,0 +1,54 @@
##### My SearXNG personal settings.
use_default_settings: true
general:
debug: false
instance_name: "McFetridge Private Search" # Changes the name on the homepage and browser tabs
brand:
docs_url: "" # Use empty strings instead of false
issue_url: "" # Hides the links without crashing the parser
custom:
links:
"Dockhand": "http://192.168.0.8:3200"
"My Dashboard": "http://192.168.0.9:3100"
server:
port: 8080
bind_address: "0.0.0.0"
secret_key: "ee072bb45348da92be54b5224bee58b982a4279d3531f056b727c4dd3397bc3e"
image_proxy: true # Proxies images through your server to protect your IP
search:
default_lang: "en-US" # Force results to a specific region
safe_search: 1 # 0 = None, 1 = Moderate, 2 = Strict
autocomplete: "duckduckgo" # Upstream source for search suggestions
formats:
- html
- json # Adds API capabilities for external script ingestion
ui:
theme: simple
results_on_new_tab: true # Keeps your engine open when browsing links
default_locale: "en"
default_interface: "general" # The default tab ("general", "images", "videos", "news", "it")
# This is the standard way to cleanly enable/disable specific engines in SearXNG
engines:
- name: google
disabled: false
- name: duckduckgo
disabled: false
- name: wikipedia
disabled: false
- name: wikidata
disabled: true
- name: bing
disabled: false
- name: brave
disabled: false
+21
View File
@@ -0,0 +1,21 @@
services:
searxng:
container_name: searxng
image: docker.io/searxng/searxng:latest
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- /opt/Docker-Deployments/searxng:/etc/searxng:rw
- /opt/Docker-Deployments/searxng_cache:/var/cache/searxng:rw
environment:
- SEARXNG_BASE_URL=https://search.mikemcfetridge.com
- UWSGI_WORKERS=${SEARXNG_UWSGI_WORKERS:-4}
- UWSGI_THREADS=${SEARXNG_UWSGI_THREADS:-4}
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:8080" ]
interval: 10s
retries: 3
timeout: 10s
start_period: 30s
+39
View File
@@ -0,0 +1,39 @@
##### My SearXNG personal settings.
use_default_settings: true
general:
debug: false
instance_name: "McFetridge Private Search" # Changes the name on the homepage and browser tabs
brand:
docs_url: "" # Use empty strings instead of false
issue_url: "" # Hides the links without crashing the parser
custom:
links:
"Dockhand": "http://192.168.0.8:3200"
"My Dashboard": "http://192.168.0.9:3100"
server:
port: 8080
bind_address: "0.0.0.0"
secret_key: "ee072bb45348da92be54b5224bee58b982a4279d3531f056b727c4dd3397bc3e"
image_proxy: true # Proxies images through your server to protect your IP
search:
default_lang: "en-US" # Force results to a specific region
safe_search: 1 # 0 = None, 1 = Moderate, 2 = Strict
autocomplete: "duckduckgo" # Upstream source for search suggestions
formats:
- html
- json # Adds API capabilities for external script ingestion
ui:
theme: simple
results_on_new_tab: true # Keeps your engine open when browsing links
default_locale: "en"
default_interface: "general" # The default tab ("general", "images", "videos", "news", "it")
# This is the standard way to cleanly enable/disable specific engines in SearXNG
engines:
- name: wikidata
disabled: true
+22
View File
@@ -0,0 +1,22 @@
services:
wgdashboard:
image: ghcr.io/wgdashboard/wgdashboard:latest
container_name: wgdashboard
restart: unless-stopped
ports:
- "10086:10086/tcp"
- "51820:51820/udp"
volumes:
- /opt/Docker-Deployments/wireguard/conf:/etc/wireguard
- /opt/Docker-Deployments/wireguard/data:/data
cap_add:
- NET_ADMIN
networks:
- external
environment:
- GUNICORN_WORKERS=1 # Keeps RAM usage low by only running 1 worker process
- GUNICORN_TIMEOUT=120 # Raises timeout to 2 minutes so long tasks don't trigger a restart
- GUNICORN_WORKER_CLASS=sync # Prevents threading conflicts during background updates
networks:
external:
external: true # Tells Compose not to create this network..