Add steps for domain purchase and DNS configuration, set up HTTPS with nginx-proxy and Let's Encrypt, and install Gitea as a self-hosted Git server. Remove temporary database files and update assembly info for API project.

This commit is contained in:
2026-05-08 14:53:33 +02:00
parent 0e9377739e
commit b8cfa1689f
15 changed files with 1285 additions and 141 deletions
+224 -72
View File
@@ -10,108 +10,260 @@
\babel@aux{ngerman}{} \babel@aux{ngerman}{}
\BKM@entry{id=1,dest={73656374696F6E2E31},srcline={5}}{5C3337365C3337375C303030535C303030655C303030725C303030765C303030655C303030725C3030302D5C303030415C303030625C303030735C303030695C303030635C303030685C303030655C303030725C303030755C3030306E5C303030675C3030305C3034305C3030305C3035305C303030555C303030625C303030755C3030306E5C303030745C303030755C3030305C3034305C303030325C303030345C3030302E5C303030305C303030345C3030305C3034305C303030615C303030755C303030665C3030305C3034305C303030435C3030306F5C3030306E5C303030745C303030615C303030625C3030306F5C3030305C3034305C303030565C303030505C303030535C3030305C303531} \BKM@entry{id=1,dest={73656374696F6E2E31},srcline={5}}{5C3337365C3337375C303030535C303030655C303030725C303030765C303030655C303030725C3030302D5C303030415C303030625C303030735C303030695C303030635C303030685C303030655C303030725C303030755C3030306E5C303030675C3030305C3034305C3030305C3035305C303030555C303030625C303030755C3030306E5C303030745C303030755C3030305C3034305C303030325C303030345C3030302E5C303030305C303030345C3030305C3034305C303030615C303030755C303030665C3030305C3034305C303030435C3030306F5C3030306E5C303030745C303030615C303030625C3030306F5C3030305C3034305C303030565C303030505C303030535C3030305C303531}
\BKM@entry{id=2,dest={73756273656374696F6E2E312E31},srcline={28}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030315C3030303A5C3030305C3034305C303030535C303030535C303030485C3030302D5C303030565C303030655C303030725C303030625C303030695C3030306E5C303030645C303030755C3030306E5C303030675C3030305C3034305C303030745C303030655C303030735C303030745C303030655C3030306E} \BKM@entry{id=2,dest={73756273656374696F6E2E312E31},srcline={28}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030315C3030303A5C3030305C3034305C303030535C303030535C303030485C3030302D5C303030565C303030655C303030725C303030625C303030695C3030306E5C303030645C303030755C3030306E5C303030675C3030305C3034305C303030745C303030655C303030735C303030745C303030655C3030306E}
\@writefile{toc}{\contentsline {section}{\numberline {1}Server-Absicherung (Ubuntu 24.04 auf Contabo VPS)}{3}{section.1}\protected@file@percent } \@writefile{toc}{\contentsline {section}{\numberline {1}Server-Absicherung (Ubuntu 24.04 auf Contabo VPS)}{4}{section.1}\protected@file@percent }
\newlabel{sec:step01}{{1}{3}{Server-Absicherung (Ubuntu 24.04 auf Contabo VPS)}{section.1}{}} \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}{3}{subsection.1.1}\protected@file@percent } \@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}{3}{lstlisting.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}{3}{lstlisting.2}\protected@file@percent } \@writefile{lol}{\contentsline {lstlisting}{\numberline {2}WARNUNG: REMOTE HOST IDENTIFICATION HAS CHANGED}{4}{lstlisting.2}\protected@file@percent }
\BKM@entry{id=3,dest={73756273656374696F6E2E312E32},srcline={67}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030325C3030303A5C3030305C3034305C303030535C303030795C303030735C303030745C303030655C3030306D5C3030302D5C303030555C303030705C303030645C303030615C303030745C303030655C30303073} \BKM@entry{id=3,dest={73756273656374696F6E2E312E32},srcline={67}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030325C3030303A5C3030305C3034305C303030535C303030795C303030735C303030745C303030655C3030306D5C3030302D5C303030555C303030705C303030645C303030615C303030745C303030655C30303073}
\BKM@entry{id=4,dest={73756273656374696F6E2E312E33},srcline={88}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030335C3030303A5C3030305C3034305C303030535C303030535C303030485C3030302D5C3030304B5C303030655C303030795C3030302D5C303030415C303030755C303030745C303030685C303030655C3030306E5C303030745C303030695C303030665C303030695C3030307A5C303030695C303030655C303030725C303030755C3030306E5C30303067} \BKM@entry{id=4,dest={73756273656374696F6E2E312E33},srcline={88}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030335C3030303A5C3030305C3034305C303030535C303030535C303030485C3030302D5C3030304B5C303030655C303030795C3030302D5C303030415C303030755C303030745C303030685C303030655C3030306E5C303030745C303030695C303030665C303030695C3030307A5C303030695C303030655C303030725C303030755C3030306E5C30303067}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {3}Alten SSH-Fingerabdruck entfernen}{4}{lstlisting.3}\protected@file@percent } \@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}{4}{subsection.1.2}\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}{4}{lstlisting.4}\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}{4}{subsection.1.3}\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}{4}{lstlisting.5}\protected@file@percent } \@writefile{lol}{\contentsline {lstlisting}{\numberline {5}SSH-Key generieren}{5}{lstlisting.5}\protected@file@percent }
\BKM@entry{id=5,dest={73756273656374696F6E2E312E34},srcline={132}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030345C3030303A5C3030305C3034305C303030535C303030535C303030485C3030302D5C303030435C3030306C5C303030695C303030655C3030306E5C303030745C3030302D5C3030304B5C3030306F5C3030306E5C303030665C303030695C303030675C303030755C303030725C303030615C303030745C303030695C3030306F5C3030306E5C3030305C3034305C3030305C3035305C303030415C3030306C5C303030695C303030615C303030735C3030305C303531} \BKM@entry{id=5,dest={73756273656374696F6E2E312E34},srcline={132}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030345C3030303A5C3030305C3034305C303030535C303030535C303030485C3030302D5C303030435C3030306C5C303030695C303030655C3030306E5C303030745C3030302D5C3030304B5C3030306F5C3030306E5C303030665C303030695C303030675C303030755C303030725C303030615C303030745C303030695C3030306F5C3030306E5C3030305C3034305C3030305C3035305C303030415C3030306C5C303030695C303030615C303030735C3030305C303531}
\BKM@entry{id=6,dest={73756273656374696F6E2E312E35},srcline={169}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030355C3030303A5C3030305C3034305C303030535C303030535C303030485C3030302D5C303030545C303030695C3030306D5C303030655C3030306F5C303030755C303030745C3030305C3034305C303030615C303030755C303030665C3030305C3034305C303030325C303030305C3030305C3034305C3030304D5C303030695C3030306E5C303030755C303030745C303030655C3030306E} \BKM@entry{id=6,dest={73756273656374696F6E2E312E35},srcline={169}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030355C3030303A5C3030305C3034305C303030535C303030535C303030485C3030302D5C303030545C303030695C3030306D5C303030655C3030306F5C303030755C303030745C3030305C3034305C303030615C303030755C303030665C3030305C3034305C303030325C303030305C3030305C3034305C3030304D5C303030695C3030306E5C303030755C303030745C303030655C3030306E}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {6}Public Key auf den Server übertragen}{5}{lstlisting.6}\protected@file@percent } \@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}{5}{lstlisting.7}\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)}{5}{subsection.1.4}\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}{5}{lstlisting.8}\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}{5}{lstlisting.9}\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}{5}{lstlisting.10}\protected@file@percent } \@writefile{lol}{\contentsline {lstlisting}{\numberline {10}Mit Alias verbinden}{6}{lstlisting.10}\protected@file@percent }
\BKM@entry{id=7,dest={73756273656374696F6E2E312E36},srcline={203}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030365C3030303A5C3030305C3034305C303030465C303030615C303030695C3030306C5C303030325C303030425C303030615C3030306E5C3030305C3034305C3030305C3035305C303030425C303030725C303030755C303030745C303030655C303030665C3030306F5C303030725C303030635C303030655C3030302D5C303030535C303030635C303030685C303030755C303030745C3030307A5C3030305C303531} \BKM@entry{id=7,dest={73756273656374696F6E2E312E36},srcline={203}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030365C3030303A5C3030305C3034305C303030465C303030615C303030695C3030306C5C303030325C303030425C303030615C3030306E5C3030305C3034305C3030305C3035305C303030425C303030725C303030755C303030745C303030655C303030665C3030306F5C303030725C303030635C303030655C3030302D5C303030535C303030635C303030685C303030755C303030745C3030307A5C3030305C303531}
\@writefile{toc}{\contentsline {subsection}{\numberline {1.5}Schritt 5: SSH-Timeout auf 20 Minuten}{6}{subsection.1.5}\protected@file@percent } \@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}{6}{lstlisting.11}\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}{6}{lstlisting.12}\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}{6}{lstlisting.13}\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)}{6}{subsection.1.6}\protected@file@percent } \@writefile{toc}{\contentsline {subsection}{\numberline {1.6}Schritt 6: Fail2Ban (Bruteforce-Schutz)}{7}{subsection.1.6}\protected@file@percent }
\BKM@entry{id=8,dest={73756273656374696F6E2E312E37},srcline={258}}{5C3337365C3337375C3030305A5C303030755C303030735C303030615C3030306D5C3030306D5C303030655C3030306E5C303030665C303030615C303030735C303030735C303030755C3030306E5C30303067} \BKM@entry{id=8,dest={73756273656374696F6E2E312E37},srcline={258}}{5C3337365C3337375C3030305A5C303030755C303030735C303030615C3030306D5C3030306D5C303030655C3030306E5C303030665C303030615C303030735C303030735C303030755C3030306E5C30303067}
\BKM@entry{id=9,dest={73656374696F6E2E32},srcline={5}}{5C3337365C3337375C303030465C303030695C303030725C303030655C303030775C303030615C3030306C5C3030306C5C3030305C3034305C3030306D5C303030695C303030745C3030305C3034305C303030555C303030465C303030575C3030305C3034305C303030655C303030695C3030306E5C303030725C303030695C303030635C303030685C303030745C303030655C3030306E} \BKM@entry{id=9,dest={73656374696F6E2E32},srcline={5}}{5C3337365C3337375C303030465C303030695C303030725C303030655C303030775C303030615C3030306C5C3030306C5C3030305C3034305C3030306D5C303030695C303030745C3030305C3034305C303030555C303030465C303030575C3030305C3034305C303030655C303030695C3030306E5C303030725C303030695C303030635C303030685C303030745C303030655C3030306E}
\BKM@entry{id=10,dest={73756273656374696F6E2E322E31},srcline={10}}{5C3337365C3337375C303030575C303030615C303030735C3030305C3034305C303030695C303030735C303030745C3030305C3034305C303030655C303030695C3030306E5C303030655C3030305C3034305C303030465C303030695C303030725C303030655C303030775C303030615C3030306C5C3030306C5C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030775C303030615C303030725C303030755C3030306D5C3030305C3034305C303030625C303030725C303030615C303030755C303030635C303030685C303030655C3030306E5C3030305C3034305C303030775C303030695C303030725C3030305C3034305C303030735C303030695C303030655C3030303F} \BKM@entry{id=10,dest={73756273656374696F6E2E322E31},srcline={10}}{5C3337365C3337375C303030575C303030615C303030735C3030305C3034305C303030695C303030735C303030745C3030305C3034305C303030655C303030695C3030306E5C303030655C3030305C3034305C303030465C303030695C303030725C303030655C303030775C303030615C3030306C5C3030306C5C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030775C303030615C303030725C303030755C3030306D5C3030305C3034305C303030625C303030725C303030615C303030755C303030635C303030685C303030655C3030306E5C3030305C3034305C303030775C303030695C303030725C3030305C3034305C303030735C303030695C303030655C3030303F}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {14}Beispiel: /etc/fail2ban/jail.local}{7}{lstlisting.14}\protected@file@percent } \@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}{7}{lstlisting.15}\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}{7}{lstlisting.16}\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}{7}{lstlisting.17}\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}{7}{lstlisting.18}\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}{7}{subsection.1.7}\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}{7}{section.2}\protected@file@percent } \@writefile{toc}{\contentsline {section}{\numberline {2}Firewall mit UFW einrichten}{8}{section.2}\protected@file@percent }
\newlabel{sec:step02}{{2}{7}{Firewall mit UFW einrichten}{section.2}{}} \newlabel{sec:step02}{{2}{8}{Firewall mit UFW einrichten}{section.2}{}}
\BKM@entry{id=11,dest={73756273656374696F6E2E322E32},srcline={21}}{5C3337365C3337375C303030445C303030695C303030655C3030305C3034305C303030365C303030355C3030302E5C303030355C303030335C303030355C3030305C3034305C303030505C3030306F5C303030725C303030745C303030735C3030303A5C3030305C3034305C303030455C303030695C3030306E5C3030305C3034305C3030306B5C303030755C303030725C3030307A5C303030655C303030725C3030305C3034305C3030305C3333345C303030625C303030655C303030725C303030625C3030306C5C303030695C303030635C3030306B} \BKM@entry{id=11,dest={73756273656374696F6E2E322E32},srcline={21}}{5C3337365C3337375C303030445C303030695C303030655C3030305C3034305C303030365C303030355C3030302E5C303030355C303030335C303030355C3030305C3034305C303030505C3030306F5C303030725C303030745C303030735C3030303A5C3030305C3034305C303030455C303030695C3030306E5C3030305C3034305C3030306B5C303030755C303030725C3030307A5C303030655C303030725C3030305C3034305C3030305C3333345C303030625C303030655C303030725C303030625C3030306C5C303030695C303030635C3030306B}
\BKM@entry{id=12,dest={73756273656374696F6E2E322E33},srcline={52}}{5C3337365C3337375C303030445C303030695C303030655C3030305C3034305C303030645C303030725C303030655C303030695C3030305C3034305C303030505C3030306F5C303030725C303030745C303030735C3030302C5C3030305C3034305C303030645C303030695C303030655C3030305C3034305C303030775C303030695C303030725C3030305C3034305C3030305C3336365C303030665C303030665C3030306E5C303030655C3030306E} \BKM@entry{id=12,dest={73756273656374696F6E2E322E33},srcline={52}}{5C3337365C3337375C303030445C303030695C303030655C3030305C3034305C303030645C303030725C303030655C303030695C3030305C3034305C303030505C3030306F5C303030725C303030745C303030735C3030302C5C3030305C3034305C303030645C303030695C303030655C3030305C3034305C303030775C303030695C303030725C3030305C3034305C3030305C3336365C303030665C303030665C3030306E5C303030655C3030306E}
\BKM@entry{id=13,dest={73756273656374696F6E2E322E34},srcline={70}}{5C3337365C3337375C303030575C303030615C303030725C303030755C3030306D5C3030305C3034305C303030485C303030545C303030545C303030505C303030535C3030305C3034305C303030665C3030305C3337345C303030725C3030305C3034305C303030505C303030575C303030415C303030735C3030305C3034305C303030505C303030665C3030306C5C303030695C303030635C303030685C303030745C3030305C3034305C303030695C303030735C30303074} \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?}{8}{subsection.2.1}\protected@file@percent } \@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}{8}{subsection.2.2}\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}}{8}{table.1}\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}{8}{subsection.2.3}\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}{8}{subsection.2.4}\protected@file@percent } \@writefile{toc}{\contentsline {subsection}{\numberline {2.4}Warum HTTPS für PWAs Pflicht ist}{9}{subsection.2.4}\protected@file@percent }
\BKM@entry{id=14,dest={73756273656374696F6E2E322E35},srcline={82}}{5C3337365C3337375C303030445C303030755C303030725C303030635C303030685C303030665C3030305C3337345C303030685C303030725C303030755C3030306E5C30303067} \BKM@entry{id=14,dest={73756273656374696F6E2E322E35},srcline={82}}{5C3337365C3337375C303030445C303030755C303030725C303030635C303030685C303030665C3030305C3337345C303030685C303030725C303030755C3030306E5C30303067}
\BKM@entry{id=15,dest={73756273756273656374696F6E2E322E352E31},srcline={84}}{5C3337365C3337375C303030535C303030745C303030615C3030306E5C303030645C303030615C303030725C303030645C303030725C303030695C303030635C303030685C303030745C3030306C5C303030695C3030306E5C303030695C303030655C3030306E5C3030305C3034305C303030735C303030655C303030745C3030307A5C303030655C3030306E} \BKM@entry{id=15,dest={73756273756273656374696F6E2E322E352E31},srcline={84}}{5C3337365C3337375C303030535C303030745C303030615C3030306E5C303030645C303030615C303030725C303030645C303030725C303030695C303030635C303030685C303030745C3030306C5C303030695C3030306E5C303030695C303030655C3030306E5C3030305C3034305C303030735C303030655C303030745C3030307A5C303030655C3030306E}
\@writefile{lot}{\contentsline {table}{\numberline {2}{\ignorespaces Geöffnete Ports und ihre Begründung}}{9}{table.2}\protected@file@percent } \@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}{9}{subsection.2.5}\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}{9}{subsubsection.2.5.1}\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}{9}{lstlisting.19}\protected@file@percent } \@writefile{lol}{\contentsline {lstlisting}{\numberline {19}Firewall-Standardregeln definieren}{10}{lstlisting.19}\protected@file@percent }
\BKM@entry{id=16,dest={73756273756273656374696F6E2E322E352E32},srcline={105}}{5C3337365C3337375C303030425C303030655C3030306E5C3030305C3336365C303030745C303030695C303030675C303030745C303030655C3030305C3034305C303030505C3030306F5C303030725C303030745C303030735C3030305C3034305C3030305C3336365C303030665C303030665C3030306E5C303030655C3030306E} \BKM@entry{id=16,dest={73756273756273656374696F6E2E322E352E32},srcline={105}}{5C3337365C3337375C303030425C303030655C3030306E5C3030305C3336365C303030745C303030695C303030675C303030745C303030655C3030305C3034305C303030505C3030306F5C303030725C303030745C303030735C3030305C3034305C3030305C3336365C303030665C303030665C3030306E5C303030655C3030306E}
\BKM@entry{id=17,dest={73756273756273656374696F6E2E322E352E33},srcline={125}}{5C3337365C3337375C303030465C303030695C303030725C303030655C303030775C303030615C3030306C5C3030306C5C3030305C3034305C303030615C3030306B5C303030745C303030695C303030765C303030695C303030655C303030725C303030655C3030306E} \BKM@entry{id=17,dest={73756273756273656374696F6E2E322E352E33},srcline={125}}{5C3337365C3337375C303030465C303030695C303030725C303030655C303030775C303030615C3030306C5C3030306C5C3030305C3034305C303030615C3030306B5C303030745C303030695C303030765C303030695C303030655C303030725C303030655C3030306E}
\BKM@entry{id=18,dest={73756273756273656374696F6E2E322E352E34},srcline={141}}{5C3337365C3337375C3030304B5C3030306F5C3030306E5C303030665C303030695C303030675C303030755C303030725C303030615C303030745C303030695C3030306F5C3030306E5C3030305C3034305C3030305C3337345C303030625C303030655C303030725C303030705C303030725C3030305C3337345C303030665C303030655C3030306E} \BKM@entry{id=18,dest={73756273756273656374696F6E2E322E352E34},srcline={141}}{5C3337365C3337375C3030304B5C3030306F5C3030306E5C303030665C303030695C303030675C303030755C303030725C303030615C303030745C303030695C3030306F5C3030306E5C3030305C3034305C3030305C3337345C303030625C303030655C303030725C303030705C303030725C3030305C3337345C303030665C303030655C3030306E}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.5.2}Benötigte Ports öffnen}{10}{subsubsection.2.5.2}\protected@file@percent } \@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}{10}{lstlisting.20}\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}{10}{subsubsection.2.5.3}\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}{10}{lstlisting.21}\protected@file@percent } \@writefile{lol}{\contentsline {lstlisting}{\numberline {21}Firewall aktivieren}{11}{lstlisting.21}\protected@file@percent }
\BKM@entry{id=19,dest={73756273656374696F6E2E322E36},srcline={179}}{5C3337365C3337375C3030305A5C303030755C303030735C303030615C3030306D5C3030306D5C303030655C3030306E5C303030665C303030615C303030735C303030735C303030755C3030306E5C30303067} \BKM@entry{id=19,dest={73756273656374696F6E2E322E36},srcline={179}}{5C3337365C3337375C3030305A5C303030755C303030735C303030615C3030306D5C3030306D5C303030655C3030306E5C303030665C303030615C303030735C303030735C303030755C3030306E5C30303067}
\BKM@entry{id=20,dest={73656374696F6E2E33},srcline={5}}{5C3337365C3337375C303030445C3030306F5C303030635C3030306B5C303030655C303030725C3030302D5C303030495C3030306D5C303030615C303030675C303030655C303030735C3030305C3034305C303030625C303030615C303030755C303030655C3030306E5C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030415C303030705C303030705C3030305C3034305C303030645C303030655C303030705C3030306C5C3030306F5C303030795C303030655C3030306E} \BKM@entry{id=20,dest={73656374696F6E2E33},srcline={5}}{5C3337365C3337375C303030445C3030306F5C303030635C3030306B5C303030655C303030725C3030302D5C303030495C3030306D5C303030615C303030675C303030655C303030735C3030305C3034305C303030625C303030615C303030755C303030655C3030306E5C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030415C303030705C303030705C3030305C3034305C303030645C303030655C303030705C3030306C5C3030306F5C303030795C303030655C3030306E}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.5.4}Konfiguration überprüfen}{11}{subsubsection.2.5.4}\protected@file@percent } \@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}{11}{lstlisting.22}\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)}{11}{lstlisting.23}\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}{11}{subsection.2.6}\protected@file@percent } \@writefile{toc}{\contentsline {subsection}{\numberline {2.6}Zusammenfassung}{12}{subsection.2.6}\protected@file@percent }
\BKM@entry{id=21,dest={73756273656374696F6E2E332E31},srcline={10}}{5C3337365C3337375C303030575C303030615C303030735C3030305C3034305C303030695C303030735C303030745C3030305C3034305C303030445C3030306F5C303030635C3030306B5C303030655C303030725C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030775C303030615C303030725C303030755C3030306D5C3030305C3034305C3030306E5C303030755C303030745C3030307A5C303030655C3030306E5C3030305C3034305C303030775C303030695C303030725C3030305C3034305C303030655C303030735C3030303F} \BKM@entry{id=21,dest={73756273656374696F6E2E332E31},srcline={10}}{5C3337365C3337375C303030575C303030615C303030735C3030305C3034305C303030695C303030735C303030745C3030305C3034305C303030445C3030306F5C303030635C3030306B5C303030655C303030725C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030775C303030615C303030725C303030755C3030306D5C3030305C3034305C3030306E5C303030755C303030745C3030307A5C303030655C3030306E5C3030305C3034305C303030775C303030695C303030725C3030305C3034305C303030655C303030735C3030303F}
\BKM@entry{id=22,dest={73756273656374696F6E2E332E32},srcline={27}}{5C3337365C3337375C303030445C303030695C303030655C3030305C3034305C303030645C303030725C303030655C303030695C3030305C3034305C303030445C3030306F5C303030635C3030306B5C303030655C303030725C303030665C303030695C3030306C5C303030655C303030735C3030305C3034305C303030695C3030306D5C3030305C3034305C303030445C303030655C303030745C303030615C303030695C3030306C} \BKM@entry{id=22,dest={73756273656374696F6E2E332E32},srcline={27}}{5C3337365C3337375C303030445C303030695C303030655C3030305C3034305C303030645C303030725C303030655C303030695C3030305C3034305C303030445C3030306F5C303030635C3030306B5C303030655C303030725C303030665C303030695C3030306C5C303030655C303030735C3030305C3034305C303030695C3030306D5C3030305C3034305C303030445C303030655C303030745C303030615C303030695C3030306C}
\BKM@entry{id=23,dest={73756273756273656374696F6E2E332E322E31},srcline={29}}{5C3337365C3337375C303030425C303030615C303030635C3030306B5C303030655C3030306E5C303030645C3030302D5C303030445C3030306F5C303030635C3030306B5C303030655C303030725C303030665C303030695C3030306C5C303030655C3030303A5C3030305C3034305C303030615C303030705C303030705C303030735C3030302F5C303030615C303030705C303030695C3030302F5C303030445C3030306F5C303030635C3030306B5C303030655C303030725C303030665C303030695C3030306C5C30303065} \BKM@entry{id=23,dest={73756273756273656374696F6E2E332E322E31},srcline={29}}{5C3337365C3337375C303030425C303030615C303030635C3030306B5C303030655C3030306E5C303030645C3030302D5C303030445C3030306F5C303030635C3030306B5C303030655C303030725C303030665C303030695C3030306C5C303030655C3030303A5C3030305C3034305C303030615C303030705C303030705C303030735C3030302F5C303030615C303030705C303030695C3030302F5C303030445C3030306F5C303030635C3030306B5C303030655C303030725C303030665C303030695C3030306C5C30303065}
\@writefile{toc}{\contentsline {section}{\numberline {3}Docker-Images bauen und App deployen}{12}{section.3}\protected@file@percent } \@writefile{toc}{\contentsline {section}{\numberline {3}Docker-Images bauen und App deployen}{13}{section.3}\protected@file@percent }
\newlabel{sec:step03}{{3}{12}{Docker-Images bauen und App deployen}{section.3}{}} \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?}{12}{subsection.3.1}\protected@file@percent } \@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}{12}{subsection.3.2}\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}}{12}{subsubsection.3.2.1}\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}{12}{lstlisting.24}\protected@file@percent } \@writefile{lol}{\contentsline {lstlisting}{\numberline {24}Dockerfile für das .NET Backend}{13}{lstlisting.24}\protected@file@percent }
\BKM@entry{id=24,dest={73756273756273656374696F6E2E332E322E32},srcline={64}}{5C3337365C3337375C303030465C303030725C3030306F5C3030306E5C303030745C303030655C3030306E5C303030645C3030302D5C303030445C3030306F5C303030635C3030306B5C303030655C303030725C303030665C303030695C3030306C5C303030655C3030303A5C3030305C3034305C303030615C303030705C303030705C303030735C3030302F5C303030775C303030655C303030625C3030302F5C303030445C3030306F5C303030635C3030306B5C303030655C303030725C303030665C303030695C3030306C5C30303065} \BKM@entry{id=24,dest={73756273756273656374696F6E2E332E322E32},srcline={64}}{5C3337365C3337375C303030465C303030725C3030306F5C3030306E5C303030745C303030655C3030306E5C303030645C3030302D5C303030445C3030306F5C303030635C3030306B5C303030655C303030725C303030665C303030695C3030306C5C303030655C3030303A5C3030305C3034305C303030615C303030705C303030705C303030735C3030302F5C303030775C303030655C303030625C3030302F5C303030445C3030306F5C303030635C3030306B5C303030655C303030725C303030665C303030695C3030306C5C30303065}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.2.2}Frontend-Dockerfile: \texttt {apps/web/Dockerfile}}{13}{subsubsection.3.2.2}\protected@file@percent } \@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}{13}{lstlisting.25}\protected@file@percent } \@writefile{lol}{\contentsline {lstlisting}{\numberline {25}Dockerfile für das React Frontend}{14}{lstlisting.25}\protected@file@percent }
\BKM@entry{id=25,dest={73756273756273656374696F6E2E332E322E33},srcline={99}}{5C3337365C3337375C3030304E5C303030675C303030695C3030306E5C303030785C3030302D5C3030304B5C3030306F5C3030306E5C303030665C303030695C303030675C303030755C303030725C303030615C303030745C303030695C3030306F5C3030306E5C3030303A5C3030305C3034305C303030615C303030705C303030705C303030735C3030302F5C303030775C303030655C303030625C3030302F5C3030306E5C303030675C303030695C3030306E5C303030785C3030302E5C303030635C3030306F5C3030306E5C30303066} \BKM@entry{id=25,dest={73756273756273656374696F6E2E332E322E33},srcline={99}}{5C3337365C3337375C3030304E5C303030675C303030695C3030306E5C303030785C3030302D5C3030304B5C3030306F5C3030306E5C303030665C303030695C303030675C303030755C303030725C303030615C303030745C303030695C3030306F5C3030306E5C3030303A5C3030305C3034305C303030615C303030705C303030705C303030735C3030302F5C303030775C303030655C303030625C3030302F5C3030306E5C303030675C303030695C3030306E5C303030785C3030302E5C303030635C3030306F5C3030306E5C30303066}
\BKM@entry{id=26,dest={73756273656374696F6E2E332E33},srcline={130}}{5C3337365C3337375C303030445C303030615C303030735C3030305C3034305C303030425C303030615C303030635C3030306B5C303030655C3030306E5C303030645C3030303A5C3030305C3034305C303030505C303030725C3030306F5C303030675C303030725C303030615C3030306D5C3030302E5C303030635C303030735C3030305C3034305C303030695C3030306D5C3030305C3034305C303030445C303030655C303030745C303030615C303030695C3030306C} \BKM@entry{id=26,dest={73756273656374696F6E2E332E33},srcline={130}}{5C3337365C3337375C303030445C303030615C303030735C3030305C3034305C303030425C303030615C303030635C3030306B5C303030655C3030306E5C303030645C3030303A5C3030305C3034305C303030505C303030725C3030306F5C303030675C303030725C303030615C3030306D5C3030302E5C303030635C303030735C3030305C3034305C303030695C3030306D5C3030305C3034305C303030445C303030655C303030745C303030615C303030695C3030306C}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.2.3}Nginx-Konfiguration: \texttt {apps/web/nginx.conf}}{14}{subsubsection.3.2.3}\protected@file@percent } \@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}{14}{lstlisting.26}\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}{15}{subsection.3.3}\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}{15}{lstlisting.27}\protected@file@percent } \@writefile{lol}{\contentsline {lstlisting}{\numberline {27}Vollständige Program.cs}{16}{lstlisting.27}\protected@file@percent }
\BKM@entry{id=27,dest={73756273656374696F6E2E332E34},srcline={186}}{5C3337365C3337375C303030445C303030655C303030725C3030305C3034305C303030415C303030505C303030495C3030302D5C303030435C3030306C5C303030695C303030655C3030306E5C303030745C3030303A5C3030305C3034305C303030635C3030306C5C303030695C303030655C3030306E5C303030745C3030302E5C303030745C303030735C3030305C3034305C303030695C3030306D5C3030305C3034305C303030445C303030655C303030745C303030615C303030695C3030306C} \BKM@entry{id=27,dest={73756273656374696F6E2E332E34},srcline={186}}{5C3337365C3337375C303030445C303030655C303030725C3030305C3034305C303030415C303030505C303030495C3030302D5C303030435C3030306C5C303030695C303030655C3030306E5C303030745C3030303A5C3030305C3034305C303030635C3030306C5C303030695C303030655C3030306E5C303030745C3030302E5C303030745C303030735C3030305C3034305C303030695C3030306D5C3030305C3034305C303030445C303030655C303030745C303030615C303030695C3030306C}
\BKM@entry{id=28,dest={73756273656374696F6E2E332E35},srcline={226}}{5C3337365C3337375C303030445C303030615C303030735C3030305C3034305C303030465C303030725C3030306F5C3030306E5C303030745C303030655C3030306E5C303030645C3030303A5C3030305C3034305C303030415C303030705C303030705C3030302E5C303030745C303030735C303030785C3030305C3034305C303030695C3030306D5C3030305C3034305C303030445C303030655C303030745C303030615C303030695C3030306C} \BKM@entry{id=28,dest={73756273656374696F6E2E332E35},srcline={226}}{5C3337365C3337375C303030445C303030615C303030735C3030305C3034305C303030465C303030725C3030306F5C3030306E5C303030745C303030655C3030306E5C303030645C3030303A5C3030305C3034305C303030415C303030705C303030705C3030302E5C303030745C303030735C303030785C3030305C3034305C303030695C3030306D5C3030305C3034305C303030445C303030655C303030745C303030615C303030695C3030306C}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.4}Der API-Client: client.ts im Detail}{16}{subsection.3.4}\protected@file@percent } \@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}{16}{lstlisting.28}\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}{16}{subsection.3.5}\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}{16}{lstlisting.29}\protected@file@percent } \@writefile{lol}{\contentsline {lstlisting}{\numberline {29}Hauptkomponente mit Workout-Liste und Formular}{17}{lstlisting.29}\protected@file@percent }
\BKM@entry{id=29,dest={73756273656374696F6E2E332E36},srcline={265}}{5C3337365C3337375C303030495C3030306D5C303030615C303030675C303030655C303030735C3030305C3034305C303030625C303030615C303030755C303030655C3030306E} \BKM@entry{id=29,dest={73756273656374696F6E2E332E36},srcline={265}}{5C3337365C3337375C303030495C3030306D5C303030615C303030675C303030655C303030735C3030305C3034305C303030625C303030615C303030755C303030655C3030306E}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.6}Images bauen}{17}{subsection.3.6}\protected@file@percent } \@writefile{toc}{\contentsline {subsection}{\numberline {3.6}Images bauen}{18}{subsection.3.6}\protected@file@percent }
\BKM@entry{id=30,dest={73756273656374696F6E2E332E37},srcline={287}}{5C3337365C3337375C303030495C3030306D5C303030615C303030675C303030655C303030735C3030305C3034305C303030655C303030785C303030705C3030306F5C303030725C303030745C303030695C303030655C303030725C303030655C3030306E5C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030615C303030755C303030665C3030305C3034305C303030645C303030655C3030306E5C3030305C3034305C303030535C303030655C303030725C303030765C303030655C303030725C3030305C3034305C3030306B5C3030306F5C303030705C303030695C303030655C303030725C303030655C3030306E} \BKM@entry{id=30,dest={73756273656374696F6E2E332E37},srcline={287}}{5C3337365C3337375C303030495C3030306D5C303030615C303030675C303030655C303030735C3030305C3034305C303030655C303030785C303030705C3030306F5C303030725C303030745C303030695C303030655C303030725C303030655C3030306E5C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030615C303030755C303030665C3030305C3034305C303030645C303030655C3030306E5C3030305C3034305C303030535C303030655C303030725C303030765C303030655C303030725C3030305C3034305C3030306B5C3030306F5C303030705C303030695C303030655C303030725C303030655C3030306E}
\BKM@entry{id=31,dest={73756273656374696F6E2E332E38},srcline={311}}{5C3337365C3337375C303030435C3030306F5C3030306E5C303030745C303030615C303030695C3030306E5C303030655C303030725C3030305C3034305C303030615C303030755C303030665C3030305C3034305C303030645C303030655C3030306D5C3030305C3034305C303030535C303030655C303030725C303030765C303030655C303030725C3030305C3034305C303030735C303030745C303030615C303030725C303030745C303030655C3030306E} \BKM@entry{id=31,dest={73756273656374696F6E2E332E38},srcline={311}}{5C3337365C3337375C303030435C3030306F5C3030306E5C303030745C303030615C303030695C3030306E5C303030655C303030725C3030305C3034305C303030615C303030755C303030665C3030305C3034305C303030645C303030655C3030306D5C3030305C3034305C303030535C303030655C303030725C303030765C303030655C303030725C3030305C3034305C303030735C303030745C303030615C303030725C303030745C303030655C3030306E}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.7}Images exportieren und auf den Server kopieren}{18}{subsection.3.7}\protected@file@percent } \@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}{18}{lstlisting.30}\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}{18}{subsection.3.8}\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}{18}{lstlisting.31}\protected@file@percent } \@writefile{lol}{\contentsline {lstlisting}{\numberline {31}Docker-Netzwerk, Volume und Container anlegen}{19}{lstlisting.31}\protected@file@percent }
\BKM@entry{id=32,dest={73756273656374696F6E2E332E39},srcline={345}}{5C3337365C3337375C303030415C303030755C303030665C303030675C303030655C303030745C303030725C303030655C303030745C303030655C3030306E5C303030655C3030305C3034305C303030505C303030725C3030306F5C303030625C3030306C5C303030655C3030306D5C303030655C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C3030304C5C3030305C3336365C303030735C303030755C3030306E5C303030675C303030655C3030306E} \BKM@entry{id=32,dest={73756273656374696F6E2E332E39},srcline={345}}{5C3337365C3337375C303030415C303030755C303030665C303030675C303030655C303030745C303030725C303030655C303030745C303030655C3030306E5C303030655C3030305C3034305C303030505C303030725C3030306F5C303030625C3030306C5C303030655C3030306D5C303030655C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C3030304C5C3030305C3336365C303030735C303030755C3030306E5C303030675C303030655C3030306E}
\BKM@entry{id=33,dest={73756273656374696F6E2E332E3130},srcline={372}}{5C3337365C3337375C3030305A5C303030755C303030735C303030615C3030306D5C3030306D5C303030655C3030306E5C303030665C303030615C303030735C303030735C303030755C3030306E5C30303067} \BKM@entry{id=33,dest={73756273656374696F6E2E332E3130},srcline={372}}{5C3337365C3337375C3030305A5C303030755C303030735C303030615C3030306D5C3030306D5C303030655C3030306E5C303030665C303030615C303030735C303030735C303030755C3030306E5C30303067}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.9}Aufgetretene Probleme und Lösungen}{19}{subsection.3.9}\protected@file@percent } \@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.10}Zusammenfassung}{20}{subsection.3.10}\protected@file@percent } \BKM@entry{id=34,dest={73656374696F6E2E34},srcline={5}}{5C3337365C3337375C303030445C3030306F5C3030306D5C303030615C303030695C3030306E5C3030305C3034305C3030306B5C303030615C303030755C303030665C303030655C3030306E5C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030445C3030304E5C303030535C3030305C3034305C3030306B5C3030306F5C3030306E5C303030665C303030695C303030675C303030755C303030725C303030695C303030655C303030725C303030655C3030306E}
\global\@namedef{scr@dte@section@lastmaxnumwidth}{11.00392pt} \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 }
\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 }
\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}
\BKM@entry{id=44,dest={73756273756273656374696F6E2E342E342E36},srcline={109}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030745C303030745C3030305C3034305C303030365C3030303A5C3030305C3034305C303030425C303030655C303030735C303030745C303030655C3030306C5C3030306C5C303030755C3030306E5C303030675C3030305C3034305C303030615C303030625C303030735C303030635C303030685C3030306C5C303030695C303030655C3030305C3333375C303030655C3030306E}
\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 }
\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 }
\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 }
\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 }
\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 }
\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 }
\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}
\BKM@entry{id=66,dest={73756273656374696F6E2E352E36},srcline={258}}{5C3337365C3337375C303030485C3030305C3334345C303030755C303030665C303030695C303030675C303030655C3030305C3034305C303030465C303030655C303030685C3030306C5C303030655C303030725C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030695C303030685C303030725C303030655C3030305C3034305C303030425C303030655C303030685C303030655C303030625C303030755C3030306E5C30303067}
\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 }
\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 }
\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 }
\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 }
\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 }
\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 }
\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 }
\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 }
\global\@namedef{scr@dte@section@lastmaxnumwidth}{11.59192pt}
\global\@namedef{scr@dte@subsection@lastmaxnumwidth}{24.81589pt} \global\@namedef{scr@dte@subsection@lastmaxnumwidth}{24.81589pt}
\global\@namedef{scr@dte@subsubsection@lastmaxnumwidth}{28.41586pt} \global\@namedef{scr@dte@subsubsection@lastmaxnumwidth}{29.13585pt}
\@writefile{toc}{\providecommand\tocbasic@end@toc@file{}\tocbasic@end@toc@file} \@writefile{toc}{\providecommand\tocbasic@end@toc@file{}\tocbasic@end@toc@file}
\gdef \@abspage@last{20} \gdef \@abspage@last{39}
+10 -7
View File
@@ -1,7 +1,7 @@
# Fdb version 4 # Fdb version 4
["pdflatex"] 1778081248.77398 "/home/computer/projects/fitness-app/LateX/main.tex" "main.pdf" "main" 1778081251.03276 0 ["pdflatex"] 1778244769.05929 "/home/computer/projects/fitness-app/LateX/main.tex" "main.pdf" "main" 1778244771.97073 0
"/etc/texmf/web2c/texmf.cnf" 1776891072.07073 475 c0e671620eb5563b2130f56340a5fde8 "" "/etc/texmf/web2c/texmf.cnf" 1776891072.07073 475 c0e671620eb5563b2130f56340a5fde8 ""
"/home/computer/projects/fitness-app/LateX/main.tex" 1778081236.97865 8413 41aad5c5d32e893cafb487728bf379a6 "" "/home/computer/projects/fitness-app/LateX/main.tex" 1778244681.19007 8476 4f7793f213e99c2fab6230bc8d2163a2 ""
"/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_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_d67aat.enc" 1570828436 3385 21a7e8c8dac3c39de5acda2c56e7bd7e ""
"/usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_iln36p.enc" 1570828436 3071 cfa92ee28d698dd9275559d9d1c3a233 "" "/usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_iln36p.enc" 1570828436 3071 cfa92ee28d698dd9275559d9d1c3a233 ""
@@ -134,13 +134,16 @@
"/usr/share/texmf/web2c/texmf.cnf" 1707919699 40399 f2c302f7d2af602abb742093540a5834 "" "/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/fonts/map/pdftex/updmap/pdftex.map" 1776891108.46284 5472669 54eaf61a88b6b7896ebd0dac973cb29c ""
"/var/lib/texmf/web2c/pdftex/pdflatex.fmt" 1776891271 8211336 7fc26d317f030a4855527787ba3b41d3 "" "/var/lib/texmf/web2c/pdftex/pdflatex.fmt" 1776891271 8211336 7fc26d317f030a4855527787ba3b41d3 ""
"main.aux" 1778081250.91843 23846 804a4d87b04ab7403c0abdcb70108b86 "pdflatex" "main.aux" 1778244771.83832 63855 4c52e1a5c85714f95fa215552b7321a7 "pdflatex"
"main.out" 1778081250.30135 0 d41d8cd98f00b204e9800998ecf8427e "pdflatex" "main.out" 1778244770.69833 0 d41d8cd98f00b204e9800998ecf8427e "pdflatex"
"main.tex" 1778081236.97865 8413 41aad5c5d32e893cafb487728bf379a6 "" "main.tex" 1778244681.19007 8476 4f7793f213e99c2fab6230bc8d2163a2 ""
"main.toc" 1778081250.92443 3404 2187def0eadc57fc64da16e547916901 "pdflatex" "main.toc" 1778244771.85532 9953 4cb30a3bd0faa13d5f22ee47f5497472 "pdflatex"
"step_01.tex" 1778074119.30934 10807 dd7fc11a20ecebed2f07638ceddcf838 "" "step_01.tex" 1778074119.30934 10807 dd7fc11a20ecebed2f07638ceddcf838 ""
"step_02.tex" 1778074524.52004 9161 30219f0c68c4ae118067f27c09a123fb "" "step_02.tex" 1778074524.52004 9161 30219f0c68c4ae118067f27c09a123fb ""
"step_03.tex" 1778081246.2535 17575 0dde7ed301abaec40a3b2d19357b160b "" "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 ""
(generated) (generated)
"main.aux" "main.aux"
"main.log" "main.log"
+10 -1
View File
@@ -234,7 +234,6 @@ INPUT /usr/share/texlive/texmf-dist/tex/latex/fira/T1FiraMono-TOsF.fd
INPUT /usr/share/texlive/texmf-dist/tex/latex/fira/T1FiraMono-TOsF.fd INPUT /usr/share/texlive/texmf-dist/tex/latex/fira/T1FiraMono-TOsF.fd
INPUT /usr/share/texlive/texmf-dist/tex/latex/fira/T1FiraMono-TOsF.fd INPUT /usr/share/texlive/texmf-dist/tex/latex/fira/T1FiraMono-TOsF.fd
INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/fira/FiraMono-Regular-tosf-t1.tfm INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/fira/FiraMono-Regular-tosf-t1.tfm
OUTPUT main.toc
INPUT /usr/share/texlive/texmf-dist/fonts/vf/public/fira/FiraSans-Bold-osf-t1.vf INPUT /usr/share/texlive/texmf-dist/fonts/vf/public/fira/FiraSans-Bold-osf-t1.vf
INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/fira/FiraSans-Bold-osf-t1--base.tfm INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/fira/FiraSans-Bold-osf-t1--base.tfm
INPUT /usr/share/texlive/texmf-dist/fonts/vf/public/fira/FiraSans-Regular-osf-t1.vf INPUT /usr/share/texlive/texmf-dist/fonts/vf/public/fira/FiraSans-Regular-osf-t1.vf
@@ -242,6 +241,7 @@ INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/fira/FiraSans-Regular-osf-t
INPUT /usr/share/texlive/texmf-dist/fonts/vf/public/fira/FiraMono-Regular-tosf-t1.vf INPUT /usr/share/texlive/texmf-dist/fonts/vf/public/fira/FiraMono-Regular-tosf-t1.vf
INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/fira/FiraMono-Regular-tosf-t1--base.tfm INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/fira/FiraMono-Regular-tosf-t1--base.tfm
INPUT /usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_d4q673.enc INPUT /usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_d4q673.enc
OUTPUT main.toc
INPUT ./step_01.tex INPUT ./step_01.tex
INPUT ./step_01.tex INPUT ./step_01.tex
INPUT step_01.tex INPUT step_01.tex
@@ -273,6 +273,15 @@ INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/fira/FiraMono-Bold-tosf-t1-
INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/fira/FiraMono-Oblique-tosf-t1.tfm INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/fira/FiraMono-Oblique-tosf-t1.tfm
INPUT /usr/share/texlive/texmf-dist/fonts/vf/public/fira/FiraMono-Oblique-tosf-t1.vf INPUT /usr/share/texlive/texmf-dist/fonts/vf/public/fira/FiraMono-Oblique-tosf-t1.vf
INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/fira/FiraMono-Oblique-tosf-t1--base.tfm INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/fira/FiraMono-Oblique-tosf-t1--base.tfm
INPUT ./step_04.tex
INPUT ./step_04.tex
INPUT step_04.tex
INPUT ./step_05.tex
INPUT ./step_05.tex
INPUT step_05.tex
INPUT ./step_06.tex
INPUT ./step_06.tex
INPUT step_06.tex
INPUT main.aux INPUT main.aux
INPUT ./main.out INPUT ./main.out
INPUT ./main.out INPUT ./main.out
+82 -26
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) 6 MAY 2026 17:27 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
entering extended mode entering extended mode
restricted \write18 enabled. restricted \write18 enabled.
file:line:error style messages enabled. file:line:error style messages enabled.
@@ -628,13 +628,13 @@ Package microtype Info: Loading generic protrusion settings for font family
(microtype) `FiraMono-TOsF' (encoding: T1). (microtype) `FiraMono-TOsF' (encoding: T1).
(microtype) For optimal results, create family-specific settings. (microtype) For optimal results, create family-specific settings.
(microtype) See the microtype manual for details. (microtype) See the microtype manual for details.
) [2
{/usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_d4q673.enc}])
\tf@toc=\write4 \tf@toc=\write4
\openout4 = `main.toc'. \openout4 = `main.toc'.
[2 [3] (./step_01.tex
{/usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_d4q673.enc}] (./step_01.tex
LaTeX Font Info: Trying to load font information for TS1+FiraSans-OsF on input line 21. 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 (/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. 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. (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 LaTeX Font Info: Font shape `T1/FiraSans-OsF/regular/n' will be
(Font) scaled to size 10.0pt on input line 36. (Font) scaled to size 10.0pt on input line 36.
[3 [4
{/usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_d67aat.enc}] [4] {/usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_d67aat.enc}] [5]
LaTeX Font Info: Font shape `T1/FiraMono-TOsF/b/n' in size <10> not available 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. (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 LaTeX Font Info: Font shape `T1/FiraMono-TOsF/bold/n' will be
(Font) scaled to size 8.99994pt on input line 140. (Font) scaled to size 8.99994pt on input line 140.
[5] [6]
Package Listings Warning: Text dropped after begin of listing on input line 221. Package Listings Warning: Text dropped after begin of listing on input line 221.
[6]) (./step_02.tex [7] [7]) (./step_02.tex [8]
Underfull \hbox (badness 10000) in paragraph at lines 63--64 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- []|\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'. LaTeX Warning: `h' float specifier changed to `ht'.
[8] [9]
Overfull \hbox (3.891pt too wide) in paragraph at lines 77--78 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) []\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)
[] []
[9] [10]) (./step_03.tex [11] [10] [11]) (./step_03.tex [12]
LaTeX Font Info: Font shape `T1/FiraMono-TOsF/b/n' in size <12> not available 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. (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 LaTeX Font Info: Font shape `T1/FiraMono-TOsF/bold/n' will be
(Font) scaled to size 10.79993pt on input line 29. (Font) scaled to size 10.79993pt on input line 29.
[12] [13] [13] [14]
Overfull \hbox (74.52446pt too wide) in paragraph at lines 125--126 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 []\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) ) []\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) )
[] []
[14] [15] [15] [16]
LaTeX Font Info: Font shape `T1/FiraMono-TOsF/m/it' in size <10> not available 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. (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 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) . []\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) .
[] []
[16] [17] [18] [17] [18] [19]
Overfull \hbox (10.69511pt too wide) in paragraph at lines 341--342 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- []\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,63 @@ 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) . []\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) .
[] []
[19]) [20] (./main.aux) [20]) (./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-
[]
Underfull \hbox (badness 2150) in paragraph at lines 38--39
[]|\T1/FiraSans-OsF/regular/n/12 (+20) Definiert, wel-che Na-me-ser-ver
[]
LaTeX Warning: `h' float specifier changed to `ht'.
[21] [22] [23]
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
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]
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]
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.
[]
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]
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]
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) :
[]
LaTeX Warning: `h' float specifier changed to `ht'.
[34] [35] [36]
Overfull \hbox (70.29362pt too wide) in paragraph at lines 197--208
[][]
[]
[37] [38]) [39] (./main.aux)
*********** ***********
LaTeX2e <2023-11-01> patch level 1 LaTeX2e <2023-11-01> patch level 1
L3 programming layer <2024-01-22> L3 programming layer <2024-01-22>
@@ -756,18 +812,18 @@ Package rerunfilecheck Info: File `main.out' has not changed.
(rerunfilecheck) Checksum: D41D8CD98F00B204E9800998ECF8427E;0. (rerunfilecheck) Checksum: D41D8CD98F00B204E9800998ECF8427E;0.
) )
Here is how much of TeX's memory you used: Here is how much of TeX's memory you used:
19894 strings out of 474222 20493 strings out of 474222
343688 string characters out of 5748733 351901 string characters out of 5748733
2200975 words of memory out of 5000000 2292975 words of memory out of 5000000
41353 multiletter control sequences out of 15000+600000 41569 multiletter control sequences out of 15000+600000
692737 words of font info for 213 fonts, out of 8000000 for 9000 697305 words of font info for 241 fonts, out of 8000000 for 9000
1141 hyphenation exceptions out of 8191 1141 hyphenation exceptions out of 8191
108i,10n,107p,10941b,2229s stack positions out of 10000i,1000n,20000p,200000b,200000s 108i,11n,107p,10941b,2229s 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> </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 (20 pages, 300891 bytes). Output written on main.pdf (39 pages, 374479 bytes).
PDF statistics: PDF statistics:
651 PDF objects out of 1000 (max. 8388607) 1350 PDF objects out of 1440 (max. 8388607)
609 compressed objects within 7 object streams 1283 compressed objects within 13 object streams
336 named destinations out of 1000 (max. 500000) 668 named destinations out of 1000 (max. 500000)
45833 words of extra memory for PDF output out of 51595 (max. 10000000) 46297 words of extra memory for PDF output out of 51595 (max. 10000000)
BIN
View File
Binary file not shown.
Binary file not shown.
+3
View File
@@ -246,6 +246,9 @@
\input{step_01.tex} \input{step_01.tex}
\input{step_02.tex} \input{step_02.tex}
\input{step_03.tex} \input{step_03.tex}
\input{step_04.tex}
\input{step_05.tex}
\input{step_06.tex}
% Weitere Kapitel folgen hier: % Weitere Kapitel folgen hier:
% \input{step_02.tex} % \input{step_02.tex}
+95 -33
View File
@@ -1,35 +1,97 @@
\babel@toc {ngerman}{}\relax \babel@toc {ngerman}{}\relax
\contentsline {section}{\numberline {1}Server-Absicherung (Ubuntu 24.04 auf Contabo VPS)}{3}{section.1}% \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}{3}{subsection.1.1}% \contentsline {subsection}{\numberline {1.1}Schritt 1: SSH-Verbindung testen}{4}{subsection.1.1}%
\contentsline {subsection}{\numberline {1.2}Schritt 2: System-Updates}{4}{subsection.1.2}% \contentsline {subsection}{\numberline {1.2}Schritt 2: System-Updates}{5}{subsection.1.2}%
\contentsline {subsection}{\numberline {1.3}Schritt 3: SSH-Key-Authentifizierung}{4}{subsection.1.3}% \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)}{5}{subsection.1.4}% \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}{6}{subsection.1.5}% \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)}{6}{subsection.1.6}% \contentsline {subsection}{\numberline {1.6}Schritt 6: Fail2Ban (Bruteforce-Schutz)}{7}{subsection.1.6}%
\contentsline {subsection}{\numberline {1.7}Zusammenfassung}{7}{subsection.1.7}% \contentsline {subsection}{\numberline {1.7}Zusammenfassung}{8}{subsection.1.7}%
\contentsline {section}{\numberline {2}Firewall mit UFW einrichten}{7}{section.2}% \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?}{8}{subsection.2.1}% \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}{8}{subsection.2.2}% \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}{8}{subsection.2.3}% \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}{8}{subsection.2.4}% \contentsline {subsection}{\numberline {2.4}Warum HTTPS für PWAs Pflicht ist}{9}{subsection.2.4}%
\contentsline {subsection}{\numberline {2.5}Durchführung}{9}{subsection.2.5}% \contentsline {subsection}{\numberline {2.5}Durchführung}{10}{subsection.2.5}%
\contentsline {subsubsection}{\numberline {2.5.1}Standardrichtlinien setzen}{9}{subsubsection.2.5.1}% \contentsline {subsubsection}{\numberline {2.5.1}Standardrichtlinien setzen}{10}{subsubsection.2.5.1}%
\contentsline {subsubsection}{\numberline {2.5.2}Benötigte Ports öffnen}{10}{subsubsection.2.5.2}% \contentsline {subsubsection}{\numberline {2.5.2}Benötigte Ports öffnen}{11}{subsubsection.2.5.2}%
\contentsline {subsubsection}{\numberline {2.5.3}Firewall aktivieren}{10}{subsubsection.2.5.3}% \contentsline {subsubsection}{\numberline {2.5.3}Firewall aktivieren}{11}{subsubsection.2.5.3}%
\contentsline {subsubsection}{\numberline {2.5.4}Konfiguration überprüfen}{11}{subsubsection.2.5.4}% \contentsline {subsubsection}{\numberline {2.5.4}Konfiguration überprüfen}{12}{subsubsection.2.5.4}%
\contentsline {subsection}{\numberline {2.6}Zusammenfassung}{11}{subsection.2.6}% \contentsline {subsection}{\numberline {2.6}Zusammenfassung}{12}{subsection.2.6}%
\contentsline {section}{\numberline {3}Docker-Images bauen und App deployen}{12}{section.3}% \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?}{12}{subsection.3.1}% \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}{12}{subsection.3.2}% \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}}{12}{subsubsection.3.2.1}% \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}}{13}{subsubsection.3.2.2}% \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}}{14}{subsubsection.3.2.3}% \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}{15}{subsection.3.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}{16}{subsection.3.4}% \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}{16}{subsection.3.5}% \contentsline {subsection}{\numberline {3.5}Das Frontend: App.tsx im Detail}{17}{subsection.3.5}%
\contentsline {subsection}{\numberline {3.6}Images bauen}{17}{subsection.3.6}% \contentsline {subsection}{\numberline {3.6}Images bauen}{18}{subsection.3.6}%
\contentsline {subsection}{\numberline {3.7}Images exportieren und auf den Server kopieren}{18}{subsection.3.7}% \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}{18}{subsection.3.8}% \contentsline {subsection}{\numberline {3.8}Container auf dem Server starten}{19}{subsection.3.8}%
\contentsline {subsection}{\numberline {3.9}Aufgetretene Probleme und Lösungen}{19}{subsection.3.9}% \contentsline {subsection}{\numberline {3.9}Aufgetretene Probleme und Lösungen}{20}{subsection.3.9}%
\contentsline {subsection}{\numberline {3.10}Zusammenfassung}{20}{subsection.3.10}% \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}%
\providecommand \tocbasic@end@toc@file {}\tocbasic@end@toc@file \providecommand \tocbasic@end@toc@file {}\tocbasic@end@toc@file
+211
View File
@@ -0,0 +1,211 @@
% ============================================
% STEP 04: DOMAIN KAUFEN & DNS KONFIGURIEREN
% ============================================
\section{Domain kaufen und DNS konfigurieren}
\label{sec:step04}
In diesem Schritt kaufen wir eine eigene Domain und verknüpfen sie mit unserem Server, damit die Fitness-App unter einem eigenen Namen (nicht nur der IP-Adresse) weltweit erreichbar ist. Wir machen das direkt bei unserem Server-Anbieter Contabo das spart Verwaltungsaufwand, weil alles unter einem Dach bleibt.
\subsection{Warum eine eigene Domain?}
Bisher ist unsere App unter \texttt{http://185.209.229.167} erreichbar. Das hat mehrere Nachteile:
\begin{itemize}
\item \textbf{Schwer zu merken:} Niemand kann sich IP-Adressen merken.
\item \textbf{Kein HTTPS:} Für ein SSL-Zertifikat braucht man eine Domain. Ohne HTTPS keine PWA-Installation!
\item \textbf{Unprofessionell:} Eine eigene Domain wirkt seriös und vertrauenswürdig.
\item \textbf{Flexibel:} Wenn du später den Server wechselst, änderst du einfach den DNS-Eintrag. Die Domain bleibt gleich.
\end{itemize}
\subsection{Grundlagen: Wie funktioniert das DNS?}
DNS steht für \textbf{Domain Name System}. Es ist das "Telefonbuch des Internets" und übersetzt menschenlesbare Domain-Namen in maschinenlesbare IP-Adressen.
\textbf{Die wichtigsten Record-Typen:}
\begin{table}[h]
\centering
\caption{DNS-Record-Typen und ihre Funktion}
\begin{tabular}{@{}clp{6cm}@{}}
\toprule
\textbf{Typ} & \textbf{Name} & \textbf{Funktion} \\
\midrule
A & Address Record & Verbindet eine Domain mit einer IPv4-Adresse. "robre.de $\rightarrow$ 185.209.229.167" \\
AAAA & IPv6 Address Record & Wie A-Record, aber für IPv6-Adressen \\
CNAME & Canonical Name & Verweist eine Domain auf eine andere Domain (Alias) \\
MX & Mail Exchange & Legt fest, welcher Server E-Mails für die Domain empfängt \\
NS & Name Server & Definiert, welche Nameserver für die Domain zuständig sind \\
TXT & Text Record & Enthält beliebige Textinformationen (z. B. für SPF, DKIM) \\
\bottomrule
\end{tabular}
\end{table}
\textbf{Wie eine DNS-Auflösung abläuft:}
\begin{enumerate}
\item Du gibst \texttt{robre.de} in den Browser ein.
\item Dein Rechner fragt seinen DNS-Resolver (meist bei deinem Internet-Provider): "Welche IP hat \texttt{robre.de}?"
\item Der Resolver fragt die Root-Nameserver, dann die .de-Nameserver, dann Contabos Nameserver.
\item Contabo antwortet: \texttt{robre.de = 185.209.229.167}
\item Der Browser stellt eine HTTP-Verbindung zu dieser IP her.
\item Deine App erscheint!
\end{enumerate}
\subsection{Was ist DNS-Propagation?}
Wenn du DNS-Einträge änderst, dauert es eine Weile, bis alle DNS-Server weltweit die neuen Informationen haben. Das nennt man \textbf{Propagation} (Verbreitung).
\begin{itemize}
\item \textbf{Dauer:} Meist 15 Minuten bis 2 Stunden, in seltenen Fällen bis zu 48 Stunden.
\item \textbf{Grund:} Jeder DNS-Resolver hat einen Cache (Zwischenspeicher) mit alten Einträgen. Erst wenn der Cache abläuft (TTL = Time To Live), wird der aktuelle Wert abgefragt.
\item \textbf{TTL-Wert:} Unsere Einträge haben TTL 86400 = 24 Stunden. Deshalb kann es länger dauern, bis alte Caches verfallen sind.
\end{itemize}
\textbf{Tipp:} Mit dem Befehl \texttt{nslookup robre.de ns1.contabo.net} fragst du \textbf{direkt} bei Contabos Nameserver an ohne Cache. So siehst du sofort, ob die Konfiguration stimmt, auch wenn dein lokaler DNS die Domain noch nicht kennt.
\subsection{Domain-Kauf bei Contabo}
\subsubsection{Schritt 1: Einloggen ins Kundencenter}
Unter \texttt{https://contabo.com} mit deinen Zugangsdaten anmelden.
\subsubsection{Schritt 2: Domain bestellen}
\begin{enumerate}
\item In der linken Seitenleiste auf \textbf{"Domains"} klicken.
\item Auf den blauen Button \textbf{"Domain bestellen"} klicken.
\item Wunschname eingeben (z. B. "robre") und Endung auswählen (.de, .com, .net, etc.).
\item Auf "Weiter" klicken.
\end{enumerate}
\subsubsection{Schritt 3: Domain-Handles konfigurieren}
Auf der nächsten Seite werden die sogenannten \textbf{Domain-Handles} (Kontaktdaten) abgefragt:
\begin{itemize}
\item \textbf{Owner / Besitzer:} Der rechtmäßige Eigentümer der Domain. Das sollte immer eine Privatperson oder Firma sein NIEMALS der Provider!
\item \textbf{Admin:} Der administrative Ansprechpartner. Meist dieselbe Person wie der Owner.
\item \textbf{Tech:} Der technische Ansprechpartner. Hier kann der Provider stehen (Contabo GmbH).
\item \textbf{Zone:} Zonenverwaltung. Ebenfalls Contabo GmbH.
\end{itemize}
\textbf{Standardwerte übernehmen:} Für Tech und Zone einfach die vorausgefüllte Contabo GmbH lassen. Das vereinfacht die technische Verwaltung.
\subsubsection{Schritt 4: Nameserver festlegen}
Auf der nächsten Seite wählst du die Nameserver:
\begin{itemize}
\item \textbf{Contabo Standard-Nameserver} auswählen (ns1.contabo.net, ns2.contabo.net, ns3.contabo.net).
\item Das bedeutet: Contabo verwaltet die DNS-Einträge für dich. Du kannst sie jederzeit im Kundencenter ändern.
\end{itemize}
\subsubsection{Schritt 5: IP-Adresse auswählen}
Hier wählst du aus, auf welchen deiner Server die Domain zeigen soll. In unserem Fall:
\begin{itemize}
\item Server \textbf{"test"} mit IP \texttt{185.209.229.167}
\item Server \textbf{"prod"} mit IP \texttt{185.209.230.235}
\end{itemize}
\textbf{Empfehlung:} Nur die erste IP (\texttt{185.209.229.167}) auswählen, da dort unsere App läuft. Man kann später weitere Einträge hinzufügen.
\subsubsection{Schritt 6: Bestellung abschließen}
Die Zusammenfassung prüfen und auf \textbf{"Bestellen \& Bezahlen"} klicken.
\subsection{DNS-Einträge für die Domain einrichten}
Nach dem Kauf muss die Domain noch mit unserer Server-IP verknüpft werden. Das machen wir im \textbf{DNS Zone Management}.
\subsubsection{Schritt 1: DNS Zone Management öffnen}
Im Contabo Control Panel: \textbf{Netzwerkdienste $\rightarrow$ DNS-Verwaltung} oder direkter: \textbf{Netzwerkdienste $\rightarrow$ "DNS-Zone für [deine Domain] bearbeiten"}.
\subsubsection{Schritt 2: Notwendige A-Records anlegen}
Wir brauchen drei A-Records:
\begin{enumerate}
\item \textbf{Hauptdomain ohne Subdomain:}
\begin{itemize}
\item Name: \texttt{robre.de}
\item Typ: A
\item Data: \texttt{185.209.229.167}
\item TTL: \texttt{86400}
\end{itemize}
\item \textbf{www-Subdomain:}
\begin{itemize}
\item Name: \texttt{www.robre.de}
\item Typ: A
\item Data: \texttt{185.209.229.167}
\item TTL: \texttt{86400}
\end{itemize}
\item \textbf{Wildcard für alle anderen Subdomains (optional, aber nützlich):}
\begin{itemize}
\item Name: \texttt{*.robre.de}
\item Typ: A
\item Data: \texttt{185.209.229.167}
\item TTL: \texttt{86400}
\end{itemize}
\end{enumerate}
\textbf{Warum alle drei?}
\begin{itemize}
\item \texttt{robre.de} die Hauptdomain, die die meisten Nutzer eingeben.
\item \texttt{www.robre.de} viele Nutzer geben aus Gewohnheit "www." ein.
\item \texttt{*.robre.de} fängt alle zukünftigen Subdomains ab (z. B. \texttt{app.robre.de}, \texttt{api.robre.de}), ohne dass wir jedes Mal einen neuen Eintrag anlegen müssen.
\end{itemize}
\subsection{DNS-Propagation prüfen und beschleunigen}
\subsubsection{Direkt beim Nameserver prüfen}
Dieser Befehl fragt \textbf{direkt} Contabos Nameserver an ohne Cache. Wenn hier die richtige IP erscheint, ist die Konfiguration korrekt und wir müssen nur auf die weltweite Verbreitung warten.
\begin{lstlisting}[language=Bash, caption={DNS direkt bei Contabo abfragen}]
nslookup robre.de ns1.contabo.net
\end{lstlisting}
\textbf{Ausgabe bei korrekter Konfiguration:}
\begin{lstlisting}[language=Bash, caption={Erwartete Ausgabe}]
Server: ns1.contabo.net
Address: 2a02:c207:ff00:1200::1#53
Name: robre.de
Address: 185.209.229.167
\end{lstlisting}
\subsubsection{Lokalen DNS-Cache leeren}
Manchmal hat dein Rechner noch alte DNS-Einträge im Cache. So löschst du ihn:
\begin{lstlisting}[language=Bash, caption={DNS-Cache leeren unter Linux mit systemd-resolved}]
sudo resolvectl flush-caches
\end{lstlisting}
\subsubsection{Server direkt über IP prüfen}
Um sicherzugehen, dass der Server selbst erreichbar ist (unabhängig von DNS), testen wir mit curl:
\begin{lstlisting}[language=Bash, caption={Server direkt über IP testen}]
curl -I http://185.209.229.167
\end{lstlisting}
\textbf{Erwartete Ausgabe:}
\begin{lstlisting}[language=Bash, caption={Server antwortet korrekt}]
HTTP/1.1 200 OK
Server: nginx/1.30.0
Content-Type: text/html
...
\end{lstlisting}
\texttt{HTTP/1.1 200 OK} bedeutet: Der Server läuft, die App ist erreichbar. Das Problem liegt ausschließlich an der DNS-Verbreitung.
\subsubsection{Online DNS-Checker verwenden}
Websites wie \texttt{https://dnschecker.org} oder \texttt{https://whatsmydns.net} zeigen an, von welchen Standorten weltweit die Domain bereits aufgelöst wird. Praktisches Werkzeug, um den Fortschritt der Propagation zu verfolgen!
\subsection{Zusammenfassung}
Nach diesem Schritt haben wir:
\begin{itemize}
\item Eine eigene Domain \texttt{robre.de} für 11,88 \texteuro\ / Jahr
\item DNS-Einträge, die auf unsere Server-IP \texttt{185.209.229.167} zeigen
\item Geprüft, dass Contabo die Domain korrekt registriert hat
\item Geprüft, dass der Server direkt über die IP erreichbar ist
\item DNS-Propagation abwarten, bis die Domain weltweit funktioniert
\end{itemize}
Als nächstes folgt die Einrichtung von HTTPS mit einem kostenlosen SSL-Zertifikat das ist die Voraussetzung für die PWA-Installation!
+323
View File
@@ -0,0 +1,323 @@
\section{HTTPS mit nginx-proxy und Let's Encrypt}
\label{sec:step05}
In diesem Schritt richten wir \textbf{HTTPS} für unsere Domain ein. Dafür nutzen wir zwei Docker-Container: \texttt{nginx-proxy} als Reverse Proxy und \texttt{acme-companion} für automatische SSL-Zertifikate von Let's Encrypt. Nach diesem Schritt ist unsere App unter \texttt{https://robre.de} erreichbar und erfüllt alle Voraussetzungen für die PWA-Installation.
\subsection{Warum brauchen wir HTTPS?}
HTTP (Hypertext Transfer Protocol) sendet alle Daten im \textbf{Klartext}. Ein Angreifer im gleichen Netzwerk kann mitlesen, manipulieren oder die Verbindung kapern. HTTPS (HTTP Secure) verschlüsselt die gesamte Kommunikation zwischen Browser und Server mittels TLS (Transport Layer Security).
\textbf{Für Progressive Web Apps ist HTTPS zwingend vorgeschrieben:}
\begin{itemize}
\item Der \textbf{Service Worker} das Herzstück einer PWA funktioniert nur mit HTTPS
\item Browser verweigern die PWA-Installation bei unverschlüsselten Verbindungen
\item Moderne Browser-APIs (Geolocation, Kamera, Push-Benachrichtigungen) erfordern HTTPS
\end{itemize}
\subsection{Wie funktioniert das SSL-Zertifikat von Let's Encrypt?}
\textbf{Let's Encrypt} ist eine kostenlose Zertifizierungsstelle (Certificate Authority). Der Ablauf der Zertifikatserstellung läuft automatisch nach dem \textbf{ACME-Protokoll} (Automatic Certificate Management Environment):
\begin{enumerate}
\item Der \texttt{acme-companion} fordert ein Zertifikat für \texttt{robre.de} an
\item Let's Encrypt stellt eine \textbf{Challenge} eine Aufgabe, die beweist, dass du die Domain kontrollierst
\item Der \texttt{acme-companion} legt eine temporäre Datei auf deinem Webserver ab
\item Let's Encrypt prüft, ob diese Datei unter \texttt{http://robre.de/.well-known/acme-challenge/...} erreichbar ist
\item Wenn ja: Zertifikat wird ausgestellt und automatisch in den nginx eingebunden
\item Das Zertifikat ist 90 Tage gültig und wird automatisch erneuert
\end{enumerate}
\textbf{Wichtige Voraussetzung:} Die Domain muss weltweit über DNS erreichbar sein (\textbf{DNS-Propagation}). Ohne funktionierende DNS-Auflösung schlägt die Challenge fehl Let's Encrypt kann die Domain nicht finden und verweigert die Zertifikatsausstellung.
\subsection{DNS-Propagation: Wie lange dauert es?}
Wenn du eine neue Domain registrierst oder DNS-Einträge änderst, dauert es eine Weile, bis alle DNS-Server weltweit die neuen Informationen kennen. Diesen Prozess nennt man \textbf{DNS-Propagation}.
\begin{itemize}
\item \textbf{Normale Dauer:} 15 Minuten bis 2 Stunden
\item \textbf{Maximale Dauer:} Bis zu 48 Stunden (in seltenen Fällen)
\item \textbf{Beeinflussender Faktor:} Der \textbf{TTL-Wert} (Time To Live) der DNS-Einträge. Unser Wert von 86400 Sekunden (24 Stunden) erlaubt anderen DNS-Servern, die Information bis zu 24 Stunden zwischenzuspeichern.
\end{itemize}
\textbf{So prüfst du den Status der Propagation:}
\begin{lstlisting}[language=Bash, caption={DNS-Auflösung lokal prüfen}]
# Über deinen Standard-DNS-Resolver
nslookup robre.de
# Direkt bei Contabos Nameserver (ohne Cache)
nslookup robre.de ns1.contabo.net
# Über Googles öffentlichen DNS (8.8.8.8)
nslookup robre.de 8.8.8.8
\end{lstlisting}
Erscheint als Antwort \texttt{185.209.229.167}, ist die Propagation für diesen Server abgeschlossen. Erscheint \texttt{NXDOMAIN} (Non-Existent Domain), kennt der DNS-Server die Domain noch nicht.
\textbf{Online-Tool zur weltweiten Prüfung:} \texttt{https://dnschecker.org} zeigt auf einer Weltkarte, an welchen Standorten die Domain bereits aufgelöst wird.
\subsection{Architektur: Wie hängen die Container zusammen?}
Nach diesem Schritt sieht unsere Docker-Infrastruktur so aus:
\begin{verbatim}
Internet
|
| HTTPS (Port 443)
v
nginx-proxy (Reverse Proxy)
|
+-- robre.de --> fitness-web (Port 80)
| |
| | /api/* --> fitness-api (Port 5000)
|
+-- SSL-Zertifikate von acme-companion verwaltet
\end{verbatim}
\textbf{Erklärung der Komponenten:}
\begin{itemize}
\item \texttt{nginx-proxy}: Empfängt alle HTTP/HTTPS-Anfragen und leitet sie an den richtigen Container weiter. Entscheidet anhand des \texttt{Host}-Headers (enthält die Domain), welcher Container die Anfrage bekommt.
\item \texttt{acme-companion}: Überwacht laufende Container auf die Umgebungsvariable \texttt{LETSENCRYPT\_HOST}. Wenn eine neue Domain auftaucht, fordert er automatisch ein SSL-Zertifikat an und konfiguriert nginx.
\item \texttt{fitness-web}: Unser React-Frontend mit Nginx. Braucht selbst kein SSL der Proxy übernimmt die Verschlüsselung.
\item \texttt{fitness-api}: Unser .NET-Backend. Nur über das interne Docker-Netzwerk erreichbar, nicht direkt von außen.
\end{itemize}
\subsection{Schritt-für-Schritt: HTTPS einrichten}
\subsubsection{Schritt 1: Bestehende Container stoppen und löschen}
Da wir von manuellen \texttt{docker run}-Befehlen auf \texttt{docker compose} umsteigen, müssen die alten Container entfernt werden.
\begin{lstlisting}[language=Bash, caption={Alte Container stoppen und löschen}]
ssh testserver
docker stop fitness-web fitness-api
docker rm fitness-web fitness-api
\end{lstlisting}
\subsubsection{Schritt 2: Verzeichnis für docker-compose anlegen}
\begin{lstlisting}[language=Bash, caption={Projektverzeichnis auf dem Server}]
mkdir -p /opt/fitness
cd /opt/fitness
\end{lstlisting}
\subsubsection{Schritt 3: docker-compose.yml erstellen}
\texttt{docker compose} ist ein Tool, mit dem wir mehrere Container als \textbf{eine Einheit} definieren und verwalten können. Statt vier einzelner \texttt{docker run}-Befehle definieren wir alle Container in einer YAML-Datei.
Erstelle die Datei mit \texttt{nano /opt/fitness/docker-compose.yml}:
\begin{lstlisting}[language=YAML, caption={Vollständige docker-compose.yml}]
services:
# ============================================
# REVERSE PROXY (nimmt HTTP/HTTPS-Anfragen entgegen)
# ============================================
nginx-proxy:
image: nginxproxy/nginx-proxy
container_name: nginx-proxy
restart: unless-stopped
ports:
- ''80:80''
- ''443:443''
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- certs:/etc/nginx/certs
- vhost:/etc/nginx/vhost.d
- html:/usr/share/nginx/html
networks:
- proxy-net
# ============================================
# SSL-ZERTIFIKATE (automatisch via Let's Encrypt)
# ============================================
acme-companion:
image: nginxproxy/acme-companion
container_name: acme-companion
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- certs:/etc/nginx/certs
- vhost:/etc/nginx/vhost.d
- html:/usr/share/nginx/html
- acme:/etc/acme.sh
environment:
- DEFAULT_EMAIL=robert@robre.de
- NGINX_PROXY_CONTAINER=nginx-proxy
depends_on:
- nginx-proxy
networks:
- proxy-net
# ============================================
# BACKEND (.NET 8 API)
# ============================================
backend:
image: fitness-api:latest
container_name: fitness-api
restart: unless-stopped
volumes:
- fitness-data:/app/data
networks:
- proxy-net
# ============================================
# FRONTEND (React + Nginx)
# ============================================
frontend:
image: fitness-web:latest
container_name: fitness-web
restart: unless-stopped
environment:
- VIRTUAL_HOST=robre.de,www.robre.de
- LETSENCRYPT_HOST=robre.de,www.robre.de
- VIRTUAL_PORT=80
depends_on:
- backend
networks:
- proxy-net
# ============================================
# VOLUMES (persistente Datenspeicher)
# ============================================
volumes:
certs:
vhost:
html:
acme:
fitness-data:
# ============================================
# NETZWERKE
# ============================================
networks:
proxy-net:
driver: bridge
\end{lstlisting}
\textbf{Zeile für Zeile erklärt:}
\paragraph{nginx-proxy}
\begin{itemize}
\item \texttt{image: nginxproxy/nginx-proxy} Offizielles Image des nginx-proxy-Projekts.
\item \texttt{ports: ''80:80'' / ''443:443''} Nur dieser Container lauscht auf den Standard-Webports. Alle HTTP/HTTPS-Anfragen kommen hier an.
\item \texttt{/var/run/docker.sock:/tmp/docker.sock:ro} Bindet den Docker-Socket ein (read-only). Darüber erkennt nginx-proxy, welche Container gerade laufen und welche Domains sie bedienen.
\item \texttt{certs:/etc/nginx/certs} Hier speichert der acme-companion die SSL-Zertifikate.
\end{itemize}
\paragraph{acme-companion}
\begin{itemize}
\item \texttt{DEFAULT\_EMAIL} Für Let's-Encrypt-Benachrichtigungen (z. B. wenn ein Zertifikat abläuft). \textbf{Muss eine echte, erreichbare E-Mail-Adresse sein!}
\item \texttt{NGINX\_PROXY\_CONTAINER=nginx-proxy} Sagt dem acme-companion explizit, wie der Proxy-Container heißt. Notwendig, wenn der Container-Name vom Standard abweicht.
\item \texttt{depends\_on: nginx-proxy} Stellt sicher, dass der Proxy zuerst startet.
\end{itemize}
\paragraph{frontend (entscheidende Umgebungsvariablen!)}
\begin{itemize}
\item \texttt{VIRTUAL\_HOST=robre.de,www.robre.de} Sagt nginx-proxy: ''Ich bin für diese Domains zuständig''. Alle Anfragen an \texttt{robre.de} oder \texttt{www.robre.de} werden an diesen Container weitergeleitet.
\item \texttt{LETSENCRYPT\_HOST=robre.de,www.robre.de} Sagt acme-companion: ''Hol SSL-Zertifikate für diese Domains''.
\item \texttt{VIRTUAL\_PORT=80} Der interne Port, auf dem der Container lauscht (unser Nginx im Frontend-Container).
\end{itemize}
\paragraph{Docker Volumes}
\begin{itemize}
\item \texttt{certs, vhost, html, acme} Speichern SSL-Zertifikate, Konfiguration und Challenge-Dateien. Diese Volumes werden von nginx-proxy und acme-companion geteilt.
\item \texttt{fitness-data} Persistente Speicherung der SQLite-Datenbank (siehe Schritt 03).
\end{itemize}
\subsubsection{Schritt 4: Container starten}
\begin{lstlisting}[language=Bash, caption={Alle Container im Hintergrund starten}]
cd /opt/fitness
docker compose up -d
\end{lstlisting}
\texttt{-d} steht für \textbf{detached} die Container laufen im Hintergrund und blockieren nicht das Terminal.
\subsubsection{Schritt 5: Status prüfen}
\begin{lstlisting}[language=Bash, caption={Laufende Container anzeigen}]
docker ps
\end{lstlisting}
Es sollten vier Container erscheinen: \texttt{nginx-proxy}, \texttt{acme-companion}, \texttt{fitness-api}, \texttt{fitness-web}.
\subsubsection{Schritt 6: Logs des acme-companion prüfen}
\begin{lstlisting}[language=Bash, caption={SSL-Zertifikatserstellung verfolgen}]
docker logs -f acme-companion
\end{lstlisting}
Bei erfolgreicher Zertifikatserstellung erscheinen diese Meldungen:
\begin{lstlisting}[language=Bash, caption={Erfolgreiche Ausgabe}]
[Thu May 7 09:56:11 UTC 2026] Registered
[Thu May 7 09:56:14 UTC 2026] Account update success
Creating/renewal robre.de certificates... (robre.de www.robre.de)
\end{lstlisting}
\subsection{Häufige Fehler und ihre Behebung}
\subsubsection{Fehler 1: ''can't get nginx-proxy container ID''}
\textbf{Ursache:} Der acme-companion findet den Proxy-Container nicht, weil dieser einen individuellen Namen hat (\texttt{nginx-proxy} statt dem Standard).
\textbf{Lösung:} Die Umgebungsvariable \texttt{NGINX\_PROXY\_CONTAINER=nginx-proxy} im acme-companion setzen (wie oben bereits eingebaut).
\subsubsection{Fehler 2: ''contact email has forbidden domain''}
\textbf{Ursache:} Die \texttt{DEFAULT\_EMAIL} enthält eine ungültige Domain wie \texttt{@example.com} Let's Encrypt lehnt reservierte Domains ab.
\textbf{Lösung:} Eine echte, erreichbare E-Mail-Adresse verwenden (z. B. \texttt{robert@robre.de}).
\subsubsection{Fehler 3: ''DNS problem: NXDOMAIN''}
\textbf{Ursache:} Die DNS-Propagation ist noch nicht abgeschlossen. Let's Encrypt kann die Domain nicht auflösen und verweigert die Zertifikatsausstellung.
\textbf{Lösung:} Warten, bis die Domain weltweit erreichbar ist (bis zu 24 Stunden). Dann den acme-companion neustarten:
\begin{lstlisting}[language=Bash, caption={Zertifikatserstellung erneut anstoßen}]
docker restart acme-companion
\end{lstlisting}
\subsection{Wie füge ich später weitere Subdomains hinzu?}
Das System ist extrem flexibel. Angenommen, du willst später eine Todo-App unter \texttt{todo.robre.de} hosten:
\begin{enumerate}
\item \textbf{DNS-Eintrag beim Hoster:} Einen neuen A-Record für \texttt{todo.robre.de} anlegen, der auf dieselbe Server-IP \texttt{185.209.229.167} zeigt. Oder: Der Wildcard-Eintrag \texttt{*.robre.de} fängt automatisch alle nicht explizit definierten Subdomains ab!
\item \textbf{Docker-Container:} Einen neuen Container mit den Umgebungsvariablen \texttt{VIRTUAL\_HOST=todo.robre.de} und \texttt{LETSENCRYPT\_HOST=todo.robre.de} starten.
\item \textbf{Fertig!} nginx-proxy erkennt den neuen Container automatisch und leitet Anfragen weiter. acme-companion holt automatisch ein SSL-Zertifikat.
\end{enumerate}
\textbf{Du musst auf dem Server nichts weiter konfigurieren alles läuft automatisch!}
\subsection{Wie funktioniert der Reverse Proxy im Detail?}
Wenn eine Anfrage an \texttt{https://robre.de/api/workouts} eingeht:
\begin{enumerate}
\item Die Anfrage kommt an Port 443 des Servers an (HTTPS).
\item nginx-proxy nimmt die Anfrage entgegen und entschlüsselt sie mit dem SSL-Zertifikat.
\item nginx-proxy schaut in den \texttt{Host}-Header: \texttt{robre.de}.
\item In seiner Konfiguration findet er: \texttt{robre.de} → Container \texttt{fitness-web}, Port 80.
\item Er leitet die Anfrage an \texttt{fitness-web:80} weiter (internes Docker-Netzwerk).
\item Der Nginx im Frontend-Container empfängt die Anfrage an \texttt{/api/workouts}.
\item Seine Konfiguration sagt: Alles mit \texttt{/api/} → weiterleiten an \texttt{fitness-api:5000}.
\item Das Backend verarbeitet die Anfrage und schickt die Antwort zurück durch die gesamte Kette.
\end{enumerate}
\textbf{Die gesamte Kommunikation innerhalb des Docker-Netzwerks (Schritte 5-8) läuft unverschlüsselt das ist okay, weil sie den Server nie verlässt.}
\subsection{Zusammenfassung}
Nach diesem Schritt haben wir:
\begin{itemize}
\item Einen automatischen Reverse Proxy (nginx-proxy), der Anfragen an die richtigen Container verteilt
\item Kostenlose SSL-Zertifikate von Let's Encrypt, die sich automatisch erneuern
\item Eine Infrastruktur, die beliebig viele weitere Domains und Subdomains aufnehmen kann ohne manuelle Konfiguration
\item Die App ist unter \texttt{https://robre.de} verschlüsselt erreichbar
\item Alle Voraussetzungen für die PWA-Installation sind erfüllt
\end{itemize}
\textbf{Wartezeit beachten:} Nach der Einrichtung kann es bis zu 24 Stunden dauern, bis die DNS-Propagation abgeschlossen ist und Let's Encrypt die Zertifikate ausstellen kann. Der acme-companion versucht es automatisch jede Stunde erneut.
+325
View File
@@ -0,0 +1,325 @@
% ============================================
% STEP 06: GITEA INSTALLATION & SERVER-ÜBERSICHT
% ============================================
\section{Gitea Installation und Server-Übersicht}
\label{sec:step06}
In diesem Schritt installieren wir \textbf{Gitea} einen selbst gehosteten Git-Server mit Web-Oberfläche als Ersatz für OneDev, das sich leider als fehlerhaft erwies. Am Ende dieses Kapitels hast du einen vollständigen Überblick über deinen Server: welche Container laufen, welche Ports offen sind, wo die Daten liegen und wie alles zusammenhängt.
\subsection{Warum ein eigener Git-Server?}
Bisher haben wir den Code manuell gebaut, als Docker-Image exportiert und per \texttt{scp} auf den Server kopiert ein umständlicher Prozess, der bei jedem Update wiederholt werden muss. Ein eigener Git-Server mit CI/CD-Pipeline automatisiert diesen Ablauf:
\begin{itemize}
\item \textbf{Push = Deploy:} Code auf den Server pushen, Pipeline baut automatisch Docker-Images und startet Container neu
\item \textbf{Versionierung:} Alle Änderungen sind nachvollziehbar, kein „das ging gestern noch"-Problem
\item \textbf{Teamarbeit:} Mehrere Entwickler können gleichzeitig am Projekt arbeiten
\item \textbf{Backup:} Das Repository liegt auf deinem Server, nicht bei GitHub/GitLab
\end{itemize}
\subsection{OneDev: Der gescheiterte Versuch}
Ursprünglich wollten wir \textbf{OneDev} installieren eine All-in-One-Lösung aus Git-Server, CI/CD-Pipeline, Issue-Tracker und Paket-Registry. OneDev bietet deutlich mehr Funktionen als Gitea, erwies sich jedoch als problematisch:
\subsubsection{Installationsversuch mit Docker (Version \texttt{1dev/server:latest})}
\begin{lstlisting}[language=YAML, caption={docker-compose.yml für OneDev}]
services:
onedev:
image: 1dev/server:latest
container_name: onedev
restart: unless-stopped
ports:
- "6610:6610"
- "6611:6611"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- onedev_data:/opt/onedev
volumes:
onedev_data:
\end{lstlisting}
\textbf{Aufgetretene Probleme:}
\begin{enumerate}
\item \textbf{Container stoppt sofort:} Nach dem Start erschien in den Logs nur „INFO - Stopping application". Der Container beendete sich ohne Fehlermeldung.
\item \textbf{Workaround mit fester Version:} Statt \texttt{latest} nutzten wir \texttt{1dev/server:11.6.13} gleiches Problem.
\item \textbf{Datenbank-Fehler:} Die entscheidende Fehlermeldung in \texttt{/opt/onedev/logs/server.log}:
\begin{lstlisting}[language=Bash, caption={Kritischer Fehler beim OneDev-Start}]
java.lang.IllegalStateException: EntityManagerFactory is closed
at org.hibernate.internal.SessionFactoryImpl.validateNotClosed(...)
\end{lstlisting}
\textbf{Ursache:} OneDevs interne H2-Datenbank wurde beim ersten Start korrupt. Der Befehl \texttt{upgrade /opt/onedev} im Start-Script versuchte, eine nicht existierende Datenbank zu aktualisieren statt sie neu anzulegen. Selbst komplettes Löschen des Volumes und Neustart behoben das Problem nicht die Logs wurden nach dem ersten Crash nicht mehr aktualisiert, der Container hing fest.
\item \textbf{Versuch mit direkter Java-Installation:} Nachdem Docker scheiterte, luden wir die JAR-Datei herunter (57 Bytes defekter Download) und stellten fest, dass Java nicht installiert war. Zu diesem Zeitpunkt war klar: Der Aufwand für OneDev steht in keinem Verhältnis zum Nutzen.
\end{enumerate}
\textbf{Fazit:} OneDev ist ein mächtiges Tool, aber die Docker-Images sind instabil. Für einen produktiven Einsatz wäre eine native Installation mit externer PostgreSQL-Datenbank empfehlenswert für unsere Zwecke überdimensioniert.
\subsection{Gitea: Die schlanke Alternative}
\textbf{Gitea} ist ein in Go geschriebener Git-Server, der sich durch Einfachheit und geringe Ressourcenanforderungen auszeichnet. Im Vergleich zu OneDev:
\begin{table}[h]
\centering
\caption{Vergleich OneDev vs. Gitea}
\begin{tabular}{@{}p{3cm}ll@{}}
\toprule
\textbf{Merkmal} & \textbf{OneDev} & \textbf{Gitea} \\
\midrule
Größe Image & $\sim$500 MB & $\sim$100 MB \\
Startzeit & 25 Minuten & $\sim$5 Sekunden \\
CI/CD & h Eingebaut & x Extern (z.B. Woodpecker CI) \\
Datenbank & H2 (intern, fehleranfällig) & SQLite3, PostgreSQL, MySQL \\
Komplexität & Hoch & Gering \\
Installation & Fehlgeschlagen & h In 10 Sekunden \\
\bottomrule
\end{tabular}
\end{table}
\subsection{Gitea mit Docker installieren}
\subsubsection{Schritt 1: OneDev rückstandslos entfernen}
\begin{lstlisting}[language=Bash, caption={OneDev komplett löschen}]
cd /opt/onedev
docker compose down 2>/dev/null # Container stoppen
cd /
rm -rf /opt/onedev # Verzeichnis löschen
docker system prune -af # Ungenutzte Images/Volumes entfernen
\end{lstlisting}
\texttt{docker system prune -af} löscht:
\begin{itemize}
\item Alle gestoppten Container
\item Alle ungenutzten Netzwerke
\item Alle ungenutzten Images
\item Alle ungenutzten Build-Caches
\end{itemize}
Insgesamt wurden 806 MB Speicher freigegeben!
\subsubsection{Schritt 2: Gitea-Verzeichnis und docker-compose.yml anlegen}
\begin{lstlisting}[language=Bash, caption={Gitea-Verzeichnis vorbereiten}]
mkdir -p /opt/gitea
nano /opt/gitea/docker-compose.yml
\end{lstlisting}
\begin{lstlisting}[language=YAML, caption={docker-compose.yml für Gitea}]
services:
gitea:
image: gitea/gitea:latest
container_name: gitea
restart: unless-stopped
ports:
- "3000:3000" # Web-UI
- "2222:22" # SSH für Git-Operationen
volumes:
- gitea_data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
volumes:
gitea_data:
\end{lstlisting}
\textbf{Erklärung der Konfiguration:}
\begin{itemize}
\item \texttt{ports: "3000:3000"} Die Web-Oberfläche ist auf Port 3000 erreichbar
\item \texttt{ports: "2222:22"} Git-Operationen per SSH laufen auf Port 2222 (weil Port 22 bereits vom Host-SSH belegt ist)
\item \texttt{gitea\_data:/data} Alle Gitea-Daten (Repositories, Konfiguration, Datenbank) liegen in diesem Volume
\item \texttt{/etc/timezone:/etc/timezone:ro} Übergibt die Zeitzone des Hosts an den Container (\texttt{ro} = read-only)
\item \texttt{/etc/localtime:/etc/localtime:ro} Übergibt die lokale Zeit
\end{itemize}
\subsubsection{Schritt 3: Container starten}
\begin{lstlisting}[language=Bash, caption={Gitea starten}]
cd /opt/gitea
docker compose up -d
\end{lstlisting}
Ausgabe:
\begin{lstlisting}[language=Bash, caption={Erfolgreicher Start}]
[+] up 9/9
h Image gitea/gitea:latest Pulled
h Network gitea_default Created
h Volume gitea_gitea_data Created
h Container gitea Started
\end{lstlisting}
\subsubsection{Schritt 4: Firewall öffnen}
\begin{lstlisting}[language=Bash, caption={Port 3000 freigeben}]
ufw allow 3000/tcp
\end{lstlisting}
\subsubsection{Schritt 5: Gitea im Browser einrichten}
\textbf{URL:} \texttt{http://185.209.229.167:3000}
Beim ersten Aufruf erscheint die Installationsseite. Folgende Einstellungen sind vorausgefüllt und können übernommen werden:
\begin{itemize}
\item \textbf{Datenbanktyp:} SQLite3 (einfachste Option, perfekt für kleine Teams)
\item \textbf{Pfad:} \texttt{/data/gitea/gitea.db}
\item \textbf{Server-Domain:} \texttt{185.209.229.167}
\item \textbf{Gitea-Basis-URL:} \texttt{http://185.209.229.167:3000/}
\item \textbf{SSH-Server-Port:} 22
\item \textbf{Gitea-HTTP-Listen-Port:} 3000
\end{itemize}
\textbf{Wichtig:} Unter „Administratoreninstellungen" (ganz unten aufklappen) musst du einen Admin-Account anlegen:
\begin{itemize}
\item \textbf{Benutzername:} robert
\item \textbf{Passwort:} [dein sicheres Passwort]
\item \textbf{E-Mail:} robert@robre.de
\end{itemize}
Dann auf \textbf{„Gitea installieren"} klicken. Nach wenigen Sekunden ist Gitea einsatzbereit.
\subsection{Vollständige Server-Übersicht}
Nach diesem Schritt ergibt sich folgendes Gesamtbild deines Servers:
\subsubsection{Laufende Docker-Container}
\begin{table}[h]
\centering
\caption{Alle laufenden Container auf dem Server}
\begin{tabular}{@{}llll@{}}
\toprule
\textbf{Container} & \textbf{Image} & \textbf{Ports} & \textbf{Aufgabe} \\
\midrule
\texttt{gitea} & \texttt{gitea/gitea:latest} & 3000, 2222→22 & Git-Server mit Web-UI \\
\texttt{nginx-proxy} & \texttt{nginxproxy/nginx-proxy} & 80, 443 & Reverse Proxy \\
\texttt{acme-companion} & \texttt{nginxproxy/acme-companion} & & SSL-Zertifikate (Let's Encrypt) \\
\texttt{fitness-web} & \texttt{fitness-web:latest} & 80 (intern) & React-Frontend \\
\texttt{fitness-api} & \texttt{fitness-api:latest} & 5000 (intern) & .NET 8 Backend \\
\bottomrule
\end{tabular}
\end{table}
\subsubsection{Docker-Volumes (persistente Datenspeicher)}
\begin{table}[h]
\centering
\caption{Volumes und ihre Inhalte}
\begin{tabular}{@{}ll@{}}
\toprule
\textbf{Volume} & \textbf{Inhalt} \\
\midrule
\texttt{gitea\_gitea\_data} & Gitea: Repositories, Datenbank, Konfiguration \\
\texttt{fitness\_fitness-data} & Fitness-App: SQLite-Datenbank (\texttt{/app/data}) \\
\texttt{fitness\_certs} & SSL-Zertifikate von Let's Encrypt \\
\texttt{fitness\_html} & Challenge-Dateien für Let's Encrypt \\
\texttt{fitness\_vhost} & Nginx-Konfiguration pro Virtual Host \\
\texttt{fitness\_acme} & ACME-Kontodaten \\
\bottomrule
\end{tabular}
\end{table}
\subsubsection{Firewall (nur diese Ports sind offen!)}
\begin{table}[h]
\centering
\caption{Geöffnete Ports}
\begin{tabular}{@{}cll@{}}
\toprule
\textbf{Port} & \textbf{Dienst} & \textbf{Begründung} \\
\midrule
22 & SSH & Server-Verwaltung \\
80 & HTTP & Fitness-App, leitet auf HTTPS um \\
443 & HTTPS & Fitness-App (verschlüsselt), PWA-Pflicht! \\
3000 & Gitea Web & Git-Server-Oberfläche \\
\bottomrule
\end{tabular}
\end{table}
\subsubsection{Installierte Systempakete}
\begin{itemize}
\item \texttt{docker-ce}, \texttt{docker-ce-cli}, \texttt{docker-compose-plugin} Docker-Plattform
\item \texttt{fail2ban} Bruteforce-Schutz für SSH
\item \texttt{git} Git (von Gitea genutzt)
\end{itemize}
Der Server ist bewusst schlank gehalten keine überflüssigen Dienste, keine unnötigen Pakete.
\subsubsection{Verzeichnisstruktur unter /opt}
\begin{lstlisting}[language=Bash, caption={Projektverzeichnisse auf dem Server}]
/opt/
containerd/ # Docker-Laufzeitumgebung
fitness/ # docker-compose.yml fuer Fitness-App
docker-compose.yml
gitea/ # docker-compose.yml fuer Gitea
docker-compose.yml
\end{lstlisting}
\subsection{Wie Gitea in die Infrastruktur passt}
\textbf{Aktueller Datenfluss:}
\textbf{Aktueller Datenfluss:}
\begin{verbatim}
Du (lokal) Server (testserver)
--------- ------------------
git push ----------------> Gitea (Port 3000/2222)
|
| (spaeter: CI/CD-Pipeline)
v
Docker-Images bauen
|
v
Container neustarten
|
v
nginx-proxy (Port 80/443)
|
+-------+-------+
| |
v v
fitness-web fitness-api
(Port 80) (Port 5000)
\end{verbatim}
\textbf{Was noch fehlt:} Die CI/CD-Pipeline in Gitea (z.B. mit Gitea Actions oder Woodpecker CI), die automatisch bei jedem Push Docker-Images baut und die Container aktualisiert. Das folgt in einem späteren Schritt.
\subsection{Zusammenfassung}
Nach diesem Schritt haben wir:
\begin{itemize}
\item OneDev aufgrund von Docker-Inkompatibilitäten verworfen
\item Gitea erfolgreich mit Docker installiert (in unter 1 Minute!)
\item Einen vollständigen Überblick über alle Container, Volumes, Ports und Verzeichnisse
\item Die Grundlage für eine spätere CI/CD-Pipeline geschaffen
\end{itemize}
\textbf{Nützliche Befehle für die tägliche Verwaltung:}
\begin{lstlisting}[language=Bash, caption={Server-Cockpit wichtige Befehle}]
# Alle laufenden Container
docker ps
# Alle Volumes
docker volume ls
# Firewall-Status
ufw status verbose
# Installierte Pakete
apt list --installed | grep -E "docker|fail2ban"
# Verzeichnisse unter /opt
ls -la /opt/
\end{lstlisting}
Binary file not shown.
Binary file not shown.
@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("Api")] [assembly: System.Reflection.AssemblyCompanyAttribute("Api")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+2f2cbed5bd2f55d8f0fc2abb891b6a20e42ef8ea")] [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+0e9377739ecf945e0da1e75a85e0a06a95cd0d00")]
[assembly: System.Reflection.AssemblyProductAttribute("Api")] [assembly: System.Reflection.AssemblyProductAttribute("Api")]
[assembly: System.Reflection.AssemblyTitleAttribute("Api")] [assembly: System.Reflection.AssemblyTitleAttribute("Api")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
@@ -1 +1 @@
7fae9bde5435323ac2efd9b5650e0c40dbec5642bd7d43db47980db6bb51f424 ffe41f120d57867c590b01993978902e9fec8bbb7e05b266dbeabfa061be576e