diff --git a/README.md b/README.md index 450f375..7e55093 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ -# blogcontenttemplate +# blogcontent +Inhalte des Blogs \ No newline at end of file diff --git a/articles/2025/02/docker-swarm-mit-abweichendem-port-einrichten.md b/articles/2025/02/docker-swarm-mit-abweichendem-port-einrichten.md new file mode 100644 index 0000000..3ca0cc5 --- /dev/null +++ b/articles/2025/02/docker-swarm-mit-abweichendem-port-einrichten.md @@ -0,0 +1,87 @@ + +> Kennzeichnung gemäß Artikel 52 Absatz 1 EU AI Act: [💜 Kein Einsatz von KI](/page/ai) + +**Wir möchten in diesem Artikel über die abweichende Einrichtung eines Swarm-Netzwerks unter vmware berichten. Eine Besonderheit in der Konfiguration von Docker-Swarm unter vmware kann der identische Port (4789) sein, den sowohl vmware, als auch Docker-Swarm nutzen.** + +## Einleitung + +Wir möchten in diesem Artikel über die abweichende Einrichtung eines Swarm-Netzwerks unter vmware berichten. Eine Besonderheit in der Konfiguration von Docker-Swarm unter vmware kann der identische Port (4789) sein, den sowohl vmware, als auch Docker-Swarm nutzen. Hier ist es notwendig, den ```data-path-port``` zu ändern. Wir gehen hier Schritt für Schritt die Konfiguration durch. + +## Umgebung + +Wir installieren drei Swarm-Nodes auf einer vmware-Umgebung mit insgesamt 4 Hosts. Die Anzahl der vmware-Hosts ist jedoch irrelevant. Vorausgesetzt werden drei Ubuntu-Core-Server mit der OS-Version 22.04 ohne weitere Konfiguration. + +## Basis-Konfiguration + +Wir wechseln in den autorisierten Modus um administrative Aktionen ausführen zu können: + +Dazu führen wir das Kommando ```sudo su``` aus. + +Danach installieren wir die Net-Tools mit dem Kommando ```apt install net-tools```. + +Danach installieren wir den Text-Editor nano mit dem Kommando ```apt install nano```. + +Im Anschluss deaktivieren wir den Ubuntu-Cloud-Init. Hierzu suchen wir mit dem Kommando ```apt-cache pkgnames | grep cloud-init``` die passende Konfiguration. + +Die angezeigte Datei sollte nun bearbeitet werden: ```nano /etc/cloud/cloud.cfg.d/99-disable-cloud-init.cfg```. + +Wir ergänzen die Konfiguration um die Zeile ```network: {config: disabled}```. + +Jetzt ist ein Neustart der virtuellen Maschinen notwendig. + +Im Anschluss konfigurieren wir die Netzwerkeinstellungen der virtuellen Maschinen. Führen Sie die zwei Kommandos aus: + +``` +cd /etc/netplan +grep -iH enp1s0 *.* +``` + +Hierbei sollte eine Datei angezeigt werden, die ungefähr so aussieht: ```00-installer-config.yaml```. + +Jetzt bearbeiten wir die Datei mit derm Kommando ```nano 00-installer-config.yaml``` und fügen folgenden Inhalt ein: + +``` +network: + ethernets: + enp1s0: + dhcp4: no + addresses: + - 192.168.122.128/24 + gateway4: 192.168.122.1 + nameservers: + addresses: [1.1.1.1, 1.0.0.1] + version: 2 +``` + +Jetzt aktivieren wir die Konfiguration mit dem Kommando ```netplan apply```. + +## Installation von Docker + +Installieren Sie Docker mit dem Kommando ```apt install docker.io```. + +## Einrichten des Swarm (nur auf dem ersten Server) + +Führen Sie foldendes Kommando aus um den Swarm-Modus zu aktivieren. Besonders hervorzuheben, ist der abweichende Port. Dieser hat uns bei unser Installation in dieser Kombination Kopfzerbrechen bereitet. Deswegen teilen wir unseren Lösungsweg: + +``` +docker swarm init --data-path-port 4788 --advertise-addr 172.29.8.15 +``` + +Beachten Sie, hier bei ```--advertise-addr``` die IP-Adresse Ihrer ersten virtuellen Maschine einzugeben! + +Nachdem Sie den Befehl ausgeführt haben wird Swarm initialisiert. Achten Sie hierbei auf die Ausgabe. Es sollte eine Meldung mit Ihrem "Swarm-Key" ersichtlich sein. Sollte der Key nicht angezeigt werden, können Sie ihn mit dem Kommando ```docker swarm join-token worker``` erneut aufrufen. + +Hinzufügen der zwei anderen Server zum Swarm +Mit nur einer Node ist ein Swarm ziemlich unnötig. Deswegen fügen wir die zwei weiteren virtuellen Maschinen hinzu: + +```docker swarm join --token --KEY-- 172.29.8.15:2377```. + +Diesen Befehl führen sie auf jedem Server aus, der dem Swarm beitreten soll. Ersetzen Sie --KEY-- durch Ihren Swarm-Key. +Mit den folgenden Befehlen können Sie Informationen zu Ihrem Swarm abrufen: + +```docker info``` +```docker node ls``` + +Jetzt sind alle Server Teil des Swarm. + +Möchten Sie die anderen Server ebenfalls zu Manager-Nodes machen, führen Sie diesen Befehl auf dem ersten Server aus: ```docker node promote name```. \ No newline at end of file diff --git a/pages/ai.md b/pages/ai.md new file mode 100644 index 0000000..6717a5d --- /dev/null +++ b/pages/ai.md @@ -0,0 +1,47 @@ + +Ich legen offen, in welchem Umfang künstliche Intelligenz (KI) bei der Erstellung meiner Inhalte beteiligt war.\ +Alle Beiträge sind mit einem eindeutigen Hinweis versehen, damit Leserinnen und Leser nachvollziehen können, ob und wie KI eingesetzt wurde. + +**Die Kennzeichnung erfolgt nach folgendem Schema:** + +> ### 💜 Kein Einsatz von KI +> - Für die inhaltliche Erstellung des Beitrags kam keine KI zum Einsatz. +> - Der Artikel wurde eigenhändig erstellt und überprüft. +> - Das Titelbild **kann** von einer KI erstellt sein. + +Diese Beiträge werden so gekennzeichnet: + +> Kennzeichnung gemäß Artikel 52 Absatz 1 EU AI Act: [💜 Kein Einsatz von KI](/page/ai) + +--- + +> #### 🌱 Kennzeichnung gemäß Artikel 52 Absatz 1 EU AI Act: Rechercheunterstützung +> - Die KI sammelt relevante Quellen, Daten und Fakten, um dem Autor eine fundierte Grundlage für den Beitrag zu liefern. +> - Der Artikel wurde redaktionell überarbeitet und überprüft. +> - Das Titelbild **kann** von einer KI erstellt sein. + +Diese Beiträge werden so gekennzeichnet: + +> Kennzeichnung gemäß Artikel 52 Absatz 1 EU AI Act: [🌱 Rechercheunterstützung](/page/ai) + +--- + +> #### 💬 Kennzeichnung gemäß Artikel 52 Absatz 1 EU AI Act: Inhaltliche Zusammenfassung +> - Die KI fasst längere Texte oder Studien prägnant zusammen, damit der Autor Kernaussagen effizient weiterverarbeiten kann. +> - Der Artikel wurde redaktionell überarbeitet und überprüft. +> - Das Titelbild **kann** von einer KI erstellt sein. + +Diese Beiträge werden so gekennzeichnet: + +> Kennzeichnung gemäß Artikel 52 Absatz 1 EU AI Act: [💬 Inhaltliche Zusammenfassung](/page/ai) + +--- + +> #### ⚡ Kennzeichnung gemäß Artikel 52 Absatz 1 EU AI Act: Vollständige Inhaltserstellung +> - Die KI generiert eigenständig komplette Blogartikel, einschließlich Struktur, Formulierungen und abschließendem Feinschliff. +> - Der Artikel wurde redaktionell überarbeitet und überprüft. +> - Das Titelbild **kann** von einer KI erstellt sein. + +Diese Beiträge werden so gekennzeichnet: + +> Kennzeichnung gemäß Artikel 52 Absatz 1 EU AI Act: [⚡ Vollständige Inhaltserstellung](/page/ai) diff --git a/pages/impressum.md b/pages/impressum.md new file mode 100644 index 0000000..0271a31 --- /dev/null +++ b/pages/impressum.md @@ -0,0 +1,34 @@ + +### Name und Anschrift +Dein Name\ +Adresse 1\ +12345 Test-Stadt + +### Kontakt +E-Mail: mail@example.com\ +Telefon: +49 (1234) 12345-6 + +### Inhaltlich verantwortlich +Dein Name\ +Adresse 1\ +12345 Test-Stadt + +### Weitere Informationen + +Die auf dieser Webseite veröffentlichten kostenlosen und frei zugänglichen Inhalte wurden mit größter Sorgfalt erstellt. + +Diese Website enthält Links zu externen Websites Dritter. Für diese Websites sind die jeweiligen Betreiber verantwortlich.\ +Der Anbieter hat die externen Links bei ihrer erstmaligen Erstellung auf mögliche Rechtsverstöße überprüft und keine festgestellt.\ +Auf die aktuelle und zukünftige Gestaltung sowie auf die Inhalte der verlinkten Seiten hat der Anbieter keinen Einfluss.\ +Das Setzen externer Links bedeutet nicht, dass sich der Anbieter die Inhalte dieser Seiten zu eigen macht.\ +Eine kontinuierliche Überprüfung der externen Links ist für den Anbieter ohne konkrete Hinweise auf Rechtsverstöße nicht zumutbar.\ +Bei Bekanntwerden von Rechtsverstößen werden derartige externe Links jedoch umgehend entfernt. + +Die auf dieser Website veröffentlichten Inhalte sind durch das deutsche Urheber- und Leistungsschutzrecht geschützt.\ +Jede Verwertung, die nicht durch das deutsche Urheber- und Leistungsschutzrecht gestattet ist,\ +erfordert die vorherige schriftliche Zustimmung des Anbieters oder des jeweiligen Rechteinhabers.\ +Dies gilt insbesondere für die Vervielfältigung, Bearbeitung, Übersetzung, Speicherung,\ +Verarbeitung oder Wiedergabe von Inhalten in Datenbanken oder anderen elektronischen Medien und Systemen.\ +Inhalte und Rechte Dritter sind entsprechend gekennzeichnet.\ +Die unerlaubte Vervielfältigung oder Verbreitung einzelner Inhalte oder kompletter Seiten ist nicht gestattet und strafbar.\ +Nur die Erstellung von Kopien und Downloads für den persönlichen, privaten und nicht kommerziellen Gebrauch ist erlaubt. \ No newline at end of file diff --git a/pages/privacy.md b/pages/privacy.md new file mode 100644 index 0000000..156d479 --- /dev/null +++ b/pages/privacy.md @@ -0,0 +1,66 @@ + +## Angaben gemäß § 5 des Telemediengesetzes (TMG) +Verantwortlicher für diese Website (im Folgenden „Blog“): + +### Name und Anschrift +Dein Name\ +Adresse 1\ +12345 Test-Stadt + +### Kontakt +E-Mail: mail@example.com\ +Telefon: +49 (1234) 12345-6 + +--- + +## Allgemeine Hinweise und Pflichtinformationen + +Mir ist der Schutz deiner Daten besonders wichtig. Deshalb gelten auf diesem Blog folgende Grundsätze: + +1. Keine Cookies +Auf diesem Blog werden keinerlei Cookies eingesetzt. Es werden weder technische noch optionale Cookies gesetzt oder gespeichert.\ +Mein Blog ist so programmiert, das er ohne die Speicherung von Informationen auskommt. Weder auf meinem Server von auf deinem Endgerät! + +2. Keine Affiliate-Links +Es gibt keine Affiliate-Links oder andere kommerzielle Verlinkungen, die dazu dienen, Besucheraktivitäten zu erfassen oder Provisionen zu generieren.\ +Dieser Blog ist ein Hobby und dient nicht zur Generierung von Einkommen. + +3. Kein Tracking +Natürlich wäre es spannend zu wissen, über welche Wege die Nutzer hierher gefunden haben.\ +Solche Informationen könnten helfen, Inhalte gezielter auszurichten oder den Blog weiterzuentwickeln. Trotzdem steht für mich eines an erster Stelle: dein Vertrauen.\ +Die Grundsätze dieses Blogs – keine Überwachung, kein Tracking, keine Analyse des Nutzerverhaltens – haben Vorrang vor jeder Statistik.\ +Deshalb verzichte ich bewusst auf den Einsatz von Tools wie Google Analytics, Matomo oder ähnlichen Diensten.\ +Die einzige Funktion ist das anonyme "hochzählen" von Aufrufen eines Artikels. Das hilft mir zu verstehen, wie hoch das Interesse an einem bestimmten Thema ist.\ +Dies ist eine Funktion meinen selbst erstellten Webservers und steht in keinem Zusammenhang zum aufrufenden Besucher.\ +Wenn ein Besucher also 50x F5 drückt, sind dies ungeachtet 50 Aufrufe. + +4. Keine Drittanbieter-Dienste +Auf diesem Blog werden keine Inhalte von Drittanbietern eingebunden.\ +Es werden weder externe Schriftarten (z.B. Google Fonts), noch Skripte, noch Social-Media-Plugins oder Werbenetzwerke verwendet.\ +Sämtliche Inhalte werden lokal und unabhängig bereitgestellt. + +5. Keine Erhebung personenbezogener Daten +Ich erhebe, speichere oder verarbeite keine personenbezogenen Daten.\ +Es gibt keine Formulare, keine Kommentarfunktion, keinen Newsletter und keine anderen Möglichkeiten, personenbezogene Daten zu übermitteln.\ +Bitte sende mir auch bei Kontaktanfragen keine personenbezogenen Daten, wenn dies nicht erforderlich ist. + +6. Statischer Inhalt, keine Interaktion +Der Blog besteht ausschließlich aus statischen Inhalten.\ +Es gibt keine Möglichkeit zur Interaktion, kein Login, keine Registrierung und keine nutzergenerierten Inhalte. + +7. Kontakt +Wenn du Fragen hast oder weitere Informationen benötigst, kannst du mich gerne kontaktieren. Die Kontaktmöglichkeiten findest du im Impressum.\ +Auch hier bitte ich dich, auf die Übermittlung personenbezogener Daten zu verzichten, soweit dies möglich ist. + +**Hinweis** +Da auf diesem Blog keine personenbezogenen Daten verarbeitet werden, entfällt die Pflicht zur Benennung eines Datenschutzbeauftragten gemäß Art. 37 DSGVO. + +--- + +Sollte sich der Umfang dieses Blogs ändern und personenbezogene Daten betroffen sein, wird diese Datenschutzerklärung entsprechend aktualisiert. + +--- + +Diese Maßnahmen dienen dem Ziel, ein Höchstmaß an Privatsphäre und Datenschutz für alle Besucher sicherzustellen.\ +Wenn du Fragen hast oder weitere Informationen benötigst, kannst du mich gerne kontaktieren – die Kontaktmöglichkeiten findest du im Impressum,\ +aber auch hier gilt: bitte ohne Übermittlung personenbezogener Daten. diff --git a/pages/welcome.md b/pages/welcome.md new file mode 100644 index 0000000..d11fe4a --- /dev/null +++ b/pages/welcome.md @@ -0,0 +1,17 @@ + +**Herzlich willkommen auf meinem privaten Blog! Schön, dass du hierher gefunden hast.** + +Ich bin ein IT-Professional mit Leidenschaft für Technologie, Softwareentwicklung und digitale Trends. In diesem Blog teile ich Gedanken, Ideen und Erfahrungen aus meinem Berufsleben – aber auch Themen, die mich in meiner Freizeit beschäftigen. Es ist mir wichtig, hier nicht nur Fachinhalte zu präsentieren, sondern auch nützliche, inspirierende und manchmal einfach unterhaltsame Beiträge zu liefern! + +### Worum geht es hier? + +Der Blog deckt eine breite Palette an Themen ab: von Programmierung, IT-Sicherheit und digitalen Tools bis hin zu persönlichen Projekten, Hobbys und allgemeinen Beobachtungen aus der digitalen Welt. Mein Ziel ist es, Inhalte zu veröffentlichen, die anderen weiterhelfen, Denkanstöße geben oder einfach interessant zu lesen sind. + +### Einsatz von KI-generierten Inhalten + +Ein Teil der Inhalte, insbesondere Bilder, wird mit Hilfe von Künstlicher Intelligenz erzeugt. Ich nutze diese Technologie, um kreative und visuell ansprechende Elemente zu erstellen, die den Blog bereichern. Dabei lege ich Wert darauf, transparent zu machen, wo KI zum Einsatz kommt. +Weitere Informationen können hier gefunden werden: [Kennzeichnungspflicht gemäß EU AI Act](/page/ai) + +--- + +Ich freue mich, wenn du hier etwas findest, das dich inspiriert, dir weiterhilft oder einfach Spaß macht. Viel Freude beim Lesen und Entdecken! diff --git a/static/fonts/FiraCode-VF.woff2 b/static/fonts/FiraCode-VF.woff2 new file mode 100644 index 0000000..e755a9d Binary files /dev/null and b/static/fonts/FiraCode-VF.woff2 differ diff --git a/static/fonts/InterVariable.woff2 b/static/fonts/InterVariable.woff2 new file mode 100644 index 0000000..5a8d3e7 Binary files /dev/null and b/static/fonts/InterVariable.woff2 differ diff --git a/static/img/favicon.ico b/static/img/favicon.ico new file mode 100644 index 0000000..52b302f Binary files /dev/null and b/static/img/favicon.ico differ diff --git a/static/img/placeholder.webp b/static/img/placeholder.webp new file mode 100644 index 0000000..6361ea0 Binary files /dev/null and b/static/img/placeholder.webp differ diff --git a/static/main.css b/static/main.css new file mode 100644 index 0000000..c18791f --- /dev/null +++ b/static/main.css @@ -0,0 +1,182 @@ +/* ---------- Local Web‑Fonts ---------- */ +@font-face { + font-family: "Fira Code"; + src: url("/static/fonts/FiraCode-VF.woff2") format("woff2"); + font-weight: 400 700; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: "Inter"; + src: url("/static/fonts/InterVariable.woff2") format("woff2"); + font-weight: 100 900; + font-style: normal; + font-display: swap; +} +/* ---------- Farbpalette ---------- */ +:root { + /* Light theme */ + --bg: #f5f7fa; + --bg-alt: #ffffff; + --card-bg: #ffffff; + --text: #000000; + --text-muted: #1f2933; + --accent: #2563eb; /* Indigo‑600 */ + --accent-light: #3b82f6; /* Indigo‑500 */ + --code-bg: #f1f5f9; + --code-border: #e2e8f0; + --radius: 0.75rem; + --gap: 2rem; + --shadow: 0 4px 16px rgba(0,0,0,.08); + font-size: 16px; + font-family: "Inter", system-ui, sans-serif; + color-scheme: light; +} + +/* Dark mode (optional) */ +@media (prefers-color-scheme: dark) { + :root { + --bg: #0d1117; + --bg-alt: #161b22; + --card-bg: #161b22; + --text: #ffffff; + --text-muted: #e4e8ec; + --accent: #3b82f6; + --accent-light:#60a5fa; + --code-bg: #1e242c; + --code-border: #30363d; + --shadow: 0 4px 16px rgba(0,0,0,.32); + } +} + +/* ---------- Grundlayout ---------- */ +* { box-sizing: border-box; } +body { + margin: 0; + background: var(--bg); + color: var(--text); + line-height: 1.65; +} +a { + color: var(--accent); + text-decoration: underline dotted; + transition: color .15s; +} +a:hover { color: var(--accent-light); } + + +a.no-underline { + text-decoration: none; +} + +/* Container in der Mitte */ +.wrapper { + max-width: 1200px; + margin: 0 auto; + padding: var(--gap) calc(var(--gap) / 1.5); +} + +img.footer { + max-width: 150px; + max-height: 60px; /* oder ein anderer fixer Wert, z. B. 500px */ + width: auto; + height: auto; +} + +/* ---------- Kopf & Fuß ---------- */ +header, footer { + background: var(--bg-alt); + box-shadow: var(--shadow); +} +header { + position: sticky; top: 0; z-index: 10; + display: flex; justify-content: space-between; align-items: center; + padding: 10px calc(var(--gap) / 1.2); +} +header h1 { margin: 0; font-size: 1.4rem; } +footer { + text-align: center; + padding: 2rem 1rem; + color: var(--text-muted); + font-size: .9rem; + margin-top: var(--gap); +} + +/* ---------- Karten‑Grid ---------- */ +.post-list { + display: grid; + gap: var(--gap); + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + list-style: none; + padding: 0; + margin: 0; +} +.card { + display: flex; + flex-direction: column; + background: var(--card-bg); + border-radius: var(--radius); + box-shadow: var(--shadow); + overflow: hidden; + transition: transform .2s ease, box-shadow .2s ease; +} +.card:hover { transform: translateY(-6px); box-shadow: 0 6px 24px rgba(0,0,0,.1); } +.card img { + width: 100%; height: 180px; object-fit: cover; +} +.card-content { padding: 1rem 1.25rem 1.5rem; } +.card h2 { margin: .25rem 0 .5rem; font-size: 1.25rem; line-height: 1.3; } +.card time { color: var(--text-muted); font-size: .85rem; } + +/* ---------- Artikel ---------- */ +.hero { + width: 100%; height: 320px; object-fit: cover; + border-radius: var(--radius); + box-shadow: var(--shadow); +} +article h1 { font-size: 2.2rem; margin: 1.2rem 0 .3rem; } +article time { color: var(--text-muted); font-size: .9rem; } +article img:not(.hero), article video { + max-width: 100%; height: auto; border-radius: var(--radius); + box-shadow: var(--shadow); + margin: 1rem 0; +} +article pre { + background: var(--code-bg); + border: 1px solid var(--code-border); + padding: 1rem 1.2rem; + border-radius: var(--radius); + overflow: auto; + font-family: "Fira Code", Consolas, monospace; +} +article blockquote { + border-left: 4px solid var(--accent); + padding: .5rem 1rem; margin: 1rem 0; + background: var(--code-bg); + color: var(--text-muted); +} +code { + background: var(--code-bg); + color: var(--text-muted); +} +.main-nav ul { + display: flex; + gap: 1.25rem; + list-style: none; + margin: 0; + padding: 0; +} +.main-nav a { + font-weight: 600; + color: var(--text); +} +.main-nav a:hover { + color: var(--accent); +} + +/* ---------- Responsive ---------- */ +@media (max-width: 640px) { + :root { font-size: 15px; } + .hero { height: 200px; } + header { flex-direction: column; gap: .5rem; } +} diff --git a/templates/article.html b/templates/article.html new file mode 100644 index 0000000..d9c7a0e --- /dev/null +++ b/templates/article.html @@ -0,0 +1,20 @@ +{{ define "title" }}{{ .Title }} – B1tsblog{{ end }} + +{{ define "body" }} +
+ {{ if .Cover }} + + {{ end }} +

← Zurück zur Übersicht

+

{{ .Title }}

+ + +
+ {{ .Body }} +
+ +

← Zurück zur Übersicht

+
+{{ end }} + +{{ define "article" }}{{ template "layout" . }}{{ end }} diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..0c97995 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,39 @@ +{{ define "layout" }} + + + + + + {{ if .Description }} + + {{ end }} + {{ block "title" . }}B1tsblog{{ end }} + + + + +
+

B1tsblog

+ +
+ +
+ {{ template "body" . }} +
+ + + + +{{ end }} \ No newline at end of file diff --git a/templates/list.html b/templates/list.html new file mode 100644 index 0000000..1444f02 --- /dev/null +++ b/templates/list.html @@ -0,0 +1,19 @@ +{{ define "body" }} + +{{ end }} diff --git a/templates/page.html b/templates/page.html new file mode 100644 index 0000000..2b4e51f --- /dev/null +++ b/templates/page.html @@ -0,0 +1,12 @@ +{{ define "title" }}{{ .Title }} – B1tsblog{{ end }} + +{{ define "body" }} +
+

← Zurück

+

{{ .Title }}

+
{{ .Body }}
+

← Zurück

+
+{{ end }} + +{{ define "page" }}{{ template "layout" . }}{{ end }}