Compare commits

...

2 Commits

Author SHA1 Message Date
robre 50235e5de0 Fix: API_BASE auf leer gesetzt für Produktion
Deploy Fitness App / deploy (push) Successful in 1m21s
2026-05-09 19:39:16 +02:00
robre 5a20a14720 Add comprehensive tutorial for CI/CD with Gitea Actions and Docker 2026-05-09 14:12:57 +02:00
10 changed files with 827 additions and 297 deletions
+236 -164
View File
@@ -10,122 +10,122 @@
\babel@aux{ngerman}{}
\BKM@entry{id=1,dest={73656374696F6E2E31},srcline={5}}{5C3337365C3337375C303030535C303030655C303030725C303030765C303030655C303030725C3030302D5C303030415C303030625C303030735C303030695C303030635C303030685C303030655C303030725C303030755C3030306E5C303030675C3030305C3034305C3030305C3035305C303030555C303030625C303030755C3030306E5C303030745C303030755C3030305C3034305C303030325C303030345C3030302E5C303030305C303030345C3030305C3034305C303030615C303030755C303030665C3030305C3034305C303030435C3030306F5C3030306E5C303030745C303030615C303030625C3030306F5C3030305C3034305C303030565C303030505C303030535C3030305C303531}
\BKM@entry{id=2,dest={73756273656374696F6E2E312E31},srcline={28}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030315C3030303A5C3030305C3034305C303030535C303030535C303030485C3030302D5C303030565C303030655C303030725C303030625C303030695C3030306E5C303030645C303030755C3030306E5C303030675C3030305C3034305C303030745C303030655C303030735C303030745C303030655C3030306E}
\@writefile{toc}{\contentsline {section}{\numberline {1}Server-Absicherung (Ubuntu 24.04 auf Contabo VPS)}{4}{section.1}\protected@file@percent }
\newlabel{sec:step01}{{1}{4}{Server-Absicherung (Ubuntu 24.04 auf Contabo VPS)}{section.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {1.1}Schritt 1: SSH-Verbindung testen}{4}{subsection.1.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {1}SSH-Verbindung zum Server aufbauen}{4}{lstlisting.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {2}WARNUNG: REMOTE HOST IDENTIFICATION HAS CHANGED}{4}{lstlisting.2}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {1}Server-Absicherung (Ubuntu 24.04 auf Contabo VPS)}{5}{section.1}\protected@file@percent }
\newlabel{sec:step01}{{1}{5}{Server-Absicherung (Ubuntu 24.04 auf Contabo VPS)}{section.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {1.1}Schritt 1: SSH-Verbindung testen}{5}{subsection.1.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {1}SSH-Verbindung zum Server aufbauen}{5}{lstlisting.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {2}WARNUNG: REMOTE HOST IDENTIFICATION HAS CHANGED}{5}{lstlisting.2}\protected@file@percent }
\BKM@entry{id=3,dest={73756273656374696F6E2E312E32},srcline={67}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030325C3030303A5C3030305C3034305C303030535C303030795C303030735C303030745C303030655C3030306D5C3030302D5C303030555C303030705C303030645C303030615C303030745C303030655C30303073}
\BKM@entry{id=4,dest={73756273656374696F6E2E312E33},srcline={88}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030335C3030303A5C3030305C3034305C303030535C303030535C303030485C3030302D5C3030304B5C303030655C303030795C3030302D5C303030415C303030755C303030745C303030685C303030655C3030306E5C303030745C303030695C303030665C303030695C3030307A5C303030695C303030655C303030725C303030755C3030306E5C30303067}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {3}Alten SSH-Fingerabdruck entfernen}{5}{lstlisting.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {1.2}Schritt 2: System-Updates}{5}{subsection.1.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {4}System-Updates ausführen}{5}{lstlisting.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {1.3}Schritt 3: SSH-Key-Authentifizierung}{5}{subsection.1.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5}SSH-Key generieren}{5}{lstlisting.5}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {3}Alten SSH-Fingerabdruck entfernen}{6}{lstlisting.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {1.2}Schritt 2: System-Updates}{6}{subsection.1.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {4}System-Updates ausführen}{6}{lstlisting.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {1.3}Schritt 3: SSH-Key-Authentifizierung}{6}{subsection.1.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5}SSH-Key generieren}{6}{lstlisting.5}\protected@file@percent }
\BKM@entry{id=5,dest={73756273656374696F6E2E312E34},srcline={132}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030345C3030303A5C3030305C3034305C303030535C303030535C303030485C3030302D5C303030435C3030306C5C303030695C303030655C3030306E5C303030745C3030302D5C3030304B5C3030306F5C3030306E5C303030665C303030695C303030675C303030755C303030725C303030615C303030745C303030695C3030306F5C3030306E5C3030305C3034305C3030305C3035305C303030415C3030306C5C303030695C303030615C303030735C3030305C303531}
\BKM@entry{id=6,dest={73756273656374696F6E2E312E35},srcline={169}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030355C3030303A5C3030305C3034305C303030535C303030535C303030485C3030302D5C303030545C303030695C3030306D5C303030655C3030306F5C303030755C303030745C3030305C3034305C303030615C303030755C303030665C3030305C3034305C303030325C303030305C3030305C3034305C3030304D5C303030695C3030306E5C303030755C303030745C303030655C3030306E}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {6}Public Key auf den Server übertragen}{6}{lstlisting.6}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {7}Login ohne Passwort testen}{6}{lstlisting.7}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {1.4}Schritt 4: SSH-Client-Konfiguration (Alias)}{6}{subsection.1.4}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {8}SSH-Konfiguration bearbeiten}{6}{lstlisting.8}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {9}Inhalt von \textasciitilde /.ssh/config}{6}{lstlisting.9}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {10}Mit Alias verbinden}{6}{lstlisting.10}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {6}Public Key auf den Server übertragen}{7}{lstlisting.6}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {7}Login ohne Passwort testen}{7}{lstlisting.7}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {1.4}Schritt 4: SSH-Client-Konfiguration (Alias)}{7}{subsection.1.4}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {8}SSH-Konfiguration bearbeiten}{7}{lstlisting.8}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {9}Inhalt von \textasciitilde /.ssh/config}{7}{lstlisting.9}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {10}Mit Alias verbinden}{7}{lstlisting.10}\protected@file@percent }
\BKM@entry{id=7,dest={73756273656374696F6E2E312E36},srcline={203}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030365C3030303A5C3030305C3034305C303030465C303030615C303030695C3030306C5C303030325C303030425C303030615C3030306E5C3030305C3034305C3030305C3035305C303030425C303030725C303030755C303030745C303030655C303030665C3030306F5C303030725C303030635C303030655C3030302D5C303030535C303030635C303030685C303030755C303030745C3030307A5C3030305C303531}
\@writefile{toc}{\contentsline {subsection}{\numberline {1.5}Schritt 5: SSH-Timeout auf 20 Minuten}{7}{subsection.1.5}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {11}SSH-Server-Konfiguration bearbeiten}{7}{lstlisting.11}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {12}Timeout-Konfiguration}{7}{lstlisting.12}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {13}SSH-Dienst neustarten}{7}{lstlisting.13}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {1.6}Schritt 6: Fail2Ban (Bruteforce-Schutz)}{7}{subsection.1.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {1.5}Schritt 5: SSH-Timeout auf 20 Minuten}{8}{subsection.1.5}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {11}SSH-Server-Konfiguration bearbeiten}{8}{lstlisting.11}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {12}Timeout-Konfiguration}{8}{lstlisting.12}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {13}SSH-Dienst neustarten}{8}{lstlisting.13}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {1.6}Schritt 6: Fail2Ban (Bruteforce-Schutz)}{8}{subsection.1.6}\protected@file@percent }
\BKM@entry{id=8,dest={73756273656374696F6E2E312E37},srcline={258}}{5C3337365C3337375C3030305A5C303030755C303030735C303030615C3030306D5C3030306D5C303030655C3030306E5C303030665C303030615C303030735C303030735C303030755C3030306E5C30303067}
\BKM@entry{id=9,dest={73656374696F6E2E32},srcline={5}}{5C3337365C3337375C303030465C303030695C303030725C303030655C303030775C303030615C3030306C5C3030306C5C3030305C3034305C3030306D5C303030695C303030745C3030305C3034305C303030555C303030465C303030575C3030305C3034305C303030655C303030695C3030306E5C303030725C303030695C303030635C303030685C303030745C303030655C3030306E}
\BKM@entry{id=10,dest={73756273656374696F6E2E322E31},srcline={10}}{5C3337365C3337375C303030575C303030615C303030735C3030305C3034305C303030695C303030735C303030745C3030305C3034305C303030655C303030695C3030306E5C303030655C3030305C3034305C303030465C303030695C303030725C303030655C303030775C303030615C3030306C5C3030306C5C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030775C303030615C303030725C303030755C3030306D5C3030305C3034305C303030625C303030725C303030615C303030755C303030635C303030685C303030655C3030306E5C3030305C3034305C303030775C303030695C303030725C3030305C3034305C303030735C303030695C303030655C3030303F}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {14}Beispiel: /etc/fail2ban/jail.local}{8}{lstlisting.14}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {15}Fail2Ban installieren}{8}{lstlisting.15}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {16}Fail2Ban aktivieren und starten}{8}{lstlisting.16}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {17}Fail2Ban-Status abfragen}{8}{lstlisting.17}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {18}Erfolgreiche Ausgabe}{8}{lstlisting.18}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {1.7}Zusammenfassung}{8}{subsection.1.7}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {2}Firewall mit UFW einrichten}{8}{section.2}\protected@file@percent }
\newlabel{sec:step02}{{2}{8}{Firewall mit UFW einrichten}{section.2}{}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {14}Beispiel: /etc/fail2ban/jail.local}{9}{lstlisting.14}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {15}Fail2Ban installieren}{9}{lstlisting.15}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {16}Fail2Ban aktivieren und starten}{9}{lstlisting.16}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {17}Fail2Ban-Status abfragen}{9}{lstlisting.17}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {18}Erfolgreiche Ausgabe}{9}{lstlisting.18}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {1.7}Zusammenfassung}{9}{subsection.1.7}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {2}Firewall mit UFW einrichten}{9}{section.2}\protected@file@percent }
\newlabel{sec:step02}{{2}{9}{Firewall mit UFW einrichten}{section.2}{}}
\BKM@entry{id=11,dest={73756273656374696F6E2E322E32},srcline={21}}{5C3337365C3337375C303030445C303030695C303030655C3030305C3034305C303030365C303030355C3030302E5C303030355C303030335C303030355C3030305C3034305C303030505C3030306F5C303030725C303030745C303030735C3030303A5C3030305C3034305C303030455C303030695C3030306E5C3030305C3034305C3030306B5C303030755C303030725C3030307A5C303030655C303030725C3030305C3034305C3030305C3333345C303030625C303030655C303030725C303030625C3030306C5C303030695C303030635C3030306B}
\BKM@entry{id=12,dest={73756273656374696F6E2E322E33},srcline={52}}{5C3337365C3337375C303030445C303030695C303030655C3030305C3034305C303030645C303030725C303030655C303030695C3030305C3034305C303030505C3030306F5C303030725C303030745C303030735C3030302C5C3030305C3034305C303030645C303030695C303030655C3030305C3034305C303030775C303030695C303030725C3030305C3034305C3030305C3336365C303030665C303030665C3030306E5C303030655C3030306E}
\BKM@entry{id=13,dest={73756273656374696F6E2E322E34},srcline={70}}{5C3337365C3337375C303030575C303030615C303030725C303030755C3030306D5C3030305C3034305C303030485C303030545C303030545C303030505C303030535C3030305C3034305C303030665C3030305C3337345C303030725C3030305C3034305C303030505C303030575C303030415C303030735C3030305C3034305C303030505C303030665C3030306C5C303030695C303030635C303030685C303030745C3030305C3034305C303030695C303030735C30303074}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Was ist eine Firewall und warum brauchen wir sie?}{9}{subsection.2.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Die 65.535 Ports: Ein kurzer Überblick}{9}{subsection.2.2}\protected@file@percent }
\@writefile{lot}{\contentsline {table}{\numberline {1}{\ignorespaces Bekannte Ports und ihre Dienste}}{9}{table.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}Die drei Ports, die wir öffnen}{9}{subsection.2.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.4}Warum HTTPS für PWAs Pflicht ist}{9}{subsection.2.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Was ist eine Firewall und warum brauchen wir sie?}{10}{subsection.2.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Die 65.535 Ports: Ein kurzer Überblick}{10}{subsection.2.2}\protected@file@percent }
\@writefile{lot}{\contentsline {table}{\numberline {1}{\ignorespaces Bekannte Ports und ihre Dienste}}{10}{table.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}Die drei Ports, die wir öffnen}{10}{subsection.2.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.4}Warum HTTPS für PWAs Pflicht ist}{10}{subsection.2.4}\protected@file@percent }
\BKM@entry{id=14,dest={73756273656374696F6E2E322E35},srcline={82}}{5C3337365C3337375C303030445C303030755C303030725C303030635C303030685C303030665C3030305C3337345C303030685C303030725C303030755C3030306E5C30303067}
\BKM@entry{id=15,dest={73756273756273656374696F6E2E322E352E31},srcline={84}}{5C3337365C3337375C303030535C303030745C303030615C3030306E5C303030645C303030615C303030725C303030645C303030725C303030695C303030635C303030685C303030745C3030306C5C303030695C3030306E5C303030695C303030655C3030306E5C3030305C3034305C303030735C303030655C303030745C3030307A5C303030655C3030306E}
\@writefile{lot}{\contentsline {table}{\numberline {2}{\ignorespaces Geöffnete Ports und ihre Begründung}}{10}{table.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.5}Durchführung}{10}{subsection.2.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.5.1}Standardrichtlinien setzen}{10}{subsubsection.2.5.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {19}Firewall-Standardregeln definieren}{10}{lstlisting.19}\protected@file@percent }
\@writefile{lot}{\contentsline {table}{\numberline {2}{\ignorespaces Geöffnete Ports und ihre Begründung}}{11}{table.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.5}Durchführung}{11}{subsection.2.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.5.1}Standardrichtlinien setzen}{11}{subsubsection.2.5.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {19}Firewall-Standardregeln definieren}{11}{lstlisting.19}\protected@file@percent }
\BKM@entry{id=16,dest={73756273756273656374696F6E2E322E352E32},srcline={105}}{5C3337365C3337375C303030425C303030655C3030306E5C3030305C3336365C303030745C303030695C303030675C303030745C303030655C3030305C3034305C303030505C3030306F5C303030725C303030745C303030735C3030305C3034305C3030305C3336365C303030665C303030665C3030306E5C303030655C3030306E}
\BKM@entry{id=17,dest={73756273756273656374696F6E2E322E352E33},srcline={125}}{5C3337365C3337375C303030465C303030695C303030725C303030655C303030775C303030615C3030306C5C3030306C5C3030305C3034305C303030615C3030306B5C303030745C303030695C303030765C303030695C303030655C303030725C303030655C3030306E}
\BKM@entry{id=18,dest={73756273756273656374696F6E2E322E352E34},srcline={141}}{5C3337365C3337375C3030304B5C3030306F5C3030306E5C303030665C303030695C303030675C303030755C303030725C303030615C303030745C303030695C3030306F5C3030306E5C3030305C3034305C3030305C3337345C303030625C303030655C303030725C303030705C303030725C3030305C3337345C303030665C303030655C3030306E}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.5.2}Benötigte Ports öffnen}{11}{subsubsection.2.5.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {20}Ports 22, 80, 443 für TCP freigeben}{11}{lstlisting.20}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.5.3}Firewall aktivieren}{11}{subsubsection.2.5.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {21}Firewall aktivieren}{11}{lstlisting.21}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.5.2}Benötigte Ports öffnen}{12}{subsubsection.2.5.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {20}Ports 22, 80, 443 für TCP freigeben}{12}{lstlisting.20}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.5.3}Firewall aktivieren}{12}{subsubsection.2.5.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {21}Firewall aktivieren}{12}{lstlisting.21}\protected@file@percent }
\BKM@entry{id=19,dest={73756273656374696F6E2E322E36},srcline={179}}{5C3337365C3337375C3030305A5C303030755C303030735C303030615C3030306D5C3030306D5C303030655C3030306E5C303030665C303030615C303030735C303030735C303030755C3030306E5C30303067}
\BKM@entry{id=20,dest={73656374696F6E2E33},srcline={5}}{5C3337365C3337375C303030445C3030306F5C303030635C3030306B5C303030655C303030725C3030302D5C303030495C3030306D5C303030615C303030675C303030655C303030735C3030305C3034305C303030625C303030615C303030755C303030655C3030306E5C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030415C303030705C303030705C3030305C3034305C303030645C303030655C303030705C3030306C5C3030306F5C303030795C303030655C3030306E}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.5.4}Konfiguration überprüfen}{12}{subsubsection.2.5.4}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {22}Firewall-Status mit Details anzeigen}{12}{lstlisting.22}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {23}Erwartete Firewall-Ausgabe (gekürzt)}{12}{lstlisting.23}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.6}Zusammenfassung}{12}{subsection.2.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.5.4}Konfiguration überprüfen}{13}{subsubsection.2.5.4}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {22}Firewall-Status mit Details anzeigen}{13}{lstlisting.22}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {23}Erwartete Firewall-Ausgabe (gekürzt)}{13}{lstlisting.23}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.6}Zusammenfassung}{13}{subsection.2.6}\protected@file@percent }
\BKM@entry{id=21,dest={73756273656374696F6E2E332E31},srcline={10}}{5C3337365C3337375C303030575C303030615C303030735C3030305C3034305C303030695C303030735C303030745C3030305C3034305C303030445C3030306F5C303030635C3030306B5C303030655C303030725C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030775C303030615C303030725C303030755C3030306D5C3030305C3034305C3030306E5C303030755C303030745C3030307A5C303030655C3030306E5C3030305C3034305C303030775C303030695C303030725C3030305C3034305C303030655C303030735C3030303F}
\BKM@entry{id=22,dest={73756273656374696F6E2E332E32},srcline={27}}{5C3337365C3337375C303030445C303030695C303030655C3030305C3034305C303030645C303030725C303030655C303030695C3030305C3034305C303030445C3030306F5C303030635C3030306B5C303030655C303030725C303030665C303030695C3030306C5C303030655C303030735C3030305C3034305C303030695C3030306D5C3030305C3034305C303030445C303030655C303030745C303030615C303030695C3030306C}
\BKM@entry{id=23,dest={73756273756273656374696F6E2E332E322E31},srcline={29}}{5C3337365C3337375C303030425C303030615C303030635C3030306B5C303030655C3030306E5C303030645C3030302D5C303030445C3030306F5C303030635C3030306B5C303030655C303030725C303030665C303030695C3030306C5C303030655C3030303A5C3030305C3034305C303030615C303030705C303030705C303030735C3030302F5C303030615C303030705C303030695C3030302F5C303030445C3030306F5C303030635C3030306B5C303030655C303030725C303030665C303030695C3030306C5C30303065}
\@writefile{toc}{\contentsline {section}{\numberline {3}Docker-Images bauen und App deployen}{13}{section.3}\protected@file@percent }
\newlabel{sec:step03}{{3}{13}{Docker-Images bauen und App deployen}{section.3}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.1}Was ist Docker und warum nutzen wir es?}{13}{subsection.3.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.2}Die drei Dockerfiles im Detail}{13}{subsection.3.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.2.1}Backend-Dockerfile: \texttt {apps/api/Dockerfile}}{13}{subsubsection.3.2.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {24}Dockerfile für das .NET Backend}{13}{lstlisting.24}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {3}Docker-Images bauen und App deployen}{14}{section.3}\protected@file@percent }
\newlabel{sec:step03}{{3}{14}{Docker-Images bauen und App deployen}{section.3}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.1}Was ist Docker und warum nutzen wir es?}{14}{subsection.3.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.2}Die drei Dockerfiles im Detail}{14}{subsection.3.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.2.1}Backend-Dockerfile: \texttt {apps/api/Dockerfile}}{14}{subsubsection.3.2.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {24}Dockerfile für das .NET Backend}{14}{lstlisting.24}\protected@file@percent }
\BKM@entry{id=24,dest={73756273756273656374696F6E2E332E322E32},srcline={64}}{5C3337365C3337375C303030465C303030725C3030306F5C3030306E5C303030745C303030655C3030306E5C303030645C3030302D5C303030445C3030306F5C303030635C3030306B5C303030655C303030725C303030665C303030695C3030306C5C303030655C3030303A5C3030305C3034305C303030615C303030705C303030705C303030735C3030302F5C303030775C303030655C303030625C3030302F5C303030445C3030306F5C303030635C3030306B5C303030655C303030725C303030665C303030695C3030306C5C30303065}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.2.2}Frontend-Dockerfile: \texttt {apps/web/Dockerfile}}{14}{subsubsection.3.2.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {25}Dockerfile für das React Frontend}{14}{lstlisting.25}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.2.2}Frontend-Dockerfile: \texttt {apps/web/Dockerfile}}{15}{subsubsection.3.2.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {25}Dockerfile für das React Frontend}{15}{lstlisting.25}\protected@file@percent }
\BKM@entry{id=25,dest={73756273756273656374696F6E2E332E322E33},srcline={99}}{5C3337365C3337375C3030304E5C303030675C303030695C3030306E5C303030785C3030302D5C3030304B5C3030306F5C3030306E5C303030665C303030695C303030675C303030755C303030725C303030615C303030745C303030695C3030306F5C3030306E5C3030303A5C3030305C3034305C303030615C303030705C303030705C303030735C3030302F5C303030775C303030655C303030625C3030302F5C3030306E5C303030675C303030695C3030306E5C303030785C3030302E5C303030635C3030306F5C3030306E5C30303066}
\BKM@entry{id=26,dest={73756273656374696F6E2E332E33},srcline={130}}{5C3337365C3337375C303030445C303030615C303030735C3030305C3034305C303030425C303030615C303030635C3030306B5C303030655C3030306E5C303030645C3030303A5C3030305C3034305C303030505C303030725C3030306F5C303030675C303030725C303030615C3030306D5C3030302E5C303030635C303030735C3030305C3034305C303030695C3030306D5C3030305C3034305C303030445C303030655C303030745C303030615C303030695C3030306C}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.2.3}Nginx-Konfiguration: \texttt {apps/web/nginx.conf}}{15}{subsubsection.3.2.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {26}Nginx-Konfiguration mit Reverse Proxy}{15}{lstlisting.26}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.3}Das Backend: Program.cs im Detail}{16}{subsection.3.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {27}Vollständige Program.cs}{16}{lstlisting.27}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.2.3}Nginx-Konfiguration: \texttt {apps/web/nginx.conf}}{16}{subsubsection.3.2.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {26}Nginx-Konfiguration mit Reverse Proxy}{16}{lstlisting.26}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.3}Das Backend: Program.cs im Detail}{17}{subsection.3.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {27}Vollständige Program.cs}{17}{lstlisting.27}\protected@file@percent }
\BKM@entry{id=27,dest={73756273656374696F6E2E332E34},srcline={186}}{5C3337365C3337375C303030445C303030655C303030725C3030305C3034305C303030415C303030505C303030495C3030302D5C303030435C3030306C5C303030695C303030655C3030306E5C303030745C3030303A5C3030305C3034305C303030635C3030306C5C303030695C303030655C3030306E5C303030745C3030302E5C303030745C303030735C3030305C3034305C303030695C3030306D5C3030305C3034305C303030445C303030655C303030745C303030615C303030695C3030306C}
\BKM@entry{id=28,dest={73756273656374696F6E2E332E35},srcline={226}}{5C3337365C3337375C303030445C303030615C303030735C3030305C3034305C303030465C303030725C3030306F5C3030306E5C303030745C303030655C3030306E5C303030645C3030303A5C3030305C3034305C303030415C303030705C303030705C3030302E5C303030745C303030735C303030785C3030305C3034305C303030695C3030306D5C3030305C3034305C303030445C303030655C303030745C303030615C303030695C3030306C}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.4}Der API-Client: client.ts im Detail}{17}{subsection.3.4}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {28}Manueller API-Client}{17}{lstlisting.28}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.5}Das Frontend: App.tsx im Detail}{17}{subsection.3.5}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {29}Hauptkomponente mit Workout-Liste und Formular}{17}{lstlisting.29}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.4}Der API-Client: client.ts im Detail}{18}{subsection.3.4}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {28}Manueller API-Client}{18}{lstlisting.28}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.5}Das Frontend: App.tsx im Detail}{18}{subsection.3.5}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {29}Hauptkomponente mit Workout-Liste und Formular}{18}{lstlisting.29}\protected@file@percent }
\BKM@entry{id=29,dest={73756273656374696F6E2E332E36},srcline={265}}{5C3337365C3337375C303030495C3030306D5C303030615C303030675C303030655C303030735C3030305C3034305C303030625C303030615C303030755C303030655C3030306E}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.6}Images bauen}{18}{subsection.3.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.6}Images bauen}{19}{subsection.3.6}\protected@file@percent }
\BKM@entry{id=30,dest={73756273656374696F6E2E332E37},srcline={287}}{5C3337365C3337375C303030495C3030306D5C303030615C303030675C303030655C303030735C3030305C3034305C303030655C303030785C303030705C3030306F5C303030725C303030745C303030695C303030655C303030725C303030655C3030306E5C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030615C303030755C303030665C3030305C3034305C303030645C303030655C3030306E5C3030305C3034305C303030535C303030655C303030725C303030765C303030655C303030725C3030305C3034305C3030306B5C3030306F5C303030705C303030695C303030655C303030725C303030655C3030306E}
\BKM@entry{id=31,dest={73756273656374696F6E2E332E38},srcline={311}}{5C3337365C3337375C303030435C3030306F5C3030306E5C303030745C303030615C303030695C3030306E5C303030655C303030725C3030305C3034305C303030615C303030755C303030665C3030305C3034305C303030645C303030655C3030306D5C3030305C3034305C303030535C303030655C303030725C303030765C303030655C303030725C3030305C3034305C303030735C303030745C303030615C303030725C303030745C303030655C3030306E}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.7}Images exportieren und auf den Server kopieren}{19}{subsection.3.7}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {30}Images exportieren und kopieren}{19}{lstlisting.30}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.8}Container auf dem Server starten}{19}{subsection.3.8}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {31}Docker-Netzwerk, Volume und Container anlegen}{19}{lstlisting.31}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.7}Images exportieren und auf den Server kopieren}{20}{subsection.3.7}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {30}Images exportieren und kopieren}{20}{lstlisting.30}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.8}Container auf dem Server starten}{20}{subsection.3.8}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {31}Docker-Netzwerk, Volume und Container anlegen}{20}{lstlisting.31}\protected@file@percent }
\BKM@entry{id=32,dest={73756273656374696F6E2E332E39},srcline={345}}{5C3337365C3337375C303030415C303030755C303030665C303030675C303030655C303030745C303030725C303030655C303030745C303030655C3030306E5C303030655C3030305C3034305C303030505C303030725C3030306F5C303030625C3030306C5C303030655C3030306D5C303030655C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C3030304C5C3030305C3336365C303030735C303030755C3030306E5C303030675C303030655C3030306E}
\BKM@entry{id=33,dest={73756273656374696F6E2E332E3130},srcline={372}}{5C3337365C3337375C3030305A5C303030755C303030735C303030615C3030306D5C3030306D5C303030655C3030306E5C303030665C303030615C303030735C303030735C303030755C3030306E5C30303067}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.9}Aufgetretene Probleme und Lösungen}{20}{subsection.3.9}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.9}Aufgetretene Probleme und Lösungen}{21}{subsection.3.9}\protected@file@percent }
\BKM@entry{id=34,dest={73656374696F6E2E34},srcline={5}}{5C3337365C3337375C303030445C3030306F5C3030306D5C303030615C303030695C3030306E5C3030305C3034305C3030306B5C303030615C303030755C303030665C303030655C3030306E5C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030445C3030304E5C303030535C3030305C3034305C3030306B5C3030306F5C3030306E5C303030665C303030695C303030675C303030755C303030725C303030695C303030655C303030725C303030655C3030306E}
\BKM@entry{id=35,dest={73756273656374696F6E2E342E31},srcline={10}}{5C3337365C3337375C303030575C303030615C303030725C303030755C3030306D5C3030305C3034305C303030655C303030695C3030306E5C303030655C3030305C3034305C303030655C303030695C303030675C303030655C3030306E5C303030655C3030305C3034305C303030445C3030306F5C3030306D5C303030615C303030695C3030306E5C3030303F}
\BKM@entry{id=36,dest={73756273656374696F6E2E342E32},srcline={21}}{5C3337365C3337375C303030475C303030725C303030755C3030306E5C303030645C3030306C5C303030615C303030675C303030655C3030306E5C3030303A5C3030305C3034305C303030575C303030695C303030655C3030305C3034305C303030665C303030755C3030306E5C3030306B5C303030745C303030695C3030306F5C3030306E5C303030695C303030655C303030725C303030745C3030305C3034305C303030645C303030615C303030735C3030305C3034305C303030445C3030304E5C303030535C3030303F}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.10}Zusammenfassung}{21}{subsection.3.10}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {4}Domain kaufen und DNS konfigurieren}{21}{section.4}\protected@file@percent }
\newlabel{sec:step04}{{4}{21}{Domain kaufen und DNS konfigurieren}{section.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1}Warum eine eigene Domain?}{21}{subsection.4.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2}Grundlagen: Wie funktioniert das DNS?}{21}{subsection.4.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.10}Zusammenfassung}{22}{subsection.3.10}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {4}Domain kaufen und DNS konfigurieren}{22}{section.4}\protected@file@percent }
\newlabel{sec:step04}{{4}{22}{Domain kaufen und DNS konfigurieren}{section.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1}Warum eine eigene Domain?}{22}{subsection.4.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2}Grundlagen: Wie funktioniert das DNS?}{22}{subsection.4.2}\protected@file@percent }
\BKM@entry{id=37,dest={73756273656374696F6E2E342E33},srcline={54}}{5C3337365C3337375C303030575C303030615C303030735C3030305C3034305C303030695C303030735C303030745C3030305C3034305C303030445C3030304E5C303030535C3030302D5C303030505C303030725C3030306F5C303030705C303030615C303030675C303030615C303030745C303030695C3030306F5C3030306E5C3030303F}
\BKM@entry{id=38,dest={73756273656374696F6E2E342E34},srcline={66}}{5C3337365C3337375C303030445C3030306F5C3030306D5C303030615C303030695C3030306E5C3030302D5C3030304B5C303030615C303030755C303030665C3030305C3034305C303030625C303030655C303030695C3030305C3034305C303030435C3030306F5C3030306E5C303030745C303030615C303030625C3030306F}
\BKM@entry{id=39,dest={73756273756273656374696F6E2E342E342E31},srcline={68}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030315C3030303A5C3030305C3034305C303030455C303030695C3030306E5C3030306C5C3030306F5C303030675C303030675C303030655C3030306E5C3030305C3034305C303030695C3030306E5C303030735C3030305C3034305C3030304B5C303030755C3030306E5C303030645C303030655C3030306E5C303030635C303030655C3030306E5C303030745C303030655C30303072}
\BKM@entry{id=40,dest={73756273756273656374696F6E2E342E342E32},srcline={71}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030325C3030303A5C3030305C3034305C303030445C3030306F5C3030306D5C303030615C303030695C3030306E5C3030305C3034305C303030625C303030655C303030735C303030745C303030655C3030306C5C3030306C5C303030655C3030306E}
\@writefile{lot}{\contentsline {table}{\numberline {3}{\ignorespaces DNS-Record-Typen und ihre Funktion}}{22}{table.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3}Was ist DNS-Propagation?}{22}{subsection.4.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4}Domain-Kauf bei Contabo}{22}{subsection.4.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.4.1}Schritt 1: Einloggen ins Kundencenter}{22}{subsubsection.4.4.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.4.2}Schritt 2: Domain bestellen}{22}{subsubsection.4.4.2}\protected@file@percent }
\@writefile{lot}{\contentsline {table}{\numberline {3}{\ignorespaces DNS-Record-Typen und ihre Funktion}}{23}{table.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3}Was ist DNS-Propagation?}{23}{subsection.4.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4}Domain-Kauf bei Contabo}{23}{subsection.4.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.4.1}Schritt 1: Einloggen ins Kundencenter}{23}{subsubsection.4.4.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.4.2}Schritt 2: Domain bestellen}{23}{subsubsection.4.4.2}\protected@file@percent }
\BKM@entry{id=41,dest={73756273756273656374696F6E2E342E342E33},srcline={79}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030335C3030303A5C3030305C3034305C303030445C3030306F5C3030306D5C303030615C303030695C3030306E5C3030302D5C303030485C303030615C3030306E5C303030645C3030306C5C303030655C303030735C3030305C3034305C3030306B5C3030306F5C3030306E5C303030665C303030695C303030675C303030755C303030725C303030695C303030655C303030725C303030655C3030306E}
\BKM@entry{id=42,dest={73756273756273656374696F6E2E342E342E34},srcline={91}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030345C3030303A5C3030305C3034305C3030304E5C303030615C3030306D5C303030655C303030735C303030655C303030725C303030765C303030655C303030725C3030305C3034305C303030665C303030655C303030735C303030745C3030306C5C303030655C303030675C303030655C3030306E}
\BKM@entry{id=43,dest={73756273756273656374696F6E2E342E342E35},srcline={99}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030355C3030303A5C3030305C3034305C303030495C303030505C3030302D5C303030415C303030645C303030725C303030655C303030735C303030735C303030655C3030305C3034305C303030615C303030755C303030735C303030775C3030305C3334345C303030685C3030306C5C303030655C3030306E}
@@ -133,56 +133,56 @@
\BKM@entry{id=45,dest={73756273656374696F6E2E342E35},srcline={112}}{5C3337365C3337375C303030445C3030304E5C303030535C3030302D5C303030455C303030695C3030306E5C303030745C303030725C3030305C3334345C303030675C303030655C3030305C3034305C303030665C3030305C3337345C303030725C3030305C3034305C303030645C303030695C303030655C3030305C3034305C303030445C3030306F5C3030306D5C303030615C303030695C3030306E5C3030305C3034305C303030655C303030695C3030306E5C303030725C303030695C303030635C303030685C303030745C303030655C3030306E}
\BKM@entry{id=46,dest={73756273756273656374696F6E2E342E352E31},srcline={116}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030315C3030303A5C3030305C3034305C303030445C3030304E5C303030535C3030305C3034305C3030305A5C3030306F5C3030306E5C303030655C3030305C3034305C3030304D5C303030615C3030306E5C303030615C303030675C303030655C3030306D5C303030655C3030306E5C303030745C3030305C3034305C3030305C3336365C303030665C303030665C3030306E5C303030655C3030306E}
\BKM@entry{id=47,dest={73756273756273656374696F6E2E342E352E32},srcline={119}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030325C3030303A5C3030305C3034305C3030304E5C3030306F5C303030745C303030775C303030655C3030306E5C303030645C303030695C303030675C303030655C3030305C3034305C303030415C3030302D5C303030525C303030655C303030635C3030306F5C303030725C303030645C303030735C3030305C3034305C303030615C3030306E5C3030306C5C303030655C303030675C303030655C3030306E}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.4.3}Schritt 3: Domain-Handles konfigurieren}{23}{subsubsection.4.4.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.4.4}Schritt 4: Nameserver festlegen}{23}{subsubsection.4.4.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.4.5}Schritt 5: IP-Adresse auswählen}{23}{subsubsection.4.4.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.4.6}Schritt 6: Bestellung abschließen}{23}{subsubsection.4.4.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5}DNS-Einträge für die Domain einrichten}{23}{subsection.4.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.1}Schritt 1: DNS Zone Management öffnen}{23}{subsubsection.4.5.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.4.3}Schritt 3: Domain-Handles konfigurieren}{24}{subsubsection.4.4.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.4.4}Schritt 4: Nameserver festlegen}{24}{subsubsection.4.4.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.4.5}Schritt 5: IP-Adresse auswählen}{24}{subsubsection.4.4.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.4.6}Schritt 6: Bestellung abschließen}{24}{subsubsection.4.4.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5}DNS-Einträge für die Domain einrichten}{24}{subsection.4.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.1}Schritt 1: DNS Zone Management öffnen}{24}{subsubsection.4.5.1}\protected@file@percent }
\BKM@entry{id=48,dest={73756273656374696F6E2E342E36},srcline={155}}{5C3337365C3337375C303030445C3030304E5C303030535C3030302D5C303030505C303030725C3030306F5C303030705C303030615C303030675C303030615C303030745C303030695C3030306F5C3030306E5C3030305C3034305C303030705C303030725C3030305C3337345C303030665C303030655C3030306E5C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030625C303030655C303030735C303030635C303030685C3030306C5C303030655C303030755C3030306E5C303030695C303030675C303030655C3030306E}
\BKM@entry{id=49,dest={73756273756273656374696F6E2E342E362E31},srcline={157}}{5C3337365C3337375C303030445C303030695C303030725C303030655C3030306B5C303030745C3030305C3034305C303030625C303030655C303030695C3030306D5C3030305C3034305C3030304E5C303030615C3030306D5C303030655C303030735C303030655C303030725C303030765C303030655C303030725C3030305C3034305C303030705C303030725C3030305C3337345C303030665C303030655C3030306E}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.2}Schritt 2: Notwendige A-Records anlegen}{24}{subsubsection.4.5.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.6}DNS-Propagation prüfen und beschleunigen}{24}{subsection.4.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.6.1}Direkt beim Nameserver prüfen}{24}{subsubsection.4.6.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {32}DNS direkt bei Contabo abfragen}{24}{lstlisting.32}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.2}Schritt 2: Notwendige A-Records anlegen}{25}{subsubsection.4.5.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.6}DNS-Propagation prüfen und beschleunigen}{25}{subsection.4.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.6.1}Direkt beim Nameserver prüfen}{25}{subsubsection.4.6.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {32}DNS direkt bei Contabo abfragen}{25}{lstlisting.32}\protected@file@percent }
\BKM@entry{id=50,dest={73756273756273656374696F6E2E342E362E32},srcline={173}}{5C3337365C3337375C3030304C5C3030306F5C3030306B5C303030615C3030306C5C303030655C3030306E5C3030305C3034305C303030445C3030304E5C303030535C3030302D5C303030435C303030615C303030635C303030685C303030655C3030305C3034305C3030306C5C303030655C303030655C303030725C303030655C3030306E}
\BKM@entry{id=51,dest={73756273756273656374696F6E2E342E362E33},srcline={180}}{5C3337365C3337375C303030535C303030655C303030725C303030765C303030655C303030725C3030305C3034305C303030645C303030695C303030725C303030655C3030306B5C303030745C3030305C3034305C3030305C3337345C303030625C303030655C303030725C3030305C3034305C303030495C303030505C3030305C3034305C303030705C303030725C3030305C3337345C303030665C303030655C3030306E}
\BKM@entry{id=52,dest={73756273756273656374696F6E2E342E362E34},srcline={197}}{5C3337365C3337375C3030304F5C3030306E5C3030306C5C303030695C3030306E5C303030655C3030305C3034305C303030445C3030304E5C303030535C3030302D5C303030435C303030685C303030655C303030635C3030306B5C303030655C303030725C3030305C3034305C303030765C303030655C303030725C303030775C303030655C3030306E5C303030645C303030655C3030306E}
\BKM@entry{id=53,dest={73756273656374696F6E2E342E37},srcline={200}}{5C3337365C3337375C3030305A5C303030755C303030735C303030615C3030306D5C3030306D5C303030655C3030306E5C303030665C303030615C303030735C303030735C303030755C3030306E5C30303067}
\BKM@entry{id=54,dest={73656374696F6E2E35},srcline={2}}{5C3337365C3337375C303030485C303030545C303030545C303030505C303030535C3030305C3034305C3030306D5C303030695C303030745C3030305C3034305C3030306E5C303030675C303030695C3030306E5C303030785C3030302D5C303030705C303030725C3030306F5C303030785C303030795C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C3030304C5C303030655C303030745C303030275C303030735C3030305C3034305C303030455C3030306E5C303030635C303030725C303030795C303030705C30303074}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {33}Erwartete Ausgabe}{25}{lstlisting.33}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.6.2}Lokalen DNS-Cache leeren}{25}{subsubsection.4.6.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {34}DNS-Cache leeren unter Linux mit systemd-resolved}{25}{lstlisting.34}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.6.3}Server direkt über IP prüfen}{25}{subsubsection.4.6.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {35}Server direkt über IP testen}{25}{lstlisting.35}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {36}Server antwortet korrekt}{25}{lstlisting.36}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.6.4}Online DNS-Checker verwenden}{25}{subsubsection.4.6.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.7}Zusammenfassung}{25}{subsection.4.7}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {33}Erwartete Ausgabe}{26}{lstlisting.33}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.6.2}Lokalen DNS-Cache leeren}{26}{subsubsection.4.6.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {34}DNS-Cache leeren unter Linux mit systemd-resolved}{26}{lstlisting.34}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.6.3}Server direkt über IP prüfen}{26}{subsubsection.4.6.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {35}Server direkt über IP testen}{26}{lstlisting.35}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {36}Server antwortet korrekt}{26}{lstlisting.36}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.6.4}Online DNS-Checker verwenden}{26}{subsubsection.4.6.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.7}Zusammenfassung}{26}{subsection.4.7}\protected@file@percent }
\BKM@entry{id=55,dest={73756273656374696F6E2E352E31},srcline={7}}{5C3337365C3337375C303030575C303030615C303030725C303030755C3030306D5C3030305C3034305C303030625C303030725C303030615C303030755C303030635C303030685C303030655C3030306E5C3030305C3034305C303030775C303030695C303030725C3030305C3034305C303030485C303030545C303030545C303030505C303030535C3030303F}
\BKM@entry{id=56,dest={73756273656374696F6E2E352E32},srcline={18}}{5C3337365C3337375C303030575C303030695C303030655C3030305C3034305C303030665C303030755C3030306E5C3030306B5C303030745C303030695C3030306F5C3030306E5C303030695C303030655C303030725C303030745C3030305C3034305C303030645C303030615C303030735C3030305C3034305C303030535C303030535C3030304C5C3030302D5C3030305A5C303030655C303030725C303030745C303030695C303030665C303030695C3030306B5C303030615C303030745C3030305C3034305C303030765C3030306F5C3030306E5C3030305C3034305C3030304C5C303030655C303030745C303030275C303030735C3030305C3034305C303030455C3030306E5C303030635C303030725C303030795C303030705C303030745C3030303F}
\BKM@entry{id=57,dest={73756273656374696F6E2E352E33},srcline={33}}{5C3337365C3337375C303030445C3030304E5C303030535C3030302D5C303030505C303030725C3030306F5C303030705C303030615C303030675C303030615C303030745C303030695C3030306F5C3030306E5C3030303A5C3030305C3034305C303030575C303030695C303030655C3030305C3034305C3030306C5C303030615C3030306E5C303030675C303030655C3030305C3034305C303030645C303030615C303030755C303030655C303030725C303030745C3030305C3034305C303030655C303030735C3030303F}
\@writefile{toc}{\contentsline {section}{\numberline {5}HTTPS mit nginx-proxy und Let's Encrypt}{26}{section.5}\protected@file@percent }
\newlabel{sec:step05}{{5}{26}{HTTPS mit nginx-proxy und Let's Encrypt}{section.5}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.1}Warum brauchen wir HTTPS?}{26}{subsection.5.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.2}Wie funktioniert das SSL-Zertifikat von Let's Encrypt?}{26}{subsection.5.2}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {5}HTTPS mit nginx-proxy und Let's Encrypt}{27}{section.5}\protected@file@percent }
\newlabel{sec:step05}{{5}{27}{HTTPS mit nginx-proxy und Let's Encrypt}{section.5}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.1}Warum brauchen wir HTTPS?}{27}{subsection.5.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.2}Wie funktioniert das SSL-Zertifikat von Let's Encrypt?}{27}{subsection.5.2}\protected@file@percent }
\BKM@entry{id=58,dest={73756273656374696F6E2E352E34},srcline={60}}{5C3337365C3337375C303030415C303030725C303030635C303030685C303030695C303030745C303030655C3030306B5C303030745C303030755C303030725C3030303A5C3030305C3034305C303030575C303030695C303030655C3030305C3034305C303030685C3030305C3334345C3030306E5C303030675C303030655C3030306E5C3030305C3034305C303030645C303030695C303030655C3030305C3034305C303030435C3030306F5C3030306E5C303030745C303030615C303030695C3030306E5C303030655C303030725C3030305C3034305C3030307A5C303030755C303030735C303030615C3030306D5C3030306D5C303030655C3030306E5C3030303F}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.3}DNS-Propagation: Wie lange dauert es?}{27}{subsection.5.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {37}DNS-Auflösung lokal prüfen}{27}{lstlisting.37}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.4}Architektur: Wie hängen die Container zusammen?}{27}{subsection.5.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.3}DNS-Propagation: Wie lange dauert es?}{28}{subsection.5.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {37}DNS-Auflösung lokal prüfen}{28}{lstlisting.37}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.4}Architektur: Wie hängen die Container zusammen?}{28}{subsection.5.4}\protected@file@percent }
\BKM@entry{id=59,dest={73756273656374696F6E2E352E35},srcline={86}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030302D5C303030665C3030305C3337345C303030725C3030302D5C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030303A5C3030305C3034305C303030485C303030545C303030545C303030505C303030535C3030305C3034305C303030655C303030695C3030306E5C303030725C303030695C303030635C303030685C303030745C303030655C3030306E}
\BKM@entry{id=60,dest={73756273756273656374696F6E2E352E352E31},srcline={88}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030315C3030303A5C3030305C3034305C303030425C303030655C303030735C303030745C303030655C303030685C303030655C3030306E5C303030645C303030655C3030305C3034305C303030435C3030306F5C3030306E5C303030745C303030615C303030695C3030306E5C303030655C303030725C3030305C3034305C303030735C303030745C3030306F5C303030705C303030705C303030655C3030306E5C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C3030306C5C3030305C3336365C303030735C303030635C303030685C303030655C3030306E}
\BKM@entry{id=61,dest={73756273756273656374696F6E2E352E352E32},srcline={98}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030325C3030303A5C3030305C3034305C303030565C303030655C303030725C3030307A5C303030655C303030695C303030635C303030685C3030306E5C303030695C303030735C3030305C3034305C303030665C3030305C3337345C303030725C3030305C3034305C303030645C3030306F5C303030635C3030306B5C303030655C303030725C3030302D5C303030635C3030306F5C3030306D5C303030705C3030306F5C303030735C303030655C3030305C3034305C303030615C3030306E5C3030306C5C303030655C303030675C303030655C3030306E}
\BKM@entry{id=62,dest={73756273756273656374696F6E2E352E352E33},srcline={105}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030335C3030303A5C3030305C3034305C303030645C3030306F5C303030635C3030306B5C303030655C303030725C3030302D5C303030635C3030306F5C3030306D5C303030705C3030306F5C303030735C303030655C3030302E5C303030795C3030306D5C3030306C5C3030305C3034305C303030655C303030725C303030735C303030745C303030655C3030306C5C3030306C5C303030655C3030306E}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.5}Schritt-für-Schritt: HTTPS einrichten}{28}{subsection.5.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.1}Schritt 1: Bestehende Container stoppen und löschen}{28}{subsubsection.5.5.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {38}Alte Container stoppen und löschen}{28}{lstlisting.38}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.2}Schritt 2: Verzeichnis für docker-compose anlegen}{28}{subsubsection.5.5.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {39}Projektverzeichnis auf dem Server}{28}{lstlisting.39}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.3}Schritt 3: docker-compose.yml erstellen}{28}{subsubsection.5.5.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {40}Vollständige docker-compose.yml}{28}{lstlisting.40}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{\nonumberline nginx-proxy}{30}{paragraph*.3}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{\nonumberline acme-companion}{30}{paragraph*.5}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{\nonumberline frontend (entscheidende Umgebungsvariablen!)}{30}{paragraph*.7}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.5}Schritt-für-Schritt: HTTPS einrichten}{29}{subsection.5.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.1}Schritt 1: Bestehende Container stoppen und löschen}{29}{subsubsection.5.5.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {38}Alte Container stoppen und löschen}{29}{lstlisting.38}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.2}Schritt 2: Verzeichnis für docker-compose anlegen}{29}{subsubsection.5.5.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {39}Projektverzeichnis auf dem Server}{29}{lstlisting.39}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.3}Schritt 3: docker-compose.yml erstellen}{29}{subsubsection.5.5.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {40}Vollständige docker-compose.yml}{29}{lstlisting.40}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{\nonumberline nginx-proxy}{31}{paragraph*.3}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{\nonumberline acme-companion}{31}{paragraph*.5}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{\nonumberline frontend (entscheidende Umgebungsvariablen!)}{31}{paragraph*.7}\protected@file@percent }
\BKM@entry{id=63,dest={73756273756273656374696F6E2E352E352E34},srcline={228}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030345C3030303A5C3030305C3034305C303030435C3030306F5C3030306E5C303030745C303030615C303030695C3030306E5C303030655C303030725C3030305C3034305C303030735C303030745C303030615C303030725C303030745C303030655C3030306E}
\BKM@entry{id=64,dest={73756273756273656374696F6E2E352E352E35},srcline={237}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030355C3030303A5C3030305C3034305C303030535C303030745C303030615C303030745C303030755C303030735C3030305C3034305C303030705C303030725C3030305C3337345C303030665C303030655C3030306E}
\BKM@entry{id=65,dest={73756273756273656374696F6E2E352E352E36},srcline={245}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030365C3030303A5C3030305C3034305C3030304C5C3030306F5C303030675C303030735C3030305C3034305C303030645C303030655C303030735C3030305C3034305C303030615C303030635C3030306D5C303030655C3030302D5C303030635C3030306F5C3030306D5C303030705C303030615C3030306E5C303030695C3030306F5C3030306E5C3030305C3034305C303030705C303030725C3030305C3337345C303030665C303030655C3030306E}
@@ -190,80 +190,152 @@
\BKM@entry{id=67,dest={73756273756273656374696F6E2E352E362E31},srcline={260}}{5C3337365C3337375C303030465C303030655C303030685C3030306C5C303030655C303030725C3030305C3034305C303030315C3030303A5C3030305C3034305C303030275C303030275C303030635C303030615C3030306E5C303030275C303030745C3030305C3034305C303030675C303030655C303030745C3030305C3034305C3030306E5C303030675C303030695C3030306E5C303030785C3030302D5C303030705C303030725C3030306F5C303030785C303030795C3030305C3034305C303030635C3030306F5C3030306E5C303030745C303030615C303030695C3030306E5C303030655C303030725C3030305C3034305C303030495C303030445C303030275C30303027}
\BKM@entry{id=68,dest={73756273756273656374696F6E2E352E362E32},srcline={266}}{5C3337365C3337375C303030465C303030655C303030685C3030306C5C303030655C303030725C3030305C3034305C303030325C3030303A5C3030305C3034305C303030275C303030275C303030635C3030306F5C3030306E5C303030745C303030615C303030635C303030745C3030305C3034305C303030655C3030306D5C303030615C303030695C3030306C5C3030305C3034305C303030685C303030615C303030735C3030305C3034305C303030665C3030306F5C303030725C303030625C303030695C303030645C303030645C303030655C3030306E5C3030305C3034305C303030645C3030306F5C3030306D5C303030615C303030695C3030306E5C303030275C30303027}
\BKM@entry{id=69,dest={73756273756273656374696F6E2E352E362E33},srcline={272}}{5C3337365C3337375C303030465C303030655C303030685C3030306C5C303030655C303030725C3030305C3034305C303030335C3030303A5C3030305C3034305C303030275C303030275C303030445C3030304E5C303030535C3030305C3034305C303030705C303030725C3030306F5C303030625C3030306C5C303030655C3030306D5C3030303A5C3030305C3034305C3030304E5C303030585C303030445C3030304F5C3030304D5C303030415C303030495C3030304E5C303030275C30303027}
\@writefile{toc}{\contentsline {paragraph}{\nonumberline Docker Volumes}{31}{paragraph*.9}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.4}Schritt 4: Container starten}{31}{subsubsection.5.5.4}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {41}Alle Container im Hintergrund starten}{31}{lstlisting.41}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.5}Schritt 5: Status prüfen}{31}{subsubsection.5.5.5}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {42}Laufende Container anzeigen}{31}{lstlisting.42}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.6}Schritt 6: Logs des acme-companion prüfen}{31}{subsubsection.5.5.6}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {43}SSL-Zertifikatserstellung verfolgen}{31}{lstlisting.43}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {44}Erfolgreiche Ausgabe}{31}{lstlisting.44}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.6}Häufige Fehler und ihre Behebung}{31}{subsection.5.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.6.1}Fehler 1: ''can't get nginx-proxy container ID''}{31}{subsubsection.5.6.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.6.2}Fehler 2: ''contact email has forbidden domain''}{31}{subsubsection.5.6.2}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{\nonumberline Docker Volumes}{32}{paragraph*.9}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.4}Schritt 4: Container starten}{32}{subsubsection.5.5.4}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {41}Alle Container im Hintergrund starten}{32}{lstlisting.41}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.5}Schritt 5: Status prüfen}{32}{subsubsection.5.5.5}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {42}Laufende Container anzeigen}{32}{lstlisting.42}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.6}Schritt 6: Logs des acme-companion prüfen}{32}{subsubsection.5.5.6}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {43}SSL-Zertifikatserstellung verfolgen}{32}{lstlisting.43}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {44}Erfolgreiche Ausgabe}{32}{lstlisting.44}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.6}Häufige Fehler und ihre Behebung}{32}{subsection.5.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.6.1}Fehler 1: ''can't get nginx-proxy container ID''}{32}{subsubsection.5.6.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.6.2}Fehler 2: ''contact email has forbidden domain''}{32}{subsubsection.5.6.2}\protected@file@percent }
\BKM@entry{id=70,dest={73756273656374696F6E2E352E37},srcline={282}}{5C3337365C3337375C303030575C303030695C303030655C3030305C3034305C303030665C3030305C3337345C303030675C303030655C3030305C3034305C303030695C303030635C303030685C3030305C3034305C303030735C303030705C3030305C3334345C303030745C303030655C303030725C3030305C3034305C303030775C303030655C303030695C303030745C303030655C303030725C303030655C3030305C3034305C303030535C303030755C303030625C303030645C3030306F5C3030306D5C303030615C303030695C3030306E5C303030735C3030305C3034305C303030685C303030695C3030306E5C3030307A5C303030755C3030303F}
\BKM@entry{id=71,dest={73756273656374696F6E2E352E38},srcline={294}}{5C3337365C3337375C303030575C303030695C303030655C3030305C3034305C303030665C303030755C3030306E5C3030306B5C303030745C303030695C3030306F5C3030306E5C303030695C303030655C303030725C303030745C3030305C3034305C303030645C303030655C303030725C3030305C3034305C303030525C303030655C303030765C303030655C303030725C303030735C303030655C3030305C3034305C303030505C303030725C3030306F5C303030785C303030795C3030305C3034305C303030695C3030306D5C3030305C3034305C303030445C303030655C303030745C303030615C303030695C3030306C5C3030303F}
\BKM@entry{id=72,dest={73756273656374696F6E2E352E39},srcline={311}}{5C3337365C3337375C3030305A5C303030755C303030735C303030615C3030306D5C3030306D5C303030655C3030306E5C303030665C303030615C303030735C303030735C303030755C3030306E5C30303067}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.6.3}Fehler 3: ''DNS problem: NXDOMAIN''}{32}{subsubsection.5.6.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {45}Zertifikatserstellung erneut anstoßen}{32}{lstlisting.45}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.7}Wie füge ich später weitere Subdomains hinzu?}{32}{subsection.5.7}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.8}Wie funktioniert der Reverse Proxy im Detail?}{32}{subsection.5.8}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.6.3}Fehler 3: ''DNS problem: NXDOMAIN''}{33}{subsubsection.5.6.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {45}Zertifikatserstellung erneut anstoßen}{33}{lstlisting.45}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.7}Wie füge ich später weitere Subdomains hinzu?}{33}{subsection.5.7}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.8}Wie funktioniert der Reverse Proxy im Detail?}{33}{subsection.5.8}\protected@file@percent }
\BKM@entry{id=73,dest={73656374696F6E2E36},srcline={5}}{5C3337365C3337375C303030475C303030695C303030745C303030655C303030615C3030305C3034305C303030495C3030306E5C303030735C303030745C303030615C3030306C5C3030306C5C303030615C303030745C303030695C3030306F5C3030306E5C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030535C303030655C303030725C303030765C303030655C303030725C3030302D5C3030305C3333345C303030625C303030655C303030725C303030735C303030695C303030635C303030685C30303074}
\BKM@entry{id=74,dest={73756273656374696F6E2E362E31},srcline={10}}{5C3337365C3337375C303030575C303030615C303030725C303030755C3030306D5C3030305C3034305C303030655C303030695C3030306E5C3030305C3034305C303030655C303030695C303030675C303030655C3030306E5C303030655C303030725C3030305C3034305C303030475C303030695C303030745C3030302D5C303030535C303030655C303030725C303030765C303030655C303030725C3030303F}
\BKM@entry{id=75,dest={73756273656374696F6E2E362E32},srcline={21}}{5C3337365C3337375C3030304F5C3030306E5C303030655C303030445C303030655C303030765C3030303A5C3030305C3034305C303030445C303030655C303030725C3030305C3034305C303030675C303030655C303030735C303030635C303030685C303030655C303030695C303030745C303030655C303030725C303030745C303030655C3030305C3034305C303030565C303030655C303030725C303030735C303030755C303030635C30303068}
\BKM@entry{id=76,dest={73756273756273656374696F6E2E362E322E31},srcline={25}}{5C3337365C3337375C303030495C3030306E5C303030735C303030745C303030615C3030306C5C3030306C5C303030615C303030745C303030695C3030306F5C3030306E5C303030735C303030765C303030655C303030725C303030735C303030755C303030635C303030685C3030305C3034305C3030306D5C303030695C303030745C3030305C3034305C303030445C3030306F5C303030635C3030306B5C303030655C303030725C3030305C3034305C3030305C3035305C303030565C303030655C303030725C303030735C303030695C3030306F5C3030306E5C3030305C3034305C303030315C303030645C303030655C303030765C3030302F5C303030735C303030655C303030725C303030765C303030655C303030725C3030303A5C3030306C5C303030615C303030745C303030655C303030735C303030745C3030305C303531}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.9}Zusammenfassung}{33}{subsection.5.9}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {6}Gitea Installation und Server-Übersicht}{33}{section.6}\protected@file@percent }
\newlabel{sec:step06}{{6}{33}{Gitea Installation und Server-Übersicht}{section.6}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {6.1}Warum ein eigener Git-Server?}{33}{subsection.6.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.2}OneDev: Der gescheiterte Versuch}{33}{subsection.6.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.9}Zusammenfassung}{34}{subsection.5.9}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {6}Gitea Installation und Server-Übersicht}{34}{section.6}\protected@file@percent }
\newlabel{sec:step06}{{6}{34}{Gitea Installation und Server-Übersicht}{section.6}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {6.1}Warum ein eigener Git-Server?}{34}{subsection.6.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.2}OneDev: Der gescheiterte Versuch}{34}{subsection.6.2}\protected@file@percent }
\BKM@entry{id=77,dest={73756273656374696F6E2E362E33},srcline={64}}{5C3337365C3337375C303030475C303030695C303030745C303030655C303030615C3030303A5C3030305C3034305C303030445C303030695C303030655C3030305C3034305C303030735C303030635C303030685C3030306C5C303030615C3030306E5C3030306B5C303030655C3030305C3034305C303030415C3030306C5C303030745C303030655C303030725C3030306E5C303030615C303030745C303030695C303030765C30303065}
\BKM@entry{id=78,dest={73756273656374696F6E2E362E34},srcline={85}}{5C3337365C3337375C303030475C303030695C303030745C303030655C303030615C3030305C3034305C3030306D5C303030695C303030745C3030305C3034305C303030445C3030306F5C303030635C3030306B5C303030655C303030725C3030305C3034305C303030695C3030306E5C303030735C303030745C303030615C3030306C5C3030306C5C303030695C303030655C303030725C303030655C3030306E}
\BKM@entry{id=79,dest={73756273756273656374696F6E2E362E342E31},srcline={87}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030315C3030303A5C3030305C3034305C3030304F5C3030306E5C303030655C303030445C303030655C303030765C3030305C3034305C303030725C3030305C3337345C303030635C3030306B5C303030735C303030745C303030615C3030306E5C303030645C303030735C3030306C5C3030306F5C303030735C3030305C3034305C303030655C3030306E5C303030745C303030665C303030655C303030725C3030306E5C303030655C3030306E}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.2.1}Installationsversuch mit Docker (Version \texttt {1dev/server:latest})}{34}{subsubsection.6.2.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {46}docker-compose.yml für OneDev}{34}{lstlisting.46}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {47}Kritischer Fehler beim OneDev-Start}{34}{lstlisting.47}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.3}Gitea: Die schlanke Alternative}{34}{subsection.6.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.2.1}Installationsversuch mit Docker (Version \texttt {1dev/server:latest})}{35}{subsubsection.6.2.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {46}docker-compose.yml für OneDev}{35}{lstlisting.46}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {47}Kritischer Fehler beim OneDev-Start}{35}{lstlisting.47}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.3}Gitea: Die schlanke Alternative}{35}{subsection.6.3}\protected@file@percent }
\BKM@entry{id=80,dest={73756273756273656374696F6E2E362E342E32},srcline={107}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030325C3030303A5C3030305C3034305C303030475C303030695C303030745C303030655C303030615C3030302D5C303030565C303030655C303030725C3030307A5C303030655C303030695C303030635C303030685C3030306E5C303030695C303030735C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030645C3030306F5C303030635C3030306B5C303030655C303030725C3030302D5C303030635C3030306F5C3030306D5C303030705C3030306F5C303030735C303030655C3030302E5C303030795C3030306D5C3030306C5C3030305C3034305C303030615C3030306E5C3030306C5C303030655C303030675C303030655C3030306E}
\@writefile{lot}{\contentsline {table}{\numberline {4}{\ignorespaces Vergleich OneDev vs. Gitea}}{35}{table.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.4}Gitea mit Docker installieren}{35}{subsection.6.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.4.1}Schritt 1: OneDev rückstandslos entfernen}{35}{subsubsection.6.4.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {48}OneDev komplett löschen}{35}{lstlisting.48}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.4.2}Schritt 2: Gitea-Verzeichnis und docker-compose.yml anlegen}{35}{subsubsection.6.4.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {49}Gitea-Verzeichnis vorbereiten}{35}{lstlisting.49}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {50}docker-compose.yml für Gitea}{35}{lstlisting.50}\protected@file@percent }
\@writefile{lot}{\contentsline {table}{\numberline {4}{\ignorespaces Vergleich OneDev vs. Gitea}}{36}{table.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.4}Gitea mit Docker installieren}{36}{subsection.6.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.4.1}Schritt 1: OneDev rückstandslos entfernen}{36}{subsubsection.6.4.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {48}OneDev komplett löschen}{36}{lstlisting.48}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.4.2}Schritt 2: Gitea-Verzeichnis und docker-compose.yml anlegen}{36}{subsubsection.6.4.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {49}Gitea-Verzeichnis vorbereiten}{36}{lstlisting.49}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {50}docker-compose.yml für Gitea}{36}{lstlisting.50}\protected@file@percent }
\BKM@entry{id=81,dest={73756273756273656374696F6E2E362E342E33},srcline={141}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030335C3030303A5C3030305C3034305C303030435C3030306F5C3030306E5C303030745C303030615C303030695C3030306E5C303030655C303030725C3030305C3034305C303030735C303030745C303030615C303030725C303030745C303030655C3030306E}
\BKM@entry{id=82,dest={73756273756273656374696F6E2E362E342E34},srcline={157}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030345C3030303A5C3030305C3034305C303030465C303030695C303030725C303030655C303030775C303030615C3030306C5C3030306C5C3030305C3034305C3030305C3336365C303030665C303030665C3030306E5C303030655C3030306E}
\BKM@entry{id=83,dest={73756273756273656374696F6E2E362E342E35},srcline={163}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030355C3030303A5C3030305C3034305C303030475C303030695C303030745C303030655C303030615C3030305C3034305C303030695C3030306D5C3030305C3034305C303030425C303030725C3030306F5C303030775C303030735C303030655C303030725C3030305C3034305C303030655C303030695C3030306E5C303030725C303030695C303030635C303030685C303030745C303030655C3030306E}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.4.3}Schritt 3: Container starten}{36}{subsubsection.6.4.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {51}Gitea starten}{36}{lstlisting.51}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {52}Erfolgreicher Start}{36}{lstlisting.52}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.4.4}Schritt 4: Firewall öffnen}{36}{subsubsection.6.4.4}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {53}Port 3000 freigeben}{36}{lstlisting.53}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.4.5}Schritt 5: Gitea im Browser einrichten}{36}{subsubsection.6.4.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.4.3}Schritt 3: Container starten}{37}{subsubsection.6.4.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {51}Gitea starten}{37}{lstlisting.51}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {52}Erfolgreicher Start}{37}{lstlisting.52}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.4.4}Schritt 4: Firewall öffnen}{37}{subsubsection.6.4.4}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {53}Port 3000 freigeben}{37}{lstlisting.53}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.4.5}Schritt 5: Gitea im Browser einrichten}{37}{subsubsection.6.4.5}\protected@file@percent }
\BKM@entry{id=84,dest={73756273656374696F6E2E362E35},srcline={188}}{5C3337365C3337375C303030565C3030306F5C3030306C5C3030306C5C303030735C303030745C3030305C3334345C3030306E5C303030645C303030695C303030675C303030655C3030305C3034305C303030535C303030655C303030725C303030765C303030655C303030725C3030302D5C3030305C3333345C303030625C303030655C303030725C303030735C303030695C303030635C303030685C30303074}
\BKM@entry{id=85,dest={73756273756273656374696F6E2E362E352E31},srcline={192}}{5C3337365C3337375C3030304C5C303030615C303030755C303030665C303030655C3030306E5C303030645C303030655C3030305C3034305C303030445C3030306F5C303030635C3030306B5C303030655C303030725C3030302D5C303030435C3030306F5C3030306E5C303030745C303030615C303030695C3030306E5C303030655C30303072}
\BKM@entry{id=86,dest={73756273756273656374696F6E2E362E352E32},srcline={210}}{5C3337365C3337375C303030445C3030306F5C303030635C3030306B5C303030655C303030725C3030302D5C303030565C3030306F5C3030306C5C303030755C3030306D5C303030655C303030735C3030305C3034305C3030305C3035305C303030705C303030655C303030725C303030735C303030695C303030735C303030745C303030655C3030306E5C303030745C303030655C3030305C3034305C303030445C303030615C303030745C303030655C3030306E5C303030735C303030705C303030655C303030695C303030635C303030685C303030655C303030725C3030305C303531}
\BKM@entry{id=87,dest={73756273756273656374696F6E2E362E352E33},srcline={229}}{5C3337365C3337375C303030465C303030695C303030725C303030655C303030775C303030615C3030306C5C3030306C5C3030305C3034305C3030305C3035305C3030306E5C303030755C303030725C3030305C3034305C303030645C303030695C303030655C303030735C303030655C3030305C3034305C303030505C3030306F5C303030725C303030745C303030735C3030305C3034305C303030735C303030695C3030306E5C303030645C3030305C3034305C3030306F5C303030665C303030665C303030655C3030306E5C303030215C3030305C303531}
\BKM@entry{id=88,dest={73756273756273656374696F6E2E362E352E34},srcline={246}}{5C3337365C3337375C303030495C3030306E5C303030735C303030745C303030615C3030306C5C3030306C5C303030695C303030655C303030725C303030745C303030655C3030305C3034305C303030535C303030795C303030735C303030745C303030655C3030306D5C303030705C303030615C3030306B5C303030655C303030745C30303065}
\@writefile{toc}{\contentsline {subsection}{\numberline {6.5}Vollständige Server-Übersicht}{37}{subsection.6.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.5.1}Laufende Docker-Container}{37}{subsubsection.6.5.1}\protected@file@percent }
\@writefile{lot}{\contentsline {table}{\numberline {5}{\ignorespaces Alle laufenden Container auf dem Server}}{37}{table.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.5.2}Docker-Volumes (persistente Datenspeicher)}{37}{subsubsection.6.5.2}\protected@file@percent }
\@writefile{lot}{\contentsline {table}{\numberline {6}{\ignorespaces Volumes und ihre Inhalte}}{37}{table.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.5.3}Firewall (nur diese Ports sind offen!)}{37}{subsubsection.6.5.3}\protected@file@percent }
\@writefile{lot}{\contentsline {table}{\numberline {7}{\ignorespaces Geöffnete Ports}}{37}{table.7}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.5}Vollständige Server-Übersicht}{38}{subsection.6.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.5.1}Laufende Docker-Container}{38}{subsubsection.6.5.1}\protected@file@percent }
\@writefile{lot}{\contentsline {table}{\numberline {5}{\ignorespaces Alle laufenden Container auf dem Server}}{38}{table.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.5.2}Docker-Volumes (persistente Datenspeicher)}{38}{subsubsection.6.5.2}\protected@file@percent }
\@writefile{lot}{\contentsline {table}{\numberline {6}{\ignorespaces Volumes und ihre Inhalte}}{38}{table.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.5.3}Firewall (nur diese Ports sind offen!)}{38}{subsubsection.6.5.3}\protected@file@percent }
\@writefile{lot}{\contentsline {table}{\numberline {7}{\ignorespaces Geöffnete Ports}}{38}{table.7}\protected@file@percent }
\BKM@entry{id=89,dest={73756273756273656374696F6E2E362E352E35},srcline={256}}{5C3337365C3337375C303030565C303030655C303030725C3030307A5C303030655C303030695C303030635C303030685C3030306E5C303030695C303030735C303030735C303030745C303030725C303030755C3030306B5C303030745C303030755C303030725C3030305C3034305C303030755C3030306E5C303030745C303030655C303030725C3030305C3034305C3030302F5C3030306F5C303030705C30303074}
\BKM@entry{id=90,dest={73756273656374696F6E2E362E36},srcline={267}}{5C3337365C3337375C303030575C303030695C303030655C3030305C3034305C303030475C303030695C303030745C303030655C303030615C3030305C3034305C303030695C3030306E5C3030305C3034305C303030645C303030695C303030655C3030305C3034305C303030495C3030306E5C303030665C303030725C303030615C303030735C303030745C303030725C303030755C3030306B5C303030745C303030755C303030725C3030305C3034305C303030705C303030615C303030735C303030735C30303074}
\BKM@entry{id=91,dest={73756273656374696F6E2E362E37},srcline={297}}{5C3337365C3337375C3030305A5C303030755C303030735C303030615C3030306D5C3030306D5C303030655C3030306E5C303030665C303030615C303030735C303030735C303030755C3030306E5C30303067}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.5.4}Installierte Systempakete}{38}{subsubsection.6.5.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.5.5}Verzeichnisstruktur unter /opt}{38}{subsubsection.6.5.5}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {54}Projektverzeichnisse auf dem Server}{38}{lstlisting.54}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.6}Wie Gitea in die Infrastruktur passt}{38}{subsection.6.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.7}Zusammenfassung}{39}{subsection.6.7}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {55}Server-Cockpit wichtige Befehle}{39}{lstlisting.55}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.5.4}Installierte Systempakete}{39}{subsubsection.6.5.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.5.5}Verzeichnisstruktur unter /opt}{39}{subsubsection.6.5.5}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {54}Projektverzeichnisse auf dem Server}{39}{lstlisting.54}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.6}Wie Gitea in die Infrastruktur passt}{39}{subsection.6.6}\protected@file@percent }
\BKM@entry{id=92,dest={73656374696F6E2E37},srcline={5}}{5C3337365C3337375C303030435C303030495C3030302F5C303030435C303030445C3030305C3034305C3030306D5C303030695C303030745C3030305C3034305C303030475C303030695C303030745C303030655C303030615C3030305C3034305C303030415C303030635C303030745C303030695C3030306F5C3030306E5C30303073}
\BKM@entry{id=93,dest={73756273656374696F6E2E372E31},srcline={10}}{5C3337365C3337375C303030445C3030306F5C303030635C3030306B5C303030655C303030725C3030302D5C303030475C303030725C303030755C3030306E5C303030645C3030306C5C303030615C303030675C303030655C3030306E5C3030303A5C3030305C3034305C303030435C3030306F5C3030306E5C303030745C303030615C303030695C3030306E5C303030655C303030725C3030305C3034305C303030765C303030655C303030725C303030735C303030745C303030655C303030685C303030655C3030306E5C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030765C303030655C303030725C303030775C303030615C3030306C5C303030745C303030655C3030306E}
\BKM@entry{id=94,dest={73756273756273656374696F6E2E372E312E31},srcline={14}}{5C3337365C3337375C303030435C3030306F5C3030306E5C303030745C303030615C303030695C3030306E5C303030655C303030725C3030305C3034305C303030615C303030755C303030665C3030306C5C303030695C303030735C303030745C303030655C3030306E}
\@writefile{toc}{\contentsline {subsection}{\numberline {6.7}Zusammenfassung}{40}{subsection.6.7}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {55}Server-Cockpit wichtige Befehle}{40}{lstlisting.55}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {7}CI/CD mit Gitea Actions}{40}{section.7}\protected@file@percent }
\newlabel{sec:step07}{{7}{40}{CI/CD mit Gitea Actions}{section.7}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {7.1}Docker-Grundlagen: Container verstehen und verwalten}{40}{subsection.7.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.1.1}Container auflisten}{40}{subsubsection.7.1.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {56}Alle laufenden Container anzeigen}{40}{lstlisting.56}\protected@file@percent }
\BKM@entry{id=95,dest={73756273756273656374696F6E2E372E312E32},srcline={42}}{5C3337365C3337375C303030435C3030306F5C3030306E5C303030745C303030615C303030695C3030306E5C303030655C303030725C3030302D5C3030304C5C3030306F5C303030675C303030735C3030305C3034305C303030615C3030306E5C3030307A5C303030655C303030695C303030675C303030655C3030306E}
\BKM@entry{id=96,dest={73756273756273656374696F6E2E372E312E33},srcline={62}}{5C3337365C3337375C303030435C3030306F5C3030306E5C303030745C303030615C303030695C3030306E5C303030655C303030725C3030305C3034305C303030735C303030745C3030306F5C303030705C303030705C303030655C3030306E5C3030302C5C3030305C3034305C303030735C303030745C303030615C303030725C303030745C303030655C3030306E5C3030302C5C3030305C3034305C3030306E5C303030655C303030755C303030735C303030745C303030615C303030725C303030745C303030655C3030306E}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {57}Auch gestoppte Container anzeigen}{41}{lstlisting.57}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.1.2}Container-Logs anzeigen}{41}{subsubsection.7.1.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {58}Logs eines Containers anzeigen}{41}{lstlisting.58}\protected@file@percent }
\BKM@entry{id=97,dest={73756273756273656374696F6E2E372E312E34},srcline={81}}{5C3337365C3337375C303030495C3030306E5C3030305C3034305C303030655C303030695C3030306E5C303030655C3030306E5C3030305C3034305C303030435C3030306F5C3030306E5C303030745C303030615C303030695C3030306E5C303030655C303030725C3030305C3034305C303030655C303030695C3030306E5C303030735C303030745C303030655C303030695C303030675C303030655C3030306E}
\BKM@entry{id=98,dest={73756273756273656374696F6E2E372E312E35},srcline={101}}{5C3337365C3337375C303030495C3030306D5C303030615C303030675C303030655C303030735C3030305C3034305C303030765C303030655C303030725C303030775C303030615C3030306C5C303030745C303030655C3030306E}
\BKM@entry{id=99,dest={73756273756273656374696F6E2E372E312E36},srcline={114}}{5C3337365C3337375C3030304E5C303030655C303030745C3030307A5C303030775C303030655C303030725C3030306B5C303030655C3030305C3034305C303030695C3030306E5C303030735C303030705C303030695C3030307A5C303030695C303030655C303030725C303030655C3030306E}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.1.3}Container stoppen, starten, neustarten}{42}{subsubsection.7.1.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {59}Container-Lebenszyklus}{42}{lstlisting.59}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.1.4}In einen Container einsteigen}{42}{subsubsection.7.1.4}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {60}Shell im Container öffnen}{42}{lstlisting.60}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.1.5}Images verwalten}{42}{subsubsection.7.1.5}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {61}Images anzeigen und löschen}{42}{lstlisting.61}\protected@file@percent }
\BKM@entry{id=100,dest={73756273656374696F6E2E372E32},srcline={127}}{5C3337365C3337375C303030435C303030495C3030302F5C303030435C303030445C3030302D5C303030505C303030695C303030705C303030655C3030306C5C303030695C3030306E5C303030655C3030305C3034305C3030306D5C303030695C303030745C3030305C3034305C303030475C303030695C303030745C303030655C303030615C3030305C3034305C303030415C303030635C303030745C303030695C3030306F5C3030306E5C303030735C3030305C3034305C303030655C303030695C3030306E5C303030725C303030695C303030635C303030685C303030745C303030655C3030306E}
\BKM@entry{id=101,dest={73756273756273656374696F6E2E372E322E31},srcline={129}}{5C3337365C3337375C303030575C303030615C303030735C3030305C3034305C303030695C303030735C303030745C3030305C3034305C303030435C303030495C3030302F5C303030435C303030445C3030303F}
\BKM@entry{id=102,dest={73756273756273656374696F6E2E372E322E32},srcline={143}}{5C3337365C3337375C303030445C303030655C303030725C3030305C3034305C303030475C303030695C303030745C303030655C303030615C3030305C3034305C303030415C303030635C303030745C3030305C3034305C303030525C303030755C3030306E5C3030306E5C303030655C30303072}
\BKM@entry{id=103,dest={73756273756273656374696F6E2E372E322E33},srcline={161}}{5C3337365C3337375C303030445C303030695C303030655C3030305C3034305C303030575C3030306F5C303030725C3030306B5C303030665C3030306C5C3030306F5C303030775C3030302D5C303030445C303030615C303030745C303030655C30303069}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.1.6}Netzwerke inspizieren}{43}{subsubsection.7.1.6}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {62}Netzwerke untersuchen}{43}{lstlisting.62}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {7.2}CI/CD-Pipeline mit Gitea Actions einrichten}{43}{subsection.7.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.2.1}Was ist CI/CD?}{43}{subsubsection.7.2.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.2.2}Der Gitea Act Runner}{43}{subsubsection.7.2.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {63}Runner starten und mit Gitea verbinden}{43}{lstlisting.63}\protected@file@percent }
\BKM@entry{id=104,dest={73756273656374696F6E2E372E33},srcline={208}}{5C3337365C3337375C303030415C3030306C5C3030306C5C303030655C3030305C3034305C303030615C303030755C303030665C303030675C303030655C303030745C303030725C303030655C303030745C303030655C3030306E5C303030655C3030306E5C3030305C3034305C303030505C303030725C3030306F5C303030625C3030306C5C303030655C3030306D5C303030655C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030695C303030685C303030725C303030655C3030305C3034305C3030304C5C3030305C3336365C303030735C303030755C3030306E5C303030675C303030655C3030306E}
\BKM@entry{id=105,dest={73756273756273656374696F6E2E372E332E31},srcline={210}}{5C3337365C3337375C303030505C303030725C3030306F5C303030625C3030306C5C303030655C3030306D5C3030305C3034305C303030315C3030303A5C3030305C3034305C303030445C3030306F5C303030635C3030306B5C303030655C303030725C3030302D5C303030535C3030306F5C303030635C3030306B5C303030655C303030745C3030305C3034305C303030645C3030306F5C303030705C303030705C303030655C3030306C5C303030745C3030305C3034305C303030675C303030655C3030306D5C3030306F5C303030755C3030306E5C303030745C303030655C30303074}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.2.3}Die Workflow-Datei}{44}{subsubsection.7.2.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {64}Vollständige deploy.yaml (finale Version)}{44}{lstlisting.64}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {7.3}Alle aufgetretenen Probleme und ihre Lösungen}{44}{subsection.7.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.3.1}Problem 1: Docker-Socket doppelt gemountet}{44}{subsubsection.7.3.1}\protected@file@percent }
\BKM@entry{id=106,dest={73756273756273656374696F6E2E372E332E32},srcline={217}}{5C3337365C3337375C303030505C303030725C3030306F5C303030625C3030306C5C303030655C3030306D5C3030305C3034305C303030325C3030303A5C3030305C3034305C303030505C303030665C303030615C303030645C303030655C3030305C3034305C3030307A5C303030755C3030305C3034305C303030445C3030306F5C303030635C3030306B5C303030655C303030725C303030665C303030695C3030306C5C303030655C30303073}
\BKM@entry{id=107,dest={73756273756273656374696F6E2E372E332E33},srcline={224}}{5C3337365C3337375C303030505C303030725C3030306F5C303030625C3030306C5C303030655C3030306D5C3030305C3034305C303030335C3030303A5C3030305C3034305C303030455C303030525C303030525C3030305C3133375C303030505C3030304E5C303030505C3030304D5C3030305C3133375C303030495C303030475C3030304E5C3030304F5C303030525C303030455C303030445C3030305C3133375C303030425C303030555C303030495C3030304C5C303030445C30303053}
\BKM@entry{id=108,dest={73756273756273656374696F6E2E372E332E34},srcline={231}}{5C3337365C3337375C303030505C303030725C3030306F5C303030625C3030306C5C303030655C3030306D5C3030305C3034305C303030345C3030303A5C3030305C3034305C303030465C303030655C303030685C3030306C5C303030655C3030306E5C303030645C303030655C3030305C3034305C3030306E5C303030675C303030695C3030306E5C303030785C3030302E5C303030635C3030306F5C3030306E5C30303066}
\BKM@entry{id=109,dest={73756273756273656374696F6E2E372E332E35},srcline={238}}{5C3337365C3337375C303030505C303030725C3030306F5C303030625C3030306C5C303030655C3030306D5C3030305C3034305C303030355C3030303A5C3030305C3034305C303030435C3030306F5C3030306E5C303030745C303030615C303030695C3030306E5C303030655C303030725C3030305C3034305C3030306F5C303030685C3030306E5C303030655C3030305C3034305C303030505C3030306F5C303030725C303030745C3030302D5C3030304D5C303030615C303030705C303030705C303030695C3030306E5C30303067}
\BKM@entry{id=110,dest={73756273656374696F6E2E372E34},srcline={245}}{5C3337365C3337375C303030545C303030755C303030745C3030306F5C303030725C303030695C303030615C3030306C5C3030303A5C3030305C3034305C303030455C303030695C3030306E5C303030665C303030615C303030635C303030685C303030655C3030305C3034305C303030485C303030545C3030304D5C3030304C5C3030302D5C303030535C303030655C303030695C303030745C303030655C3030305C3034305C303030645C303030655C303030705C3030306C5C3030306F5C303030795C303030655C3030306E}
\BKM@entry{id=111,dest={73756273756273656374696F6E2E372E342E31},srcline={249}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030315C3030303A5C3030305C3034305C303030505C303030725C3030306F5C3030306A5C303030655C3030306B5C303030745C3030305C3034305C303030655C303030725C303030735C303030745C303030655C3030306C5C3030306C5C303030655C3030306E}
\BKM@entry{id=112,dest={73756273756273656374696F6E2E372E342E32},srcline={258}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030325C3030303A5C3030305C3034305C303030695C3030306E5C303030645C303030655C303030785C3030302E5C303030685C303030745C3030306D5C3030306C5C3030305C3034305C303030655C303030725C303030735C303030745C303030655C3030306C5C3030306C5C303030655C3030306E}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.3.2}Problem 2: Pfade zu Dockerfiles}{45}{subsubsection.7.3.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.3.3}Problem 3: ERR\_PNPM\_IGNORED\_BUILDS}{45}{subsubsection.7.3.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.3.4}Problem 4: Fehlende nginx.conf}{45}{subsubsection.7.3.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.3.5}Problem 5: Container ohne Port-Mapping}{45}{subsubsection.7.3.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {7.4}Tutorial: Einfache HTML-Seite deployen}{45}{subsection.7.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.4.1}Schritt 1: Projekt erstellen}{45}{subsubsection.7.4.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {65}Neues Projekt lokal anlegen}{45}{lstlisting.65}\protected@file@percent }
\BKM@entry{id=113,dest={73756273756273656374696F6E2E372E342E33},srcline={278}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030335C3030303A5C3030305C3034305C303030445C3030306F5C303030635C3030306B5C303030655C303030725C303030665C303030695C3030306C5C303030655C3030305C3034305C303030655C303030725C303030735C303030745C303030655C3030306C5C3030306C5C303030655C3030306E}
\BKM@entry{id=114,dest={73756273756273656374696F6E2E372E342E34},srcline={287}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030345C3030303A5C3030305C3034305C303030575C3030306F5C303030725C3030306B5C303030665C3030306C5C3030306F5C303030775C3030305C3034305C303030655C303030725C303030735C303030745C303030655C3030306C5C3030306C5C303030655C3030306E}
\BKM@entry{id=115,dest={73756273756273656374696F6E2E372E342E35},srcline={315}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030355C3030303A5C3030305C3034305C303030495C3030306E5C3030305C3034305C303030475C303030695C303030745C303030655C303030615C3030305C3034305C303030705C303030755C303030735C303030685C303030655C3030306E}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.4.2}Schritt 2: index.html erstellen}{46}{subsubsection.7.4.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {66}Minimale HTML-Seite}{46}{lstlisting.66}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.4.3}Schritt 3: Dockerfile erstellen}{46}{subsubsection.7.4.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {67}Dockerfile für statische HTML-Seite}{46}{lstlisting.67}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.4.4}Schritt 4: Workflow erstellen}{46}{subsubsection.7.4.4}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {68}Verzeichnis anlegen}{46}{lstlisting.68}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {69}.gitea/workflows/deploy.yaml}{46}{lstlisting.69}\protected@file@percent }
\BKM@entry{id=116,dest={73756273756273656374696F6E2E372E342E36},srcline={325}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030365C3030303A5C3030305C3034305C303030465C303030695C303030725C303030655C303030775C303030615C3030306C5C3030306C5C3030305C3034305C3030305C3336365C303030665C303030665C3030306E5C303030655C3030306E5C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030745C303030655C303030735C303030745C303030655C3030306E}
\BKM@entry{id=117,dest={73756273656374696F6E2E372E35},srcline={333}}{5C3337365C3337375C303030445C3030306F5C303030635C3030306B5C303030655C303030725C3030302D5C303030425C303030655C303030665C303030655C303030685C3030306C5C303030655C3030305C3034305C303030435C303030685C303030655C303030615C303030745C3030305C3034305C303030535C303030685C303030655C303030655C30303074}
\BKM@entry{id=118,dest={73756273656374696F6E2E372E36},srcline={360}}{5C3337365C3337375C3030305A5C303030755C303030735C303030615C3030306D5C3030306D5C303030655C3030306E5C303030665C303030615C303030735C303030735C303030755C3030306E5C30303067}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.4.5}Schritt 5: In Gitea pushen}{47}{subsubsection.7.4.5}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {70}Push zu Gitea}{47}{lstlisting.70}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.4.6}Schritt 6: Firewall öffnen und testen}{47}{subsubsection.7.4.6}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {71}Port 8080 freigeben}{47}{lstlisting.71}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {7.5}Docker-Befehle Cheat Sheet}{47}{subsection.7.5}\protected@file@percent }
\@writefile{lot}{\contentsline {table}{\numberline {8}{\ignorespaces Häufig verwendete Docker-Befehle}}{47}{table.8}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {7.6}Zusammenfassung}{47}{subsection.7.6}\protected@file@percent }
\global\@namedef{scr@dte@section@lastmaxnumwidth}{11.59192pt}
\global\@namedef{scr@dte@subsection@lastmaxnumwidth}{24.81589pt}
\global\@namedef{scr@dte@subsubsection@lastmaxnumwidth}{29.13585pt}
\@writefile{toc}{\providecommand\tocbasic@end@toc@file{}\tocbasic@end@toc@file}
\gdef \@abspage@last{39}
\gdef \@abspage@last{47}
+8 -6
View File
@@ -1,7 +1,7 @@
# Fdb version 4
["pdflatex"] 1778244769.05929 "/home/computer/projects/fitness-app/LateX/main.tex" "main.pdf" "main" 1778244771.97073 0
["pdflatex"] 1778328618.43654 "/home/computer/projects/fitness-app/LateX/main.tex" "main.pdf" "main" 1778328621.81028 0
"/etc/texmf/web2c/texmf.cnf" 1776891072.07073 475 c0e671620eb5563b2130f56340a5fde8 ""
"/home/computer/projects/fitness-app/LateX/main.tex" 1778244681.19007 8476 4f7793f213e99c2fab6230bc8d2163a2 ""
"/home/computer/projects/fitness-app/LateX/main.tex" 1778328619.29013 8497 f5f270fc8580b2dab1a2441bfd35bc31 ""
"/usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_d4q673.enc" 1570828436 2978 6d777d1174162fa94ff58f36782f4570 ""
"/usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_d67aat.enc" 1570828436 3385 21a7e8c8dac3c39de5acda2c56e7bd7e ""
"/usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_iln36p.enc" 1570828436 3071 cfa92ee28d698dd9275559d9d1c3a233 ""
@@ -117,6 +117,7 @@
"/usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def" 1704491087 30006 57b07afb710ee2f649c65cfbafda39c1 ""
"/usr/share/texlive/texmf-dist/tex/latex/listings/listings.cfg" 1677530001 1829 d8258b7d94f5f955e70c623e525f9f45 ""
"/usr/share/texlive/texmf-dist/tex/latex/listings/listings.sty" 1677530001 80947 75a96bb4c9f40ae31d54a01d924df2ff ""
"/usr/share/texlive/texmf-dist/tex/latex/listings/lstlang1.sty" 1677530001 205154 31132370016e8c97e49bc3862419679b ""
"/usr/share/texlive/texmf-dist/tex/latex/listings/lstmisc.sty" 1677530001 77021 d05e9115c67855816136d82929db8892 ""
"/usr/share/texlive/texmf-dist/tex/latex/microtype/microtype-pdftex.def" 1678741534 48246 c3eed060aba663f58af3ff756e83f2bd ""
"/usr/share/texlive/texmf-dist/tex/latex/microtype/microtype.cfg" 1678741534 26842 05a01d67d23e805520393a049533b8c0 ""
@@ -134,16 +135,17 @@
"/usr/share/texmf/web2c/texmf.cnf" 1707919699 40399 f2c302f7d2af602abb742093540a5834 ""
"/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map" 1776891108.46284 5472669 54eaf61a88b6b7896ebd0dac973cb29c ""
"/var/lib/texmf/web2c/pdftex/pdflatex.fmt" 1776891271 8211336 7fc26d317f030a4855527787ba3b41d3 ""
"main.aux" 1778244771.83832 63855 4c52e1a5c85714f95fa215552b7321a7 "pdflatex"
"main.out" 1778244770.69833 0 d41d8cd98f00b204e9800998ecf8427e "pdflatex"
"main.tex" 1778244681.19007 8476 4f7793f213e99c2fab6230bc8d2163a2 ""
"main.toc" 1778244771.85532 9953 4cb30a3bd0faa13d5f22ee47f5497472 "pdflatex"
"main.aux" 1778328621.6741 81084 a0cf6c44cf98fdec6d02e75d97a16b77 "pdflatex"
"main.out" 1778328620.22748 0 d41d8cd98f00b204e9800998ecf8427e "pdflatex"
"main.tex" 1778328619.29013 8497 f5f270fc8580b2dab1a2441bfd35bc31 ""
"main.toc" 1778328621.6951 12758 2058fc41ed91a43ee7e8ff6187fae142 "pdflatex"
"step_01.tex" 1778074119.30934 10807 dd7fc11a20ecebed2f07638ceddcf838 ""
"step_02.tex" 1778074524.52004 9161 30219f0c68c4ae118067f27c09a123fb ""
"step_03.tex" 1778081256.10834 17575 0dde7ed301abaec40a3b2d19357b160b ""
"step_04.tex" 1778147404.27552 9769 0e1ed5ae9f963eb62f6fdf40c18f679b ""
"step_05.tex" 1778150659.56577 15313 3aba6a4bbc80c2ab38e2b98b51ace552 ""
"step_06.tex" 1778244768.71735 12776 e41d6e861e6c9823eb02364956f8b671 ""
"step_07.tex" 1778328621.28742 13953 f2a60af4bc72f800633cd952698f82be ""
(generated)
"main.aux"
"main.log"
+9
View File
@@ -282,6 +282,15 @@ INPUT step_05.tex
INPUT ./step_06.tex
INPUT ./step_06.tex
INPUT step_06.tex
INPUT ./step_07.tex
INPUT ./step_07.tex
INPUT step_07.tex
INPUT /usr/share/texlive/texmf-dist/tex/latex/listings/lstlang1.sty
INPUT /usr/share/texlive/texmf-dist/tex/latex/listings/lstlang1.sty
INPUT /usr/share/texlive/texmf-dist/tex/latex/listings/lstlang1.sty
INPUT /usr/share/texlive/texmf-dist/tex/latex/listings/lstmisc.sty
INPUT /usr/share/texlive/texmf-dist/tex/latex/listings/lstmisc.sty
INPUT /usr/share/texlive/texmf-dist/tex/latex/listings/lstmisc.sty
INPUT main.aux
INPUT ./main.out
INPUT ./main.out
+80 -31
View File
@@ -1,4 +1,4 @@
This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Debian) (preloaded format=pdflatex 2026.4.22) 8 MAY 2026 14:52
This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Debian) (preloaded format=pdflatex 2026.4.22) 9 MAY 2026 14:10
entering extended mode
restricted \write18 enabled.
file:line:error style messages enabled.
@@ -630,11 +630,11 @@ Package microtype Info: Loading generic protrusion settings for font family
(microtype) See the microtype manual for details.
[2
{/usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_d4q673.enc}])
{/usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_d4q673.enc}] [3])
\tf@toc=\write4
\openout4 = `main.toc'.
[3] (./step_01.tex
[4] (./step_01.tex
LaTeX Font Info: Trying to load font information for TS1+FiraSans-OsF on input line 21.
(/usr/share/texlive/texmf-dist/tex/latex/fira/TS1FiraSans-OsF.fd
File: TS1FiraSans-OsF.fd 2019/10/10 (autoinst) Font definitions for TS1/FiraSans-OsF.
@@ -656,18 +656,18 @@ LaTeX Font Info: Font shape `T1/FiraSans-OsF/m/n' in size <10> not available
(Font) Font shape `T1/FiraSans-OsF/regular/n' tried instead on input line 36.
LaTeX Font Info: Font shape `T1/FiraSans-OsF/regular/n' will be
(Font) scaled to size 10.0pt on input line 36.
[4
[5
{/usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_d67aat.enc}] [5]
{/usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_d67aat.enc}] [6]
LaTeX Font Info: Font shape `T1/FiraMono-TOsF/b/n' in size <10> not available
(Font) Font shape `T1/FiraMono-TOsF/bold/n' tried instead on input line 140.
LaTeX Font Info: Font shape `T1/FiraMono-TOsF/bold/n' will be
(Font) scaled to size 8.99994pt on input line 140.
[6]
[7]
Package Listings Warning: Text dropped after begin of listing on input line 221.
[7]) (./step_02.tex [8]
[8]) (./step_02.tex [9]
Underfull \hbox (badness 10000) in paragraph at lines 63--64
[]|\T1/FiraSans-OsF/regular/n/12 (+20) Unser \T1/FiraSans-OsF/bold/n/12 (+20) ein-zi-ger Ver-wal-
[]
@@ -705,17 +705,17 @@ Underfull \hbox (badness 3612) in paragraph at lines 65--66
LaTeX Warning: `h' float specifier changed to `ht'.
[9]
[10]
Overfull \hbox (3.891pt too wide) in paragraph at lines 77--78
[]\T1/FiraSans-OsF/regular/n/12 (-20) HTTP-Verbindungen kön-nen von An-grei-fern ver-än-dert wer-den (Man-in-the-Middle)
[]
[10] [11]) (./step_03.tex [12]
[11] [12]) (./step_03.tex [13]
LaTeX Font Info: Font shape `T1/FiraMono-TOsF/b/n' in size <12> not available
(Font) Font shape `T1/FiraMono-TOsF/bold/n' tried instead on input line 29.
LaTeX Font Info: Font shape `T1/FiraMono-TOsF/bold/n' will be
(Font) scaled to size 10.79993pt on input line 29.
[13] [14]
[14] [15]
Overfull \hbox (74.52446pt too wide) in paragraph at lines 125--126
[]\T1/FiraMono-TOsF/regular/n/12 location / \T1/FiraSans-OsF/regular/n/12 (-20) ^^U An-fra-gen an die Haupt-sei-te $\OMS/cmsy/m/n/12 !$ \T1/FiraSans-OsF/regular/n/12 (-20) lie-fert React-Dateien aus \T1/FiraMono-TOsF/regular/n/12 /usr/share/nginx/html
[]
@@ -725,7 +725,7 @@ Overfull \hbox (36.2292pt too wide) in paragraph at lines 126--127
[]\T1/FiraMono-TOsF/regular/n/12 location /api/ \T1/FiraSans-OsF/regular/n/12 (-20) ^^U An-fra-gen an \T1/FiraMono-TOsF/regular/n/12 /api/* $\OMS/cmsy/m/n/12 !$ \T1/FiraSans-OsF/regular/n/12 (-20) lei-tet sie an das Ba-ckend (\T1/FiraMono-TOsF/regular/n/12 fitness-api:5000\T1/FiraSans-OsF/regular/n/12 (-20) )
[]
[15] [16]
[16] [17]
LaTeX Font Info: Font shape `T1/FiraMono-TOsF/m/it' in size <10> not available
(Font) Font shape `T1/FiraMono-TOsF/regular/it' tried instead on input line 214.
LaTeX Font Info: Font shape `T1/FiraMono-TOsF/regular/it' in size <10> not available
@@ -737,7 +737,7 @@ Overfull \hbox (5.87708pt too wide) in paragraph at lines 220--221
[]\T1/FiraMono-TOsF/regular/n/12 API_BASE = \T1/FiraSans-OsF/regular/n/12 (-20) ^^U Kei-ne ab-so-lu-te URL! Statt-des-sen re-la-ti-ve Pfa-de wie \T1/FiraMono-TOsF/regular/n/12 /api/workouts\T1/FiraSans-OsF/regular/n/12 (-20) .
[]
[17] [18] [19]
[18] [19] [20]
Overfull \hbox (10.69511pt too wide) in paragraph at lines 341--342
[]\T1/FiraMono-TOsF/regular/n/12 -v fitness-data:/app/data \T1/FiraSans-OsF/regular/n/12 (-20) ^^U Bin-det das Vo-lu-me \T1/FiraMono-TOsF/regular/n/12 fitness-data \T1/FiraSans-OsF/regular/n/12 (-20) in den Container-
[]
@@ -747,7 +747,7 @@ Overfull \hbox (0.99844pt too wide) in paragraph at lines 361--362
[]\T1/FiraSans-OsF/regular/n/12 (-20) Ursache: Im Cli-ent stand \T1/FiraMono-TOsF/regular/n/12 const API_BASE = "http://192.168.178.189:5107"\T1/FiraSans-OsF/regular/n/12 (-20) .
[]
[20]) (./step_04.tex
[21]) (./step_04.tex
Underfull \hbox (badness 2197) in paragraph at lines 35--36
[]|\T1/FiraSans-OsF/regular/n/12 (+20) Wie A-Record, aber für IPv6-
[]
@@ -760,22 +760,22 @@ Underfull \hbox (badness 2150) in paragraph at lines 38--39
LaTeX Warning: `h' float specifier changed to `ht'.
[21] [22] [23]
[22] [23] [24]
Overfull \hbox (38.17029pt too wide) in paragraph at lines 152--153
[]\T1/FiraMono-TOsF/regular/n/12 *.robre.de \T1/FiraSans-OsF/regular/n/12 (-20) ^^U fängt al-le zu-künf-ti-gen Sub-do-mains ab (z. B. \T1/FiraMono-TOsF/regular/n/12 app.robre.de\T1/FiraSans-OsF/regular/n/12 (-20) , \T1/FiraMono-TOsF/regular/n/12 api.robre.de\T1/FiraSans-OsF/regular/n/12 (-20) ),
[]
[24]) (./step_05.tex
[25]) (./step_05.tex
Overfull \hbox (16.09901pt too wide) in paragraph at lines 5--6
\T1/FiraMono-TOsF/regular/n/12 https://robre.de \T1/FiraSans-OsF/regular/n/12 (-20) er-reich-bar und er-füllt al-le Vor-aus-set-zun-gen für die PWA-Installation.
[]
[25]
[26]
Overfull \hbox (74.09863pt too wide) in paragraph at lines 26--27
[]\T1/FiraSans-OsF/regular/n/12 (-20) Let's En-crypt prüft, ob die-se Da-tei un-ter \T1/FiraMono-TOsF/regular/n/12 http://robre.de/.well-known/acme-challenge/...
[]
[26] [27] [28] [29]
[27] [28] [29] [30]
Overfull \hbox (12.23381pt too wide) in paragraph at lines 205--206
[]\T1/FiraMono-TOsF/regular/n/12 certs:/etc/nginx/certs \T1/FiraSans-OsF/regular/n/12 (-20) ^^U Hier spei-chert der acme-companion die SSL-Zertifikate.
[]
@@ -785,12 +785,12 @@ Overfull \hbox (26.42038pt too wide) in paragraph at lines 224--225
[]\T1/FiraMono-TOsF/regular/n/12 certs, vhost, html, acme \T1/FiraSans-OsF/regular/n/12 (-20) ^^U Spei-chern SSL-Zertifikate, Kon-fi-gu-ra-ti-on und Challenge-
[]
[30] [31]
[31] [32]
Overfull \hbox (118.71225pt too wide) in paragraph at lines 288--289
[]\T1/FiraSans-OsF/bold/n/12 (-20) Docker-Container: \T1/FiraSans-OsF/regular/n/12 (-20) Einen neu-en Con-tai-ner mit den Um-ge-bungs-va-ria-blen \T1/FiraMono-TOsF/regular/n/12 VIRTUAL_HOST=todo.robre.de
[]
[32]) (./step_06.tex [33]
[33]) (./step_06.tex [34]
Overfull \hbox (44.70439pt too wide) in paragraph at lines 51--52
[]\T1/FiraSans-OsF/bold/n/12 (-20) Datenbank-Fehler: \T1/FiraSans-OsF/regular/n/12 (-20) Die ent-schei-den-de Feh-ler-mel-dung in \T1/FiraMono-TOsF/regular/n/12 /opt/onedev/logs/server.log\T1/FiraSans-OsF/regular/n/12 (-20) :
[]
@@ -798,12 +798,61 @@ Overfull \hbox (44.70439pt too wide) in paragraph at lines 51--52
LaTeX Warning: `h' float specifier changed to `ht'.
[34] [35] [36]
[35] [36] [37]
Overfull \hbox (70.29362pt too wide) in paragraph at lines 197--208
[][]
[]
[37] [38]) [39] (./main.aux)
[38] [39]) (./step_07.tex
Overfull \hbox (4.83234pt too wide) in paragraph at lines 27--27
[]\T1/FiraMono-TOsF/regular/n/12 CONTAINER ID IMAGE PORTS NAMES[]
[]
Overfull \hbox (37.23209pt too wide) in paragraph at lines 27--27
[]\T1/FiraMono-TOsF/regular/n/12 e8e823a7beea nginxproxy/nginx-proxy 0.0.0.0:80->80 nginx-proxy[]
[]
Overfull \hbox (43.71204pt too wide) in paragraph at lines 27--27
[]\T1/FiraMono-TOsF/regular/n/12 596b718e9c16 fitness-api:latest 5000/tcp fitness-api[]
[]
[40]
Overfull \hbox (34.20703pt too wide) in paragraph at lines 57--58
[]\T1/FiraMono-TOsF/regular/n/12 info: Microsoft.Hosting.Lifetime[14] Now listening on: http://[::]:5000
[]
Overfull \hbox (6.27603pt too wide) in paragraph at lines 58--59
[]\T1/FiraMono-TOsF/regular/n/12 [notice] 19#19: signal 1 (SIGHUP) received, reconfiguring \T1/FiraSans-OsF/regular/n/12 (-20) ^^U nginx wur-
[]
Overfull \hbox (22.20811pt too wide) in paragraph at lines 59--60
[]\T1/FiraMono-TOsF/regular/n/12 ERROR: failed to build: failed to solve \T1/FiraSans-OsF/regular/n/12 (-20) ^^U Docker-Build-Fehler (häu-fig falsche
[]
[41] [42]
Overfull \hbox (30.86067pt too wide) in paragraph at lines 138--139
[]\T1/FiraSans-OsF/regular/n/12 (-20) Gitea er-kennt den Pu-sh und sucht nach Workflow-Dateien (\T1/FiraMono-TOsF/regular/n/12 .gitea/workflows/*.yaml\T1/FiraSans-OsF/regular/n/12 (-20) )
[]
[43] [44]
Overfull \hbox (8.06087pt too wide) in paragraph at lines 222--223
[]\T1/FiraSans-OsF/bold/n/12 (-20) Lösung: \T1/FiraSans-OsF/regular/n/12 (-20) Ko-pi-en der Docker-fi-les (\T1/FiraMono-TOsF/regular/n/12 Dockerfile.api\T1/FiraSans-OsF/regular/n/12 (-20) , \T1/FiraMono-TOsF/regular/n/12 Dockerfile.web\T1/FiraSans-OsF/regular/n/12 (-20) ) im Root-Verzeichnis
[]
Overfull \hbox (17.54306pt too wide) in paragraph at lines 225--226
[]\T1/FiraSans-OsF/bold/n/12 (-20) Fehlermeldung: \T1/FiraMono-TOsF/regular/n/12 [ERR_PNPM_IGNORED_BUILDS] Ignored build scripts: @swc/core
[]
(/usr/share/texlive/texmf-dist/tex/latex/listings/lstlang1.sty
File: lstlang1.sty 2023/02/27 1.9 listings language file
) (/usr/share/texlive/texmf-dist/tex/latex/listings/lstmisc.sty
File: lstmisc.sty 2023/02/27 1.9 (Carsten Heinz)
) [45] [46]) [47] (./main.aux)
***********
LaTeX2e <2023-11-01> patch level 1
L3 programming layer <2024-01-22>
@@ -812,18 +861,18 @@ Package rerunfilecheck Info: File `main.out' has not changed.
(rerunfilecheck) Checksum: D41D8CD98F00B204E9800998ECF8427E;0.
)
Here is how much of TeX's memory you used:
20493 strings out of 474222
351901 string characters out of 5748733
20992 strings out of 474222
358177 string characters out of 5748733
2292975 words of memory out of 5000000
41569 multiletter control sequences out of 15000+600000
697305 words of font info for 241 fonts, out of 8000000 for 9000
41868 multiletter control sequences out of 15000+600000
697660 words of font info for 243 fonts, out of 8000000 for 9000
1141 hyphenation exceptions out of 8191
108i,11n,107p,10941b,2229s stack positions out of 10000i,1000n,20000p,200000b,200000s
108i,11n,107p,10941b,2302s stack positions out of 10000i,1000n,20000p,200000b,200000s
</usr/share/texlive/texmf-dist/fonts/type1/public/fira/FiraMono-Bold.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/fira/FiraMono-Oblique.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/fira/FiraMono-Regular.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/fira/FiraSans-Bold.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/fira/FiraSans-Regular.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy10.pfb>
Output written on main.pdf (39 pages, 374479 bytes).
Output written on main.pdf (47 pages, 407015 bytes).
PDF statistics:
1350 PDF objects out of 1440 (max. 8388607)
1283 compressed objects within 13 object streams
668 named destinations out of 1000 (max. 500000)
46297 words of extra memory for PDF output out of 51595 (max. 10000000)
1712 PDF objects out of 1728 (max. 8388607)
1633 compressed objects within 17 object streams
857 named destinations out of 1000 (max. 500000)
46513 words of extra memory for PDF output out of 51595 (max. 10000000)
BIN
View File
Binary file not shown.
Binary file not shown.
+1
View File
@@ -249,6 +249,7 @@
\input{step_04.tex}
\input{step_05.tex}
\input{step_06.tex}
\input{step_07.tex}
% Weitere Kapitel folgen hier:
% \input{step_02.tex}
+122 -95
View File
@@ -1,97 +1,124 @@
\babel@toc {ngerman}{}\relax
\contentsline {section}{\numberline {1}Server-Absicherung (Ubuntu 24.04 auf Contabo VPS)}{4}{section.1}%
\contentsline {subsection}{\numberline {1.1}Schritt 1: SSH-Verbindung testen}{4}{subsection.1.1}%
\contentsline {subsection}{\numberline {1.2}Schritt 2: System-Updates}{5}{subsection.1.2}%
\contentsline {subsection}{\numberline {1.3}Schritt 3: SSH-Key-Authentifizierung}{5}{subsection.1.3}%
\contentsline {subsection}{\numberline {1.4}Schritt 4: SSH-Client-Konfiguration (Alias)}{6}{subsection.1.4}%
\contentsline {subsection}{\numberline {1.5}Schritt 5: SSH-Timeout auf 20 Minuten}{7}{subsection.1.5}%
\contentsline {subsection}{\numberline {1.6}Schritt 6: Fail2Ban (Bruteforce-Schutz)}{7}{subsection.1.6}%
\contentsline {subsection}{\numberline {1.7}Zusammenfassung}{8}{subsection.1.7}%
\contentsline {section}{\numberline {2}Firewall mit UFW einrichten}{8}{section.2}%
\contentsline {subsection}{\numberline {2.1}Was ist eine Firewall und warum brauchen wir sie?}{9}{subsection.2.1}%
\contentsline {subsection}{\numberline {2.2}Die 65.535 Ports: Ein kurzer Überblick}{9}{subsection.2.2}%
\contentsline {subsection}{\numberline {2.3}Die drei Ports, die wir öffnen}{9}{subsection.2.3}%
\contentsline {subsection}{\numberline {2.4}Warum HTTPS für PWAs Pflicht ist}{9}{subsection.2.4}%
\contentsline {subsection}{\numberline {2.5}Durchführung}{10}{subsection.2.5}%
\contentsline {subsubsection}{\numberline {2.5.1}Standardrichtlinien setzen}{10}{subsubsection.2.5.1}%
\contentsline {subsubsection}{\numberline {2.5.2}Benötigte Ports öffnen}{11}{subsubsection.2.5.2}%
\contentsline {subsubsection}{\numberline {2.5.3}Firewall aktivieren}{11}{subsubsection.2.5.3}%
\contentsline {subsubsection}{\numberline {2.5.4}Konfiguration überprüfen}{12}{subsubsection.2.5.4}%
\contentsline {subsection}{\numberline {2.6}Zusammenfassung}{12}{subsection.2.6}%
\contentsline {section}{\numberline {3}Docker-Images bauen und App deployen}{13}{section.3}%
\contentsline {subsection}{\numberline {3.1}Was ist Docker und warum nutzen wir es?}{13}{subsection.3.1}%
\contentsline {subsection}{\numberline {3.2}Die drei Dockerfiles im Detail}{13}{subsection.3.2}%
\contentsline {subsubsection}{\numberline {3.2.1}Backend-Dockerfile: \texttt {apps/api/Dockerfile}}{13}{subsubsection.3.2.1}%
\contentsline {subsubsection}{\numberline {3.2.2}Frontend-Dockerfile: \texttt {apps/web/Dockerfile}}{14}{subsubsection.3.2.2}%
\contentsline {subsubsection}{\numberline {3.2.3}Nginx-Konfiguration: \texttt {apps/web/nginx.conf}}{15}{subsubsection.3.2.3}%
\contentsline {subsection}{\numberline {3.3}Das Backend: Program.cs im Detail}{16}{subsection.3.3}%
\contentsline {subsection}{\numberline {3.4}Der API-Client: client.ts im Detail}{17}{subsection.3.4}%
\contentsline {subsection}{\numberline {3.5}Das Frontend: App.tsx im Detail}{17}{subsection.3.5}%
\contentsline {subsection}{\numberline {3.6}Images bauen}{18}{subsection.3.6}%
\contentsline {subsection}{\numberline {3.7}Images exportieren und auf den Server kopieren}{19}{subsection.3.7}%
\contentsline {subsection}{\numberline {3.8}Container auf dem Server starten}{19}{subsection.3.8}%
\contentsline {subsection}{\numberline {3.9}Aufgetretene Probleme und Lösungen}{20}{subsection.3.9}%
\contentsline {subsection}{\numberline {3.10}Zusammenfassung}{21}{subsection.3.10}%
\contentsline {section}{\numberline {4}Domain kaufen und DNS konfigurieren}{21}{section.4}%
\contentsline {subsection}{\numberline {4.1}Warum eine eigene Domain?}{21}{subsection.4.1}%
\contentsline {subsection}{\numberline {4.2}Grundlagen: Wie funktioniert das DNS?}{21}{subsection.4.2}%
\contentsline {subsection}{\numberline {4.3}Was ist DNS-Propagation?}{22}{subsection.4.3}%
\contentsline {subsection}{\numberline {4.4}Domain-Kauf bei Contabo}{22}{subsection.4.4}%
\contentsline {subsubsection}{\numberline {4.4.1}Schritt 1: Einloggen ins Kundencenter}{22}{subsubsection.4.4.1}%
\contentsline {subsubsection}{\numberline {4.4.2}Schritt 2: Domain bestellen}{22}{subsubsection.4.4.2}%
\contentsline {subsubsection}{\numberline {4.4.3}Schritt 3: Domain-Handles konfigurieren}{23}{subsubsection.4.4.3}%
\contentsline {subsubsection}{\numberline {4.4.4}Schritt 4: Nameserver festlegen}{23}{subsubsection.4.4.4}%
\contentsline {subsubsection}{\numberline {4.4.5}Schritt 5: IP-Adresse auswählen}{23}{subsubsection.4.4.5}%
\contentsline {subsubsection}{\numberline {4.4.6}Schritt 6: Bestellung abschließen}{23}{subsubsection.4.4.6}%
\contentsline {subsection}{\numberline {4.5}DNS-Einträge für die Domain einrichten}{23}{subsection.4.5}%
\contentsline {subsubsection}{\numberline {4.5.1}Schritt 1: DNS Zone Management öffnen}{23}{subsubsection.4.5.1}%
\contentsline {subsubsection}{\numberline {4.5.2}Schritt 2: Notwendige A-Records anlegen}{24}{subsubsection.4.5.2}%
\contentsline {subsection}{\numberline {4.6}DNS-Propagation prüfen und beschleunigen}{24}{subsection.4.6}%
\contentsline {subsubsection}{\numberline {4.6.1}Direkt beim Nameserver prüfen}{24}{subsubsection.4.6.1}%
\contentsline {subsubsection}{\numberline {4.6.2}Lokalen DNS-Cache leeren}{25}{subsubsection.4.6.2}%
\contentsline {subsubsection}{\numberline {4.6.3}Server direkt über IP prüfen}{25}{subsubsection.4.6.3}%
\contentsline {subsubsection}{\numberline {4.6.4}Online DNS-Checker verwenden}{25}{subsubsection.4.6.4}%
\contentsline {subsection}{\numberline {4.7}Zusammenfassung}{25}{subsection.4.7}%
\contentsline {section}{\numberline {5}HTTPS mit nginx-proxy und Let's Encrypt}{26}{section.5}%
\contentsline {subsection}{\numberline {5.1}Warum brauchen wir HTTPS?}{26}{subsection.5.1}%
\contentsline {subsection}{\numberline {5.2}Wie funktioniert das SSL-Zertifikat von Let's Encrypt?}{26}{subsection.5.2}%
\contentsline {subsection}{\numberline {5.3}DNS-Propagation: Wie lange dauert es?}{27}{subsection.5.3}%
\contentsline {subsection}{\numberline {5.4}Architektur: Wie hängen die Container zusammen?}{27}{subsection.5.4}%
\contentsline {subsection}{\numberline {5.5}Schritt-für-Schritt: HTTPS einrichten}{28}{subsection.5.5}%
\contentsline {subsubsection}{\numberline {5.5.1}Schritt 1: Bestehende Container stoppen und löschen}{28}{subsubsection.5.5.1}%
\contentsline {subsubsection}{\numberline {5.5.2}Schritt 2: Verzeichnis für docker-compose anlegen}{28}{subsubsection.5.5.2}%
\contentsline {subsubsection}{\numberline {5.5.3}Schritt 3: docker-compose.yml erstellen}{28}{subsubsection.5.5.3}%
\contentsline {paragraph}{\nonumberline nginx-proxy}{30}{paragraph*.3}%
\contentsline {paragraph}{\nonumberline acme-companion}{30}{paragraph*.5}%
\contentsline {paragraph}{\nonumberline frontend (entscheidende Umgebungsvariablen!)}{30}{paragraph*.7}%
\contentsline {paragraph}{\nonumberline Docker Volumes}{31}{paragraph*.9}%
\contentsline {subsubsection}{\numberline {5.5.4}Schritt 4: Container starten}{31}{subsubsection.5.5.4}%
\contentsline {subsubsection}{\numberline {5.5.5}Schritt 5: Status prüfen}{31}{subsubsection.5.5.5}%
\contentsline {subsubsection}{\numberline {5.5.6}Schritt 6: Logs des acme-companion prüfen}{31}{subsubsection.5.5.6}%
\contentsline {subsection}{\numberline {5.6}Häufige Fehler und ihre Behebung}{31}{subsection.5.6}%
\contentsline {subsubsection}{\numberline {5.6.1}Fehler 1: ''can't get nginx-proxy container ID''}{31}{subsubsection.5.6.1}%
\contentsline {subsubsection}{\numberline {5.6.2}Fehler 2: ''contact email has forbidden domain''}{31}{subsubsection.5.6.2}%
\contentsline {subsubsection}{\numberline {5.6.3}Fehler 3: ''DNS problem: NXDOMAIN''}{32}{subsubsection.5.6.3}%
\contentsline {subsection}{\numberline {5.7}Wie füge ich später weitere Subdomains hinzu?}{32}{subsection.5.7}%
\contentsline {subsection}{\numberline {5.8}Wie funktioniert der Reverse Proxy im Detail?}{32}{subsection.5.8}%
\contentsline {subsection}{\numberline {5.9}Zusammenfassung}{33}{subsection.5.9}%
\contentsline {section}{\numberline {6}Gitea Installation und Server-Übersicht}{33}{section.6}%
\contentsline {subsection}{\numberline {6.1}Warum ein eigener Git-Server?}{33}{subsection.6.1}%
\contentsline {subsection}{\numberline {6.2}OneDev: Der gescheiterte Versuch}{33}{subsection.6.2}%
\contentsline {subsubsection}{\numberline {6.2.1}Installationsversuch mit Docker (Version \texttt {1dev/server:latest})}{34}{subsubsection.6.2.1}%
\contentsline {subsection}{\numberline {6.3}Gitea: Die schlanke Alternative}{34}{subsection.6.3}%
\contentsline {subsection}{\numberline {6.4}Gitea mit Docker installieren}{35}{subsection.6.4}%
\contentsline {subsubsection}{\numberline {6.4.1}Schritt 1: OneDev rückstandslos entfernen}{35}{subsubsection.6.4.1}%
\contentsline {subsubsection}{\numberline {6.4.2}Schritt 2: Gitea-Verzeichnis und docker-compose.yml anlegen}{35}{subsubsection.6.4.2}%
\contentsline {subsubsection}{\numberline {6.4.3}Schritt 3: Container starten}{36}{subsubsection.6.4.3}%
\contentsline {subsubsection}{\numberline {6.4.4}Schritt 4: Firewall öffnen}{36}{subsubsection.6.4.4}%
\contentsline {subsubsection}{\numberline {6.4.5}Schritt 5: Gitea im Browser einrichten}{36}{subsubsection.6.4.5}%
\contentsline {subsection}{\numberline {6.5}Vollständige Server-Übersicht}{37}{subsection.6.5}%
\contentsline {subsubsection}{\numberline {6.5.1}Laufende Docker-Container}{37}{subsubsection.6.5.1}%
\contentsline {subsubsection}{\numberline {6.5.2}Docker-Volumes (persistente Datenspeicher)}{37}{subsubsection.6.5.2}%
\contentsline {subsubsection}{\numberline {6.5.3}Firewall (nur diese Ports sind offen!)}{37}{subsubsection.6.5.3}%
\contentsline {subsubsection}{\numberline {6.5.4}Installierte Systempakete}{38}{subsubsection.6.5.4}%
\contentsline {subsubsection}{\numberline {6.5.5}Verzeichnisstruktur unter /opt}{38}{subsubsection.6.5.5}%
\contentsline {subsection}{\numberline {6.6}Wie Gitea in die Infrastruktur passt}{38}{subsection.6.6}%
\contentsline {subsection}{\numberline {6.7}Zusammenfassung}{39}{subsection.6.7}%
\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
+369
View File
@@ -0,0 +1,369 @@
% ============================================
% STEP 07: CI/CD MIT GITEA ACTIONS - DAS VOLLSTÄNDIGE TUTORIAL
% ============================================
\section{CI/CD mit Gitea Actions}
\label{sec:step07}
In diesem Schritt haben wir eine vollständige CI/CD-Pipeline mit Gitea Actions eingerichtet. Bei jedem \texttt{git push} auf den \texttt{master}-Branch wird unsere Anwendung automatisch gebaut und auf dem Server deployed. Dieses Kapitel dokumentiert den kompletten Prozess, alle aufgetretenen Probleme und deren Lösungen, sowie ein ausführliches Docker-Tutorial für die tägliche Arbeit.
\subsection{Docker-Grundlagen: Container verstehen und verwalten}
Bevor wir in die CI/CD-Pipeline einsteigen, ist es wichtig, die Docker-Befehle zu verstehen, mit denen wir täglich arbeiten.
\subsubsection{Container auflisten}
\begin{lstlisting}[language=Bash, caption={Alle laufenden Container anzeigen}]
docker ps
\end{lstlisting}
\textbf{Ausgabe verstehen:}
\begin{verbatim}
CONTAINER ID IMAGE PORTS NAMES
98f3eff6a77f gitea/gitea:latest 0.0.0.0:3000->3000 gitea
e8e823a7beea nginxproxy/nginx-proxy 0.0.0.0:80->80 nginx-proxy
596b718e9c16 fitness-api:latest 5000/tcp fitness-api
\end{verbatim}
\textbf{Spalten erklärt:}
\begin{itemize}
\item \texttt{CONTAINER ID} Eindeutige 12-stellige Hexadezimal-ID des Containers. Kann abgekürzt verwendet werden (z.B. \texttt{98f3}).
\item \texttt{IMAGE} Das Image, aus dem der Container gestartet wurde. \texttt{latest} ist der Tag (Version).
\item \texttt{PORTS} Port-Weiterleitungen. \texttt{0.0.0.0:3000->3000} bedeutet: Port 3000 des Hosts ist auf Port 3000 des Containers weitergeleitet. Steht nur \texttt{5000/tcp}, ist der Port nur container-intern erreichbar.
\item \texttt{NAMES} Der Name, den wir dem Container gegeben haben. Wird für \texttt{docker exec} und \texttt{docker logs} verwendet.
\end{itemize}
\textbf{Alle Container (auch gestoppte):}
\begin{lstlisting}[language=Bash, caption={Auch gestoppte Container anzeigen}]
docker ps -a
\end{lstlisting}
\subsubsection{Container-Logs anzeigen}
\begin{lstlisting}[language=Bash, caption={Logs eines Containers anzeigen}]
# Letzte 50 Zeilen
docker logs fitness-api --tail 50
# Logs live verfolgen (Strg+C zum Beenden)
docker logs -f nginx-proxy
# Logs seit 10 Minuten
docker logs fitness-web --since 10m
\end{lstlisting}
\textbf{Typische Log-Einträge verstehen:}
\begin{itemize}
\item \texttt{info: Microsoft.Hosting.Lifetime[14] Now listening on: http://[::]:5000} Backend läuft und wartet auf Anfragen
\item \texttt{[notice] 19\#19: signal 1 (SIGHUP) received, reconfiguring} nginx wurde neu geladen (nach Konfigurationsänderung)
\item \texttt{ERROR: failed to build: failed to solve} Docker-Build-Fehler (häufig falsche Pfade)
\end{itemize}
\subsubsection{Container stoppen, starten, neustarten}
\begin{lstlisting}[language=Bash, caption={Container-Lebenszyklus}]
# Container stoppen (bleibt existent, kann neugestartet werden)
docker stop fitness-web
# Gestoppten Container wieder starten
docker start fitness-web
# Container neustarten (stop + start)
docker restart nginx-proxy
# Container stoppen UND löschen (Wegwerfen!)
docker rm fitness-web
# Erzwingen: stoppen + löschen in einem Befehl
docker rm -f fitness-web
\end{lstlisting}
\subsubsection{In einen Container einsteigen}
\begin{lstlisting}[language=Bash, caption={Shell im Container öffnen}]
# In einen laufenden Container einsteigen und Bash öffnen
docker exec -it fitness-api bash
# Einzelnen Befehl im Container ausführen
docker exec nginx-proxy nginx -s reload
# Mit sh (falls bash nicht verfügbar)
docker exec -it fitness-web sh
\end{lstlisting}
\textbf{Erklärung:}
\begin{itemize}
\item \texttt{exec} Führt einen Befehl in einem laufenden Container aus
\item \texttt{-it} Interaktiv + Terminal (damit du tippen kannst)
\item \texttt{bash / sh} Die zu öffnende Shell
\end{itemize}
\subsubsection{Images verwalten}
\begin{lstlisting}[language=Bash, caption={Images anzeigen und löschen}]
# Alle lokal gespeicherten Images anzeigen
docker images
# Nicht mehr verwendete Images löschen
docker image prune -a
# Ein bestimmtes Image löschen
docker rmi fitness-api:latest
\end{lstlisting}
\subsubsection{Netzwerke inspizieren}
\begin{lstlisting}[language=Bash, caption={Netzwerke untersuchen}]
# Alle Docker-Netzwerke
docker network ls
# Details eines Netzwerks (welche Container sind drin?)
docker network inspect fitness_proxy-net
# Nur die Container-Namen im Netzwerk anzeigen
docker network inspect fitness_proxy-net --format='{{range .Containers}}{{.Name}} {{end}}'
\end{lstlisting}
\subsection{CI/CD-Pipeline mit Gitea Actions einrichten}
\subsubsection{Was ist CI/CD?}
\textbf{CI (Continuous Integration):} Bei jedem Push wird der Code automatisch gebaut und getestet. Fehler werden sofort erkannt.
\textbf{CD (Continuous Deployment):} Nach erfolgreichem Build wird die Anwendung automatisch auf dem Server deployed.
\textbf{Unser Workflow:}
\begin{enumerate}
\item Developer macht \texttt{git push} auf den \texttt{master}-Branch
\item Gitea erkennt den Push und sucht nach Workflow-Dateien (\texttt{.gitea/workflows/*.yaml})
\item Gitea weist den Job dem \texttt{gitea\_runner} zu
\item Der Runner checkt den Code aus, baut Docker-Images und startet die Container neu
\end{enumerate}
\subsubsection{Der Gitea Act Runner}
Der Runner ist der "Arbeiter", der die CI/CD-Jobs ausführt. Er läuft als Docker-Container und hat Zugriff auf den Docker-Socket des Hosts, um selbst Container zu bauen.
\begin{lstlisting}[language=Bash, caption={Runner starten und mit Gitea verbinden}]
docker run -d --name gitea_runner \
-e GITEA_INSTANCE_URL=http://185.209.229.167:3000 \
-e GITEA_RUNNER_REGISTRATION_TOKEN=DEIN_TOKEN \
-v /var/run/docker.sock:/var/run/docker.sock \
gitea/act_runner:nightly
\end{lstlisting}
\textbf{Wichtige Details:}
\begin{itemize}
\item \texttt{-v /var/run/docker.sock:/var/run/docker.sock} Gibt dem Runner Zugriff auf Docker. \textbf{Ohne diese Zeile kann der Runner keine Images bauen!}
\item Der Token ist ein Einmal-Passwort. Nach erfolgreicher Registrierung ist er verbraucht. Der Container stoppt dann mit Exit-Code 0 das ist normal! Einfach \texttt{docker start gitea\_runner} ausführen.
\end{itemize}
\subsubsection{Die Workflow-Datei}
Die Datei \texttt{.gitea/workflows/deploy.yaml} definiert den Ablauf:
\begin{lstlisting}[language=YAML, caption={Vollständige deploy.yaml (finale Version)}]
name: Deploy Fitness App
on:
push:
branches: [ "master" ]
jobs:
deploy:
runs-on: ubuntu-latest
container:
image: catthehacker/ubuntu:act-latest
volumes:
- /opt/fitness:/opt/fitness
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build & Deploy
run: |
docker build -f Dockerfile.api -t fitness-api:latest .
docker build -f Dockerfile.web -t fitness-web:latest .
docker stop fitness-api fitness-web 2>/dev/null || true
docker rm fitness-api fitness-web 2>/dev/null || true
docker run -d --name fitness-api --network fitness_proxy-net \
-v fitness_fitness-data:/app/data fitness-api:latest
docker run -d --name fitness-web --network fitness_proxy-net \
-p 80:80 \
-e VIRTUAL_HOST=robre.de,www.robre.de \
-e LETSENCRYPT_HOST=robre.de,www.robre.de \
-e VIRTUAL_PORT=80 \
fitness-web:latest
\end{lstlisting}
\textbf{Zeile für Zeile erklärt:}
\begin{itemize}
\item \texttt{on: push: branches: [ "master" ]} Der Workflow startet nur bei Pushes auf den master-Branch.
\item \texttt{runs-on: ubuntu-latest} Die virtuelle Maschine, auf der der Job läuft.
\item \texttt{container: image: catthehacker/ubuntu:act-latest} Ein Docker-Image mit Ubuntu + Docker CLI.
\item \texttt{volumes: /opt/fitness:/opt/fitness} Bindet das Projektverzeichnis ein.
\item \texttt{2>/dev/null || true} Unterdrückt Fehlermeldungen, wenn die Container nicht existieren.
\end{itemize}
\subsection{Alle aufgetretenen Probleme und ihre Lösungen}
\subsubsection{Problem 1: Docker-Socket doppelt gemountet}
\textbf{Fehlermeldung:} \texttt{Duplicate mount point: /var/run/docker.sock}
\textbf{Ursache:} Der Gitea-Runner mountet den Docker-Socket automatisch. Wir hatten ihn zusätzlich im Workflow definiert.
\textbf{Lösung:} Die Zeile \texttt{- /var/run/docker.sock:/var/run/docker.sock} aus dem Workflow entfernen.
\subsubsection{Problem 2: Pfade zu Dockerfiles}
\textbf{Fehlermeldung:} \texttt{open Dockerfile: no such file or directory}
\textbf{Ursache:} Die Dockerfiles lagen in \texttt{apps/api/} und \texttt{apps/web/}, aber der Build-Kontext war das Repository-Root. Relative Pfade funktionierten nicht.
\textbf{Lösung:} Kopien der Dockerfiles (\texttt{Dockerfile.api}, \texttt{Dockerfile.web}) im Root-Verzeichnis angelegt.
\subsubsection{Problem 3: ERR\_PNPM\_IGNORED\_BUILDS}
\textbf{Fehlermeldung:} \texttt{[ERR\_PNPM\_IGNORED\_BUILDS] Ignored build scripts: @swc/core}
\textbf{Ursache:} pnpm verweigert standardmäßig Build-Scripts für Sicherheitsüberprüfung.
\textbf{Lösung:} \texttt{@vitejs/plugin-react-swc} durch \texttt{@vitejs/plugin-react} ersetzt. Keine Build-Scripts mehr nötig.
\subsubsection{Problem 4: Fehlende nginx.conf}
\textbf{Fehlermeldung:} \texttt{"/apps/web/nginx.conf": not found}
\textbf{Ursache:} Die \texttt{nginx.conf} war nicht im Docker-Build-Kontext.
\textbf{Lösung:} \texttt{nginx.conf} ins Root kopiert und \texttt{Dockerfile.web} entsprechend angepasst.
\subsubsection{Problem 5: Container ohne Port-Mapping}
\textbf{Symptom:} \texttt{docker ps} zeigt \texttt{80/tcp} ohne \texttt{0.0.0.0:80->80/tcp}.
\textbf{Ursache:} Die CI/CD-Pipeline startete Container ohne \texttt{-p 80:80}.
\textbf{Lösung:} In der Workflow-Datei explizit \texttt{-p 80:80} zum \texttt{docker run}-Befehl hinzugefügt.
\subsection{Tutorial: Einfache HTML-Seite deployen}
Um den kompletten Prozess von A bis Z zu verstehen, deployen wir eine minimale HTML-Seite.
\subsubsection{Schritt 1: Projekt erstellen}
\begin{lstlisting}[language=Bash, caption={Neues Projekt lokal anlegen}]
cd ~/projects
mkdir hello-ci
cd hello-ci
git init
\end{lstlisting}
\subsubsection{Schritt 2: index.html erstellen}
\begin{lstlisting}[language=HTML, caption={Minimale HTML-Seite}]
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Hello CI/CD</title>
<style>
body { font-family: sans-serif; text-align: center; padding: 50px; }
h1 { color: #059669; }
</style>
</head>
<body>
<h1>Hello CI/CD!</h1>
<p>Diese Seite wurde automatisch deployed.</p>
</body>
</html>
\end{lstlisting}
\subsubsection{Schritt 3: Dockerfile erstellen}
\begin{lstlisting}[language=Dockerfile, caption={Dockerfile für statische HTML-Seite}]
FROM nginx:stable-alpine
COPY index.html /usr/share/nginx/html/index.html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
\end{lstlisting}
\subsubsection{Schritt 4: Workflow erstellen}
\begin{lstlisting}[language=Bash, caption={Verzeichnis anlegen}]
mkdir -p .gitea/workflows
\end{lstlisting}
\begin{lstlisting}[language=YAML, caption={.gitea/workflows/deploy.yaml}]
name: Deploy Hello Page
on:
push:
branches: [ "master" ]
jobs:
deploy:
runs-on: ubuntu-latest
container:
image: catthehacker/ubuntu:act-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build and Deploy
run: |
docker build -t hello-ci:latest .
docker stop hello-ci 2>/dev/null || true
docker rm hello-ci 2>/dev/null || true
docker run -d --name hello-ci -p 8080:80 hello-ci:latest
\end{lstlisting}
\subsubsection{Schritt 5: In Gitea pushen}
\begin{lstlisting}[language=Bash, caption={Push zu Gitea}]
# In Gitea ein neues Repository "hello-ci" anlegen, dann:
git remote add gitea http://185.209.229.167:3000/robre/hello-ci.git
git add .
git commit -m "Initial commit"
git push gitea master
\end{lstlisting}
\subsubsection{Schritt 6: Firewall öffnen und testen}
\begin{lstlisting}[language=Bash, caption={Port 8080 freigeben}]
ssh testserver "ufw allow 8080/tcp"
\end{lstlisting}
Im Browser: \texttt{http://185.209.229.167:8080}
\subsection{Docker-Befehle Cheat Sheet}
\begin{table}[h]
\centering
\caption{Häufig verwendete Docker-Befehle}
\begin{tabular}{@{}lp{8cm}@{}}
\toprule
\textbf{Befehl} & \textbf{Beschreibung} \\
\midrule
\texttt{docker ps} & Laufende Container anzeigen \\
\texttt{docker ps -a} & Alle Container (auch gestoppte) \\
\texttt{docker logs NAME} & Logs eines Containers anzeigen \\
\texttt{docker logs -f NAME} & Logs live verfolgen \\
\texttt{docker stop NAME} & Container stoppen \\
\texttt{docker start NAME} & Container starten \\
\texttt{docker restart NAME} & Container neustarten \\
\texttt{docker rm NAME} & Container löschen \\
\texttt{docker rm -f NAME} & Container erzwingen löschen \\
\texttt{docker exec -it NAME bash} & Shell im Container öffnen \\
\texttt{docker images} & Alle Images anzeigen \\
\texttt{docker network ls} & Netzwerke anzeigen \\
\texttt{docker network inspect NETZ} & Netzwerk-Details \\
\texttt{docker system prune -a} & Ungenutzte Daten löschen \\
\bottomrule
\end{tabular}
\end{table}
\subsection{Zusammenfassung}
Nach diesem Schritt haben wir:
\begin{itemize}
\item Eine vollständige CI/CD-Pipeline mit Gitea Actions
\item Automatisches Build und Deployment bei jedem Push auf master
\item Verständnis aller Docker-Befehle für die tägliche Arbeit
\item Ein komplettes Tutorial zum Nachvollziehen des Prozesses
\item Alle Fehler dokumentiert mit Ursachen und Lösungen
\end{itemize}
+2 -1
View File
@@ -1,7 +1,8 @@
// apps/web/src/api/client.ts
// const API_BASE = "http://localhost:5107";
const API_BASE = "http://192.168.178.189:5107";
// const API_BASE = "http://192.168.178.189:5107";
const API_BASE = "";
export interface Workout {
id?: string;