Files

125 lines
12 KiB
TeX

\babel@toc {ngerman}{}\relax
\contentsline {section}{\numberline {1}Server-Absicherung (Ubuntu 24.04 auf Contabo VPS)}{5}{section.1}%
\contentsline {subsection}{\numberline {1.1}Schritt 1: SSH-Verbindung testen}{5}{subsection.1.1}%
\contentsline {subsection}{\numberline {1.2}Schritt 2: System-Updates}{6}{subsection.1.2}%
\contentsline {subsection}{\numberline {1.3}Schritt 3: SSH-Key-Authentifizierung}{6}{subsection.1.3}%
\contentsline {subsection}{\numberline {1.4}Schritt 4: SSH-Client-Konfiguration (Alias)}{7}{subsection.1.4}%
\contentsline {subsection}{\numberline {1.5}Schritt 5: SSH-Timeout auf 20 Minuten}{8}{subsection.1.5}%
\contentsline {subsection}{\numberline {1.6}Schritt 6: Fail2Ban (Bruteforce-Schutz)}{8}{subsection.1.6}%
\contentsline {subsection}{\numberline {1.7}Zusammenfassung}{9}{subsection.1.7}%
\contentsline {section}{\numberline {2}Firewall mit UFW einrichten}{9}{section.2}%
\contentsline {subsection}{\numberline {2.1}Was ist eine Firewall und warum brauchen wir sie?}{10}{subsection.2.1}%
\contentsline {subsection}{\numberline {2.2}Die 65.535 Ports: Ein kurzer Überblick}{10}{subsection.2.2}%
\contentsline {subsection}{\numberline {2.3}Die drei Ports, die wir öffnen}{10}{subsection.2.3}%
\contentsline {subsection}{\numberline {2.4}Warum HTTPS für PWAs Pflicht ist}{10}{subsection.2.4}%
\contentsline {subsection}{\numberline {2.5}Durchführung}{11}{subsection.2.5}%
\contentsline {subsubsection}{\numberline {2.5.1}Standardrichtlinien setzen}{11}{subsubsection.2.5.1}%
\contentsline {subsubsection}{\numberline {2.5.2}Benötigte Ports öffnen}{12}{subsubsection.2.5.2}%
\contentsline {subsubsection}{\numberline {2.5.3}Firewall aktivieren}{12}{subsubsection.2.5.3}%
\contentsline {subsubsection}{\numberline {2.5.4}Konfiguration überprüfen}{13}{subsubsection.2.5.4}%
\contentsline {subsection}{\numberline {2.6}Zusammenfassung}{13}{subsection.2.6}%
\contentsline {section}{\numberline {3}Docker-Images bauen und App deployen}{14}{section.3}%
\contentsline {subsection}{\numberline {3.1}Was ist Docker und warum nutzen wir es?}{14}{subsection.3.1}%
\contentsline {subsection}{\numberline {3.2}Die drei Dockerfiles im Detail}{14}{subsection.3.2}%
\contentsline {subsubsection}{\numberline {3.2.1}Backend-Dockerfile: \texttt {apps/api/Dockerfile}}{14}{subsubsection.3.2.1}%
\contentsline {subsubsection}{\numberline {3.2.2}Frontend-Dockerfile: \texttt {apps/web/Dockerfile}}{15}{subsubsection.3.2.2}%
\contentsline {subsubsection}{\numberline {3.2.3}Nginx-Konfiguration: \texttt {apps/web/nginx.conf}}{16}{subsubsection.3.2.3}%
\contentsline {subsection}{\numberline {3.3}Das Backend: Program.cs im Detail}{17}{subsection.3.3}%
\contentsline {subsection}{\numberline {3.4}Der API-Client: client.ts im Detail}{18}{subsection.3.4}%
\contentsline {subsection}{\numberline {3.5}Das Frontend: App.tsx im Detail}{18}{subsection.3.5}%
\contentsline {subsection}{\numberline {3.6}Images bauen}{19}{subsection.3.6}%
\contentsline {subsection}{\numberline {3.7}Images exportieren und auf den Server kopieren}{20}{subsection.3.7}%
\contentsline {subsection}{\numberline {3.8}Container auf dem Server starten}{20}{subsection.3.8}%
\contentsline {subsection}{\numberline {3.9}Aufgetretene Probleme und Lösungen}{21}{subsection.3.9}%
\contentsline {subsection}{\numberline {3.10}Zusammenfassung}{22}{subsection.3.10}%
\contentsline {section}{\numberline {4}Domain kaufen und DNS konfigurieren}{22}{section.4}%
\contentsline {subsection}{\numberline {4.1}Warum eine eigene Domain?}{22}{subsection.4.1}%
\contentsline {subsection}{\numberline {4.2}Grundlagen: Wie funktioniert das DNS?}{22}{subsection.4.2}%
\contentsline {subsection}{\numberline {4.3}Was ist DNS-Propagation?}{23}{subsection.4.3}%
\contentsline {subsection}{\numberline {4.4}Domain-Kauf bei Contabo}{23}{subsection.4.4}%
\contentsline {subsubsection}{\numberline {4.4.1}Schritt 1: Einloggen ins Kundencenter}{23}{subsubsection.4.4.1}%
\contentsline {subsubsection}{\numberline {4.4.2}Schritt 2: Domain bestellen}{23}{subsubsection.4.4.2}%
\contentsline {subsubsection}{\numberline {4.4.3}Schritt 3: Domain-Handles konfigurieren}{24}{subsubsection.4.4.3}%
\contentsline {subsubsection}{\numberline {4.4.4}Schritt 4: Nameserver festlegen}{24}{subsubsection.4.4.4}%
\contentsline {subsubsection}{\numberline {4.4.5}Schritt 5: IP-Adresse auswählen}{24}{subsubsection.4.4.5}%
\contentsline {subsubsection}{\numberline {4.4.6}Schritt 6: Bestellung abschließen}{24}{subsubsection.4.4.6}%
\contentsline {subsection}{\numberline {4.5}DNS-Einträge für die Domain einrichten}{24}{subsection.4.5}%
\contentsline {subsubsection}{\numberline {4.5.1}Schritt 1: DNS Zone Management öffnen}{24}{subsubsection.4.5.1}%
\contentsline {subsubsection}{\numberline {4.5.2}Schritt 2: Notwendige A-Records anlegen}{25}{subsubsection.4.5.2}%
\contentsline {subsection}{\numberline {4.6}DNS-Propagation prüfen und beschleunigen}{25}{subsection.4.6}%
\contentsline {subsubsection}{\numberline {4.6.1}Direkt beim Nameserver prüfen}{25}{subsubsection.4.6.1}%
\contentsline {subsubsection}{\numberline {4.6.2}Lokalen DNS-Cache leeren}{26}{subsubsection.4.6.2}%
\contentsline {subsubsection}{\numberline {4.6.3}Server direkt über IP prüfen}{26}{subsubsection.4.6.3}%
\contentsline {subsubsection}{\numberline {4.6.4}Online DNS-Checker verwenden}{26}{subsubsection.4.6.4}%
\contentsline {subsection}{\numberline {4.7}Zusammenfassung}{26}{subsection.4.7}%
\contentsline {section}{\numberline {5}HTTPS mit nginx-proxy und Let's Encrypt}{27}{section.5}%
\contentsline {subsection}{\numberline {5.1}Warum brauchen wir HTTPS?}{27}{subsection.5.1}%
\contentsline {subsection}{\numberline {5.2}Wie funktioniert das SSL-Zertifikat von Let's Encrypt?}{27}{subsection.5.2}%
\contentsline {subsection}{\numberline {5.3}DNS-Propagation: Wie lange dauert es?}{28}{subsection.5.3}%
\contentsline {subsection}{\numberline {5.4}Architektur: Wie hängen die Container zusammen?}{28}{subsection.5.4}%
\contentsline {subsection}{\numberline {5.5}Schritt-für-Schritt: HTTPS einrichten}{29}{subsection.5.5}%
\contentsline {subsubsection}{\numberline {5.5.1}Schritt 1: Bestehende Container stoppen und löschen}{29}{subsubsection.5.5.1}%
\contentsline {subsubsection}{\numberline {5.5.2}Schritt 2: Verzeichnis für docker-compose anlegen}{29}{subsubsection.5.5.2}%
\contentsline {subsubsection}{\numberline {5.5.3}Schritt 3: docker-compose.yml erstellen}{29}{subsubsection.5.5.3}%
\contentsline {paragraph}{\nonumberline nginx-proxy}{31}{paragraph*.3}%
\contentsline {paragraph}{\nonumberline acme-companion}{31}{paragraph*.5}%
\contentsline {paragraph}{\nonumberline frontend (entscheidende Umgebungsvariablen!)}{31}{paragraph*.7}%
\contentsline {paragraph}{\nonumberline Docker Volumes}{32}{paragraph*.9}%
\contentsline {subsubsection}{\numberline {5.5.4}Schritt 4: Container starten}{32}{subsubsection.5.5.4}%
\contentsline {subsubsection}{\numberline {5.5.5}Schritt 5: Status prüfen}{32}{subsubsection.5.5.5}%
\contentsline {subsubsection}{\numberline {5.5.6}Schritt 6: Logs des acme-companion prüfen}{32}{subsubsection.5.5.6}%
\contentsline {subsection}{\numberline {5.6}Häufige Fehler und ihre Behebung}{32}{subsection.5.6}%
\contentsline {subsubsection}{\numberline {5.6.1}Fehler 1: ''can't get nginx-proxy container ID''}{32}{subsubsection.5.6.1}%
\contentsline {subsubsection}{\numberline {5.6.2}Fehler 2: ''contact email has forbidden domain''}{32}{subsubsection.5.6.2}%
\contentsline {subsubsection}{\numberline {5.6.3}Fehler 3: ''DNS problem: NXDOMAIN''}{33}{subsubsection.5.6.3}%
\contentsline {subsection}{\numberline {5.7}Wie füge ich später weitere Subdomains hinzu?}{33}{subsection.5.7}%
\contentsline {subsection}{\numberline {5.8}Wie funktioniert der Reverse Proxy im Detail?}{33}{subsection.5.8}%
\contentsline {subsection}{\numberline {5.9}Zusammenfassung}{34}{subsection.5.9}%
\contentsline {section}{\numberline {6}Gitea Installation und Server-Übersicht}{34}{section.6}%
\contentsline {subsection}{\numberline {6.1}Warum ein eigener Git-Server?}{34}{subsection.6.1}%
\contentsline {subsection}{\numberline {6.2}OneDev: Der gescheiterte Versuch}{34}{subsection.6.2}%
\contentsline {subsubsection}{\numberline {6.2.1}Installationsversuch mit Docker (Version \texttt {1dev/server:latest})}{35}{subsubsection.6.2.1}%
\contentsline {subsection}{\numberline {6.3}Gitea: Die schlanke Alternative}{35}{subsection.6.3}%
\contentsline {subsection}{\numberline {6.4}Gitea mit Docker installieren}{36}{subsection.6.4}%
\contentsline {subsubsection}{\numberline {6.4.1}Schritt 1: OneDev rückstandslos entfernen}{36}{subsubsection.6.4.1}%
\contentsline {subsubsection}{\numberline {6.4.2}Schritt 2: Gitea-Verzeichnis und docker-compose.yml anlegen}{36}{subsubsection.6.4.2}%
\contentsline {subsubsection}{\numberline {6.4.3}Schritt 3: Container starten}{37}{subsubsection.6.4.3}%
\contentsline {subsubsection}{\numberline {6.4.4}Schritt 4: Firewall öffnen}{37}{subsubsection.6.4.4}%
\contentsline {subsubsection}{\numberline {6.4.5}Schritt 5: Gitea im Browser einrichten}{37}{subsubsection.6.4.5}%
\contentsline {subsection}{\numberline {6.5}Vollständige Server-Übersicht}{38}{subsection.6.5}%
\contentsline {subsubsection}{\numberline {6.5.1}Laufende Docker-Container}{38}{subsubsection.6.5.1}%
\contentsline {subsubsection}{\numberline {6.5.2}Docker-Volumes (persistente Datenspeicher)}{38}{subsubsection.6.5.2}%
\contentsline {subsubsection}{\numberline {6.5.3}Firewall (nur diese Ports sind offen!)}{38}{subsubsection.6.5.3}%
\contentsline {subsubsection}{\numberline {6.5.4}Installierte Systempakete}{39}{subsubsection.6.5.4}%
\contentsline {subsubsection}{\numberline {6.5.5}Verzeichnisstruktur unter /opt}{39}{subsubsection.6.5.5}%
\contentsline {subsection}{\numberline {6.6}Wie Gitea in die Infrastruktur passt}{39}{subsection.6.6}%
\contentsline {subsection}{\numberline {6.7}Zusammenfassung}{40}{subsection.6.7}%
\contentsline {section}{\numberline {7}CI/CD mit Gitea Actions}{40}{section.7}%
\contentsline {subsection}{\numberline {7.1}Docker-Grundlagen: Container verstehen und verwalten}{40}{subsection.7.1}%
\contentsline {subsubsection}{\numberline {7.1.1}Container auflisten}{40}{subsubsection.7.1.1}%
\contentsline {subsubsection}{\numberline {7.1.2}Container-Logs anzeigen}{41}{subsubsection.7.1.2}%
\contentsline {subsubsection}{\numberline {7.1.3}Container stoppen, starten, neustarten}{42}{subsubsection.7.1.3}%
\contentsline {subsubsection}{\numberline {7.1.4}In einen Container einsteigen}{42}{subsubsection.7.1.4}%
\contentsline {subsubsection}{\numberline {7.1.5}Images verwalten}{42}{subsubsection.7.1.5}%
\contentsline {subsubsection}{\numberline {7.1.6}Netzwerke inspizieren}{43}{subsubsection.7.1.6}%
\contentsline {subsection}{\numberline {7.2}CI/CD-Pipeline mit Gitea Actions einrichten}{43}{subsection.7.2}%
\contentsline {subsubsection}{\numberline {7.2.1}Was ist CI/CD?}{43}{subsubsection.7.2.1}%
\contentsline {subsubsection}{\numberline {7.2.2}Der Gitea Act Runner}{43}{subsubsection.7.2.2}%
\contentsline {subsubsection}{\numberline {7.2.3}Die Workflow-Datei}{44}{subsubsection.7.2.3}%
\contentsline {subsection}{\numberline {7.3}Alle aufgetretenen Probleme und ihre Lösungen}{44}{subsection.7.3}%
\contentsline {subsubsection}{\numberline {7.3.1}Problem 1: Docker-Socket doppelt gemountet}{44}{subsubsection.7.3.1}%
\contentsline {subsubsection}{\numberline {7.3.2}Problem 2: Pfade zu Dockerfiles}{45}{subsubsection.7.3.2}%
\contentsline {subsubsection}{\numberline {7.3.3}Problem 3: ERR\_PNPM\_IGNORED\_BUILDS}{45}{subsubsection.7.3.3}%
\contentsline {subsubsection}{\numberline {7.3.4}Problem 4: Fehlende nginx.conf}{45}{subsubsection.7.3.4}%
\contentsline {subsubsection}{\numberline {7.3.5}Problem 5: Container ohne Port-Mapping}{45}{subsubsection.7.3.5}%
\contentsline {subsection}{\numberline {7.4}Tutorial: Einfache HTML-Seite deployen}{45}{subsection.7.4}%
\contentsline {subsubsection}{\numberline {7.4.1}Schritt 1: Projekt erstellen}{45}{subsubsection.7.4.1}%
\contentsline {subsubsection}{\numberline {7.4.2}Schritt 2: index.html erstellen}{46}{subsubsection.7.4.2}%
\contentsline {subsubsection}{\numberline {7.4.3}Schritt 3: Dockerfile erstellen}{46}{subsubsection.7.4.3}%
\contentsline {subsubsection}{\numberline {7.4.4}Schritt 4: Workflow erstellen}{46}{subsubsection.7.4.4}%
\contentsline {subsubsection}{\numberline {7.4.5}Schritt 5: In Gitea pushen}{47}{subsubsection.7.4.5}%
\contentsline {subsubsection}{\numberline {7.4.6}Schritt 6: Firewall öffnen und testen}{47}{subsubsection.7.4.6}%
\contentsline {subsection}{\numberline {7.5}Docker-Befehle Cheat Sheet}{47}{subsection.7.5}%
\contentsline {subsection}{\numberline {7.6}Zusammenfassung}{47}{subsection.7.6}%
\providecommand \tocbasic@end@toc@file {}\tocbasic@end@toc@file