added felhom.eu

This commit is contained in:
2026-01-26 16:47:31 +01:00
parent 7824e7d36c
commit f791b4d0ca
2 changed files with 619 additions and 0 deletions
+21
View File
@@ -1033,3 +1033,24 @@ spec:
- CreateNamespace=true
- ServerSideApply=true
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: felhom
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: homelab
source:
repoURL: https://gitea.dooplex.hu/admin/homelab-manifests.git
targetRevision: main
path: felhom-system
destination:
server: https://kubernetes.default.svc
namespace: felhom-system
syncPolicy:
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
---
+598
View File
@@ -0,0 +1,598 @@
---
# Namespace for felhom.eu website
apiVersion: v1
kind: Namespace
metadata:
name: felhom-system
---
# ConfigMap containing the website HTML
# NOTE: For larger sites, consider using a custom Docker image instead
apiVersion: v1
kind: ConfigMap
metadata:
name: felhom-website
namespace: felhom-system
labels:
app.kubernetes.io/name: felhom
app.kubernetes.io/instance: felhom
data:
index.html: |
<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Felhom.eu - Saját szerver, saját adatok. Professzionális otthoni szerver telepítés és üzemeltetés.">
<title>Felhom.eu - Saját felhőd, saját szabályaid</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<link rel="icon" type="image/png" href="/logo.png">
<style>
:root {
--bg-primary: #0d1117;
--bg-secondary: #161b22;
--bg-card: #1c2128;
--text-primary: #e6edf3;
--text-secondary: #8b949e;
--accent-blue: #0088cc;
--accent-light: #00aaff;
--accent-glow: rgba(0, 136, 204, 0.3);
--border-color: #30363d;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, sans-serif;
background: var(--bg-primary);
color: var(--text-primary);
line-height: 1.6;
min-height: 100vh;
}
body::before {
content: '';
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background-image:
linear-gradient(rgba(0, 136, 204, 0.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(0, 136, 204, 0.03) 1px, transparent 1px);
background-size: 50px 50px;
pointer-events: none;
z-index: -1;
}
.container { max-width: 1100px; margin: 0 auto; padding: 0 24px; }
nav {
position: fixed;
top: 0; left: 0; right: 0;
padding: 20px 0;
background: rgba(13, 17, 23, 0.8);
backdrop-filter: blur(12px);
border-bottom: 1px solid var(--border-color);
z-index: 100;
}
nav .container { display: flex; justify-content: space-between; align-items: center; }
.logo { display: flex; align-items: center; gap: 12px; text-decoration: none; }
.logo img { height: 40px; width: auto; }
.logo-text { font-size: 1.5rem; font-weight: 700; color: var(--accent-light); letter-spacing: -0.02em; }
.nav-links { display: flex; gap: 32px; list-style: none; }
.nav-links a { color: var(--text-secondary); text-decoration: none; font-weight: 500; font-size: 0.95rem; transition: color 0.2s ease; }
.nav-links a:hover { color: var(--accent-light); }
.hero {
min-height: 100vh;
display: flex;
align-items: center;
padding: 120px 0 80px;
}
.hero-content { display: grid; grid-template-columns: 1fr 1fr; gap: 60px; align-items: center; }
.hero-text h1 {
font-size: clamp(2.5rem, 5vw, 3.5rem);
font-weight: 700;
line-height: 1.1;
margin-bottom: 24px;
letter-spacing: -0.03em;
}
.hero-text h1 span {
background: linear-gradient(135deg, var(--accent-light), var(--accent-blue));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.hero-text p { font-size: 1.2rem; color: var(--text-secondary); margin-bottom: 32px; max-width: 500px; }
.hero-visual { display: flex; justify-content: center; align-items: center; }
.hero-visual img {
max-width: 380px;
width: 100%;
height: auto;
filter: drop-shadow(0 0 60px var(--accent-glow));
animation: float 6s ease-in-out infinite;
}
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-15px); }
}
.cta-button {
display: inline-flex;
align-items: center;
gap: 8px;
background: linear-gradient(135deg, var(--accent-blue), var(--accent-light));
color: white;
padding: 16px 32px;
border-radius: 8px;
text-decoration: none;
font-weight: 600;
font-size: 1rem;
transition: transform 0.2s ease, box-shadow 0.2s ease;
box-shadow: 0 4px 20px var(--accent-glow);
}
.cta-button:hover { transform: translateY(-2px); box-shadow: 0 8px 30px var(--accent-glow); }
.problem { padding: 100px 0; background: var(--bg-secondary); }
.section-header { text-align: center; margin-bottom: 60px; }
.section-header h2 { font-size: 2.2rem; font-weight: 700; margin-bottom: 16px; letter-spacing: -0.02em; }
.section-header p { color: var(--text-secondary); font-size: 1.1rem; max-width: 600px; margin: 0 auto; }
.problem-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 24px; }
.problem-card {
background: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 32px;
transition: border-color 0.3s ease, transform 0.3s ease;
}
.problem-card:hover { border-color: var(--accent-blue); transform: translateY(-4px); }
.problem-icon { font-size: 2.5rem; margin-bottom: 20px; }
.problem-card h3 { font-size: 1.2rem; margin-bottom: 12px; color: var(--text-primary); }
.problem-card p { color: var(--text-secondary); font-size: 0.95rem; }
.services { padding: 100px 0; }
.service-list { display: grid; gap: 20px; }
.service-item {
display: grid;
grid-template-columns: auto 1fr auto;
gap: 24px;
align-items: center;
background: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 28px 32px;
transition: border-color 0.3s ease;
}
.service-item:hover { border-color: var(--accent-blue); }
.service-number {
font-family: 'JetBrains Mono', monospace;
font-size: 0.9rem;
color: var(--accent-light);
background: rgba(0, 136, 204, 0.15);
padding: 8px 14px;
border-radius: 6px;
font-weight: 500;
}
.service-content h3 { font-size: 1.15rem; margin-bottom: 6px; }
.service-content p { color: var(--text-secondary); font-size: 0.95rem; }
.service-icon { font-size: 1.8rem; }
.why { padding: 100px 0; background: var(--bg-secondary); }
.why-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 40px; }
.why-card {
padding: 40px;
background: linear-gradient(135deg, var(--bg-card), var(--bg-primary));
border: 1px solid var(--border-color);
border-radius: 16px;
position: relative;
overflow: hidden;
}
.why-card::before {
content: '';
position: absolute;
top: 0; left: 0;
width: 4px; height: 100%;
background: linear-gradient(180deg, var(--accent-light), var(--accent-blue));
}
.why-card h3 { font-size: 1.3rem; margin-bottom: 16px; display: flex; align-items: center; gap: 12px; }
.why-card p { color: var(--text-secondary); font-size: 1rem; line-height: 1.7; }
.contact { padding: 100px 0; text-align: center; }
.contact-box {
max-width: 600px;
margin: 0 auto;
background: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: 16px;
padding: 48px;
}
.contact-box h2 { font-size: 2rem; margin-bottom: 16px; }
.contact-box p { color: var(--text-secondary); margin-bottom: 32px; }
.contact-methods { display: flex; flex-direction: column; gap: 16px; }
.contact-link {
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
padding: 16px 24px;
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 8px;
color: var(--text-primary);
text-decoration: none;
font-weight: 500;
transition: border-color 0.2s ease, background 0.2s ease;
}
.contact-link:hover { border-color: var(--accent-blue); background: rgba(0, 136, 204, 0.1); }
footer { padding: 40px 0; border-top: 1px solid var(--border-color); text-align: center; }
footer p { color: var(--text-secondary); font-size: 0.9rem; }
.beta-badge {
display: inline-block;
background: rgba(0, 136, 204, 0.2);
color: var(--accent-light);
padding: 6px 12px;
border-radius: 20px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: 16px;
}
@media (max-width: 900px) {
.hero-content { grid-template-columns: 1fr; text-align: center; }
.hero-text p { margin-left: auto; margin-right: auto; }
.hero-visual { order: -1; }
.hero-visual img { max-width: 280px; }
.why-grid { grid-template-columns: 1fr; }
.service-item { grid-template-columns: 1fr; text-align: center; gap: 16px; }
.nav-links { display: none; }
}
@media (max-width: 600px) {
.hero { padding: 100px 0 60px; }
.section-header h2 { font-size: 1.8rem; }
.contact-box { padding: 32px 24px; }
}
</style>
</head>
<body>
<nav>
<div class="container">
<a href="#" class="logo">
<img src="/logo.png" alt="Felhom.eu logo">
<span class="logo-text">felhom.eu</span>
</a>
<ul class="nav-links">
<li><a href="#szolgaltatasok">Szolgáltatások</a></li>
<li><a href="#miert">Miért érdemes?</a></li>
<li><a href="#kapcsolat">Kapcsolat</a></li>
</ul>
</div>
</nav>
<section class="hero">
<div class="container">
<div class="hero-content">
<div class="hero-text">
<span class="beta-badge">🚀 Hamarosan indul</span>
<h1>Saját felhőd,<br><span>saját szabályaid</span></h1>
<p>Professzionális otthoni szerver telepítés és üzemeltetés. Te irányítasz, mi segítünk.</p>
<a href="#kapcsolat" class="cta-button">Érdekel →</a>
</div>
<div class="hero-visual">
<img src="/logo.png" alt="Felhom.eu - Otthoni szerver szolgáltatás">
</div>
</div>
</div>
</section>
<section class="problem">
<div class="container">
<div class="section-header">
<h2>Miért ne a felhőszolgáltatók?</h2>
<p>A nagy techcégek kényelmes megoldásokat kínálnak, de van néhány hátrány...</p>
</div>
<div class="problem-grid">
<div class="problem-card">
<div class="problem-icon">💸</div>
<h3>Folyamatos költségek</h3>
<p>Havonta fizetsz a tárhelyért, a prémium funkciókért, és az árak csak nőnek idővel.</p>
</div>
<div class="problem-card">
<div class="problem-icon">👁️</div>
<h3>Adataid másé</h3>
<p>A fotóid, dokumentumaid, személyes adataid idegen szervereken vannak, idegen kezekben.</p>
</div>
<div class="problem-card">
<div class="problem-icon">🔒</div>
<h3>Korlátozott kontroll</h3>
<p>Nem te döntöd el, milyen szolgáltatásokat használsz, és mikor szűnnek meg.</p>
</div>
</div>
</div>
</section>
<section class="services" id="szolgaltatasok">
<div class="container">
<div class="section-header">
<h2>Mit kapsz tőlünk?</h2>
<p>Kulcsrakész megoldások, professzionális kivitelezéssel</p>
</div>
<div class="service-list">
<div class="service-item">
<span class="service-number">01</span>
<div class="service-content">
<h3>Szerver beszerzés és beüzemelés</h3>
<p>Segítünk kiválasztani az igényeidnek megfelelő hardvert, és mindent beállítunk.</p>
</div>
<span class="service-icon">🖥️</span>
</div>
<div class="service-item">
<span class="service-number">02</span>
<div class="service-content">
<h3>Alkalmazás telepítés</h3>
<p>Nextcloud, Plex, Jellyfin, Home Assistant, és még sok más - amit csak szeretnél.</p>
</div>
<span class="service-icon">📦</span>
</div>
<div class="service-item">
<span class="service-number">03</span>
<div class="service-content">
<h3>Biztonságos távoli elérés</h3>
<p>Bárhonnan elérheted a szervereidet, biztonságosan, titkosított kapcsolaton keresztül.</p>
</div>
<span class="service-icon">🌐</span>
</div>
<div class="service-item">
<span class="service-number">04</span>
<div class="service-content">
<h3>Automatikus mentések</h3>
<p>Soha többé nem veszíted el az adataidat - rendszeres, automatikus mentések.</p>
</div>
<span class="service-icon">💾</span>
</div>
<div class="service-item">
<span class="service-number">05</span>
<div class="service-content">
<h3>Támogatás és karbantartás</h3>
<p>Ha bármi gond van, itt vagyunk. Rendszeres frissítések, proaktív monitoring.</p>
</div>
<span class="service-icon">🛠️</span>
</div>
</div>
</div>
</section>
<section class="why" id="miert">
<div class="container">
<div class="section-header">
<h2>Miért válaszd a saját szervered?</h2>
<p>Az előnyök, amik miatt megéri</p>
</div>
<div class="why-grid">
<div class="why-card">
<h3>🔐 Teljes adatvédelem</h3>
<p>Az adataid a te otthonodban maradnak. Senki más nem fér hozzájuk - sem a Google, sem a Microsoft, sem senki más.</p>
</div>
<div class="why-card">
<h3>💰 Egyszeri befektetés</h3>
<p>Nincs havi előfizetés, nincs rejtett költség. A szerver a tiéd, örökre. Csak az áramért fizetsz.</p>
</div>
<div class="why-card">
<h3>⚡ Korlátlan kapacitás</h3>
<p>Nincs 15GB-os limit. Bővítheted ahogy nőnek az igényeid - TB-okkal, ha kell.</p>
</div>
<div class="why-card">
<h3>🎛️ Teljes kontroll</h3>
<p>Te döntöd el, milyen szolgáltatásokat futtatsz. Te vagy a főnök, nem a szolgáltató.</p>
</div>
</div>
</div>
</section>
<section class="contact" id="kapcsolat">
<div class="container">
<div class="contact-box">
<h2>Érdekel? Beszéljünk!</h2>
<p>Jelenleg kézi egyeztetéssel dolgozunk. Írj nekünk, és személyre szabott ajánlatot készítünk.</p>
<div class="contact-methods">
<a href="mailto:info@felhom.eu" class="contact-link">✉️ info@felhom.eu</a>
</div>
</div>
</div>
</section>
<footer>
<div class="container">
<p>© 2025 felhom.eu — Saját felhőd, saját szabályaid</p>
</div>
</footer>
</body>
</html>
---
# ConfigMap for the logo (base64 would be needed, or use a PVC/external source)
# For the logo, you'll need to either:
# 1. Host it separately and reference via URL
# 2. Create a PVC and manually upload it
# 3. Base64 encode it in another ConfigMap
# See notes below for the recommended approach
---
# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: felhom
namespace: felhom-system
labels:
app.kubernetes.io/name: felhom
app.kubernetes.io/instance: felhom
app.kubernetes.io/version: "1.0.0"
spec:
replicas: 1
strategy:
type: RollingUpdate
selector:
matchLabels:
app.kubernetes.io/name: felhom
app.kubernetes.io/instance: felhom
template:
metadata:
labels:
app.kubernetes.io/name: felhom
app.kubernetes.io/instance: felhom
app.kubernetes.io/version: "1.0.0"
spec:
containers:
- name: nginx
image: nginx:1.27-alpine
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
resources:
requests:
cpu: 10m
memory: 16Mi
limits:
cpu: 100m
memory: 64Mi
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 5
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 3
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
volumeMounts:
- name: website
mountPath: /usr/share/nginx/html/index.html
subPath: index.html
- name: assets
mountPath: /usr/share/nginx/html/logo.png
subPath: logo.png
volumes:
- name: website
configMap:
name: felhom-website
- name: assets
persistentVolumeClaim:
claimName: felhom-assets
---
# Service
apiVersion: v1
kind: Service
metadata:
name: felhom
namespace: felhom-system
labels:
app.kubernetes.io/name: felhom
app.kubernetes.io/instance: felhom
spec:
type: ClusterIP
ports:
- name: http
port: 80
targetPort: http
protocol: TCP
selector:
app.kubernetes.io/name: felhom
app.kubernetes.io/instance: felhom
---
# Ingress - NOTE: This is PUBLIC facing, no geo-restriction!
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: felhom
namespace: felhom-system
labels:
app.kubernetes.io/name: felhom
app.kubernetes.io/instance: felhom
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
external-dns.alpha.kubernetes.io/hostname: felhom.eu,www.felhom.eu
nginx.ingress.kubernetes.io/ssl-redirect: "true"
# No geo-restriction - this is a public business website!
spec:
ingressClassName: nginx-internal
rules:
- host: felhom.eu
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: felhom
port:
number: 80
- host: www.felhom.eu
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: felhom
port:
number: 80
tls:
- hosts:
- felhom.eu
- www.felhom.eu
secretName: felhom-tls
---
# Small PVC for static assets (logo, images, etc.)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: felhom-assets
namespace: felhom-system
labels:
app.kubernetes.io/name: felhom
app.kubernetes.io/instance: felhom
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 100Mi