\documentclass{article}

\usepackage[utf8]{inputenc}
\usepackage{helvet}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}
\usepackage{multicol}[]
\usepackage{blindtext}
\usepackage{float}
\usepackage{booktabs}
\usepackage{makecell}

\usepackage{fancyhdr}
\usepackage{geometry}
\usepackage{abstract}
\usepackage{graphicx}
\usepackage{acronym}
\usepackage{hyperref}

\usepackage{amsmath}
\usepackage{xcolor}
\usepackage{listings}

\usepackage{tikz}
\usetikzlibrary{positioning,arrows.meta,fit,backgrounds}

\usepackage{biblatex}

% Lstlisting-Stil für YAML-Beispiele
\definecolor{lstbg}{rgb}{0.97,0.97,0.97}
\definecolor{lstkw}{rgb}{0.10,0.30,0.65}
\definecolor{lstcm}{rgb}{0.40,0.40,0.40}
\lstdefinelanguage{yaml}{
	keywords={true,false,null},
	keywordstyle=\color{lstkw}\bfseries,
	sensitive=false,
	comment=[l]{\#},
	commentstyle=\color{lstcm}\itshape,
	morestring=[b]',
	morestring=[b]",
}
\lstset{
	backgroundcolor=\color{lstbg},
	basicstyle=\ttfamily\footnotesize,
	breaklines=true,
	captionpos=b,
	frame=single,
	framesep=4pt,
	rulecolor=\color{black!20},
	xleftmargin=4pt,
	xrightmargin=4pt,
	showstringspaces=false,
}

% Markierung des Verfassers eines Kapitels (Pflicht laut Profvorgabe)
\newcommand{\authornote}[1]{\textit{\small Verfasst von: #1}\par\medskip}

\graphicspath{ {./bilder/} }

\geometry{
	a4paper,margin=25mm
}

\title{\huge{Dev Ops mit Microservices - GitLab}}
\date{\today}
\author{
	\begin{tabular}{ccc}
		\textbf{Roman Schöne} & \textbf{Christopher Schmitt}\\
		2211275 & 2023467\\
		roman.schoene@stud.th-mannheim.de & christopher.schmitt@stud.th-mannheim.de
	\end{tabular}\\\\
	Technische Hochschule Mannheim
}
\addbibresource{literatur/dms.bib}

\renewcommand\familydefault{\sfdefault} % Helvetica 

\begin{document}
	\pagestyle{fancy}
	%... then configure it.
	\fancyhead{} % clear all header fields
	\fancyhead[L]{GitLab}
	\fancyhead[R]{DMS - DevOps mit Micro Services}
	\fancyfoot{} % clear all footer fields
	\fancyfoot[LE,RO]{\thepage}
	
	\maketitle
	
	\begin{abstract}
		\blindtext
	\end{abstract}
	
	
	
	
	\begin{multicols}{2}
		\tableofcontents
		
		\section{Einleitung}
		
		\subsection{Motivation}
		
		\textbf{\ac{CI}} ist eine Methodik zur Softwareentwicklung. Ziele der Vorgehensweise sind die Erstellung von qualitativen Quellcode, durch stetiges Überprüfen der Funktionalität des verfassten Code. Der Entwicklungsstand einer Software liegt innerhalb des sogenannten Hauptzweiges. Entwickler nehmen fortlaufend kleinere Änderungen vor und bauen diese innerhalb kurzen Entwicklungszyklen in den Hauptzweig ein. Der Entwickler stellt eine Anfrage, ob sein Code in den Hauptzweig aufgenommen werden kann (Pull Request). Damit eine korrekte Funktionsweise des Hauptzweiges sichergestellt werden kann, wird jeweils eine Reihe an Tests durchgeführt. Schlagen diese Tests fehl, so muss der Entwickler seine Änderungen ausbessern und den Prozess erneut anstossen und wiederholt diesen Schritt solange bis die Tests erfolgreich sind. Die Änderungen können somit in den Hauptzweig übernommen werden (Merge).
		Häufig findet \ac{CI} in Kombination mit agiler Projektmethodik statt.  \cite{arefeen_continuous_2019}.\\
		\textbf{\ac{CD}} beschreibt den durch \ac{CI} notwendigen Aspekt der Automatisierung. Eine manuelle Durchführung der Tests benötigt einen höheren zeitlichen Aufwand und kann fehlerhaft durchgeführt werden. Zu den Vorteilen von \ac{CI}/\ac{CD} zählen eine frühe Fehlererkennung und schnellere Entwicklungszyklen.
		GitLab ist eine Plattform, die es ermöglicht \ac{CI}/\ac{CD} in Verbindung mit agiler Entwicklung umzusetzen. 
		Nach der jährlichen Entwicklerumfrage von Stack Overflow, ist GitLab, mit 35.6 \%, neben GitHub, mit 81.8 \%, und Jira, mit 46.4 \% eine der meistgenutzten Plattformen zur Dokumentation und zur kollaborativen Zusammenarbeit an Code \cite{2025StackOverflow}. Siehe \ref{fig:stackoverflow-devsurvey-tools}
		\begin{figure}[H]
			\includegraphics[width=\linewidth]{bilder/stack_overflow_developer_survey_collab_tools_documentation.png}
			\caption{Auswahl der 10 meist verwendeten Dokumentations- und Kollaborations Werkzeuge nach Stack Overflow Survey 2025 \cite{2025StackOverflow}}
			\label{fig:stackoverflow-devsurvey-tools}
		\end{figure}
		Diese wissenschaftliche Ausarbeitung beschäftigt sich damit, inwiefern sich die von GitLab v18.11 bereitgestellten Werkzeuge bzw. Möglichkeiten eignen um eine beispielhafte Anwendung zu entwickeln, zu testen und einzusetzen. Ebenso wird betrachtet in welchen Punkten sich die Implementierung von \ac{CI}/\ac{CD} in GitLab zu seinem Mitstreiter GitHub unterscheidet.
		\subsection{Softwarelösung}
		GitLab ist eine mit Git kompatible Plattform für Code-Hosting. Der Code von GitLab ist in Ruby verfasst \cite{degeler_gitlab_2014}. Unter der Haube verwendet Git die relationale Datenbank PostgreSQL. Auf GitLab kann mithilfe einer Weboberfläche zugegriffen werden \cite{gitlab_about}. Es wird differenziert in die kostenfreie \ac{CE} und kostenpflichtige \ac{EE}. 
		GitLab kann in folgenden unterschiedlichen Formen genutzt werden:
		
		\begin{itemize}
			\item \textbf{\ac{SaaS}} Die Plattform wird innerhalb der Cloud von GitLab gehostet. Die Arbeit mit GitLab kann sofort gestartet werden.
			\item \textbf{Selbst gehostet} GitLab kann auf linux-basierten Servern selbst betrieben werden. Installation, Konfiguration und Administration der Infrastruktur muss selbst übernommen werden.
			\item \textbf{Dediziertes \ac{SaaS}} Für Unternehmen und Regierungen kann GitLab in eigenen isolierten Instanzen verwendet werden, um hohe Sicherheitsstandards und gesetzliche Regulierungen zu gewährleisten.
		\end{itemize}
		
		Für die \ac{SaaS}- und die selbst gehostete Variante von GitLab gibt es drei unterschiedliche Preispläne: Free, Premium und Ultimate. Tabelle \ref{tab:saas_plans} zeigt eine Auswahl an Funktionalitäten und deren Verfügbarkeit nach Preisplan. In der selbst gehosteten Variante von GitLab sind die technischen Limitierungen Nutzeranzahl, Rechnungszeit und Speicher von der Bereitstellung eigener Serverkapazitäten abhängig. Die Verfügbarkeit der restlichen Funktionalitäten ist analog.
		\begin{table}[H]
			\begin{tabular}{@{}llll@{}}
				\toprule
				& \multicolumn{3}{c}{Verfügbarkkeit}        \\ \midrule
				Preisplan       & Free    & Premium   & Ultimate  \\ \midrule
				Nutzerzahl   & 5       & $\infty$         & $\infty$          \\
				\makecell[cl]{Rechnungs-\\zeit} & 400 min & 10000 min & 50000 min \\
				Speicher   & 10 GiB  & 500 GiB   & 500 GiB\\\midrule
				\ac{CI}/\ac{CD} & X & X & X\\
				\makecell[cl]{Container-\\Scan} & X & X & X\\
				Web \acs{IDE} & - & X & X\\
				Pushregeln & - & X & X\\
				\makecell[cl]{Integrierte\\Testfälle} & - & - & X\\ \midrule
				\makecell[cl]{Zeitracking} & X & X & X\\
				Wikis & X & X & X\\
				\makecell[cl]{Issue-\\Gewichte} & - & X & X\\
				\makecell[cl]{Projekt-\\analyse} & - & X & X\\
				\makecell[cl]{Statusseite} & - & - & X\\
				\midrule
				Preis & 0\texteuro & \makecell[cl]{29\texteuro je$\frac{\text{Nutzer}}{\text{Monat}}$} & \makecell[cl]{kunden-\\spezifisch}\\ \bottomrule
			\end{tabular}
			\caption{Auswahl an Funktionalitäten und deren Verfügbarkeit, nach Preisplan \cite{gitlab_about}}
			\label{tab:saas_plans}
		\end{table}
		
		\subsection{Geschichte}
		
		GitLab wurde von Sytse Sijbrandij und von Dmitriy Zaporozhets gegründet. Zaporozhets entwickelte GitLab 2011 als Hilfsmittel für seine eigenen Projekte. GitLab war zu dem Zeitpunkt eine private und freie Plattform zum eigenen Code-Hosting, entwickelt von Zaporozhets. Zaporozhets und Sijbrandij lernten sich auf der \href{https://thenextweb.com/conference}{The Next Web} Konferenz kennen. Nachdem Zaporozhets sich entschied den Quellcode von GitLab frei zugänglich zu machen, entstand die Partnerschaft mit Sijbrandij. Um den Einstieg in die Nutzung von GitLab zu erleichtern entschieden sich Sijbrandij GitLab als \ac{SaaS} unter der Domain \url{https://gitlab.com/} anzubieten. Der Quellcode von GitLab ist frei unter \url{https://gitlab.com/gitlab-org/gitlab} verfügbar \cite{degeler_gitlab_2014}. Der Quellcode des Konkurrenten GitHub ist nicht frei zugänglich. 2014 wurde GitLab erstmalig als Unternehmen eingetragen und erfuhr seitdem einen grossen Zuwachs an Mitarbeitern. Aktuell zählt GitLab mehr als 2600 Mitarbeiter, die über 65 Länder verteilt leben \cite{gitlab_about}. GitLab selbst besitzt keinen grossen ausgebauten Firmenhauptsitz, da Mitarbeiter hauptsächlich remote arbeiten und freie Verfügung über ihre Arbeitszeit besitzen. Der organisatorische Aufbau und der Ablauf interner Prozesse von GitLab, können in dem von GitLab öffentlichem Handbuch \url{https://handbook.gitlab.com/} nachgelesen werden \cite{choudhuryGitLabWorkWhere2020}.
		GitLab finanziert sich durch Spenden um neue Funktionalitäten zu realisieren. Ein weiterer Teil der Einnahmen kommt durch den Abschluss von kostenpflichtiger Abonnements. \cite{degeler_gitlab_2014}. 
		Abbildung \ref{fig:gitlablogo} zeigt das Logo von GitLab. Es besteht aus einem Tanuki, einem in Japan heimischen Waschbärhund, und dem GitLab Schriftzug.
		\begin{figure}[H]
			\centering
			\includegraphics[width=0.8\linewidth]{./bilder/gitlab-logo-100-rgb.png}
			\caption{Logo GitLab}
			\label{fig:gitlablogo}
		\end{figure} 
		GitLab erregte in mehreren Fällen mediale Aufmerksamkeit auf sich. 2017 verlor die \ac{SaaS}-Lösung von GitLab sechs Stunden an Nutzerdaten, aufgrund von einer menschlichen Fehlreaktion, ausgelöst durch Spamanfragen die in Problemen mit der Datenbank resultierten \cite{GitLabcomDatabaseIncident}. GitLab wagte im Oktober 2021 den Gang an die Börse und ist aktuell als Aktie im \ac{NASDAQ} unter dem Kürzel: GTLB erhältlich \cite{teamGitLabIncGTLB}.
		Ebenso bestanden 2022 Pläne inaktive Repositories löschen. Nach starker Kritik wurde sich dazu entschieden, anstatt zu löschen, zu archivieren \cite{onlineVersionsverwaltungGitLabRudert2022}.
		
		\subsection{Aufbau}
		
		Zusammenarbeit in GitLab ist in Form von Gruppen organisiert. Diese können in Subgruppen unterteilt werden. Gruppen und Subgruppen können Projekte und Mitarbeiter zugeordnet werden. 
		Jedes Projekt besteht aus einer Issue-Seite und einem Code-Repository. Für ein Projekt kann optional ein Wiki angelegt werden, um Informationen in Form von \ac{GLFM} zu dokumentieren \cite{gitlab_gitlab_nodate}. \ac{GLFM} ist eine spezielle Markdown-Spezifikation, welche die grundlegende Definition erweitert. Projekte besitzen folgende Sichtbarkeitsstufen:
		\begin{itemize}
			\item \textbf{Public} Als öffentlich zugängliche Ressourcen kann jedermann zugreifen. Ein Zugriff ist auch ohne einen GitLab Account möglich.
			\item \textbf{Internal} Nur GitLab-Nutzer können auf die als intern markierte Ressource zugreifen.
			\item \textbf{Private} Nur Nutzer die explizit als Mitarbeiter/Teilnehmer zu einem Projekt hinzugefügt wurden, können auf private Ressourcen zugreifen.
		\end{itemize}
		Ein Projekt wird immer unter einem Namensraum angelegt. In GitLab wird in 2 Typen von Namensräumen unterschieden:
		\begin{itemize}
			\item \textbf{Nutzer} Der Namensraum von einem Nutzer kann keine Subgruppen enthalten. Wird sich entschieden den Nutzernamen zu ändern, so ändert sich auch die URL des Namensraum
			\item \textbf{Gruppe} Innerhalb von Gruppen können Subgruppen erstellt werden, welche ihre Einstellungen vorerst von ihrer Elterngruppe erben.
		\end{itemize}
		Tabelle \ref{tab:namespaces} zeigt eine Auflistung beispielhafter Namensräume mit entsprechender URL für eine Gitlab-Instanz unter der Domain \texttt{domain.com}.
		\begin{table}[H]
			\centering
			\resizebox{\columnwidth}{!}{%
				\begin{tabular}{@{}lll@{}}
					\toprule
					Namensraum & URL                                    & Beschreibung                     \\ \midrule
					\texttt{max}         & https://domain.com/max         & \makecell[cl]{Nutzer mit Namen \\ \texttt{max}}            \\
					\texttt{team}        & https://domain.com/team        & \makecell[cl]{Gruppe mit Namen \\ \texttt{team}}           \\
					\texttt{team/design} & https://domain.com.com/team/design & \makecell[cl]{Subgruppe \texttt{design}\\ der Gruppe \texttt{team}} \\ \bottomrule
				\end{tabular}%
			}
			\caption{Beispielhafte Namensräume von Projekten in GitLab}
			\label{tab:namespaces}
		\end{table}
		GitLab unterscheidet in folgende Nutzertypen, die auf eine GitLab Instanz zugreifen können \cite{gitlab_gitlab_nodate}: 
		\begin{itemize}
			\item \textbf{Auditor} Ein Auditor besitzt nur Lese-Zugriff auf alle zur Verfügung stehenden Ressourcen. Auditoren werden in der Praxis meist verwendet um die Einhaltung von bspw. gesetzlichen Regularien und Richtlinien, die von einem Unternehmen erfüllt werden sollen, zu überprüfen. Auditoren sind nur innerhalb des selbstgehosten und dedizierten Lösung möglich.
			\item \textbf{External} Ein externer Nutzer besitzt eingeschränkten Zugriff auf private Ressourcen einer GitLab-Instanz. Diese müssen davor explizit als externe Nutzer hinzugefügt werden. Meistens werden externe Nutzer verwendet um Nutzern außerhalb eines Unternehmens spezifischen Zugriff auf ein Projekt oder eine Gruppe zu geben. Externe Nutzer sind nur innerhalb des selbstgehosten und dedizierten Lösung möglich.
			\item \textbf{Internal} Ein Interner Nutzer besitzt meist eingeschränkten Zugriff und wird durch GitLab automatisch erstellt. Interne Nutzer können als Bots betrachtet werden, die automatisierte Prozesse durchführen, die durch normale Nutzer nicht ausgeführt werden können. Interne Nutzer sind für alle Lösungen von GitLab erhältlich.
			\item \textbf{Service} Service Accounts repräsentieren nicht menschliche Nutzer. Service Nutzer kommen bei der automatischen Ausführung von Prozessen und Pipelines zum Einsatz. Service Nutzer sind für alle Lösungen von GitLab erhältlich.
		\end{itemize}
		\subsection{GitLab vs. GitHub}
		
		Bei der Wahl von Code-Hosting ist oft GitHub die erste Wahl. GitHub wurde 2008 von Chris Wanstrath, Tom Preston-Werner und Phillip Jeffrey Hyett gegründet. GitHub wurde 2018 für ungefähr 7,5 Milliarden USD an den Software-Giganten Microsoft verkauft \cite{jrHowThis33yearold2018}. Der Code von GitHub selber ist nicht öffentlich zugänglich. Für Github besteht keine Option die Plattform selbst zu hosten. Nutzer sind daran gebunden, unter der Haube, auf Services zuzugreifen, die in Microsoft Azure laufen. \url{github.com} besitzt im Vergleich zu \url{gitlab.com} eine höhere Anzahl an Nutzern für Q4 2025. GitHub hat verdächtige Nutzer und Bots in ihrer Angabe herausgefiltert und kommt auf eine Gesamtanzahl an ca. 179 Millionen Nutzer \cite{GitHubInnovationGraph}. GitLab gibt an, dass von mindestens 50 Millionen Nutzern ausgegangen werden kann \cite{Q4FY2026GitLab}.
		Aufgrund der grösseren Nutzerbasis eignet sich GitHub mehr für eine kollaborative Zusammenarbeit an \ac{OSS}. Ein Projekt erreicht mehr Nutzer, die potenziell beitragen können.
		GitLab und GitHub teilen sich neben demselben Namenspräfix, ähnliche Mechanismen \cite{gitlab_gitlab_nodate}.\\\\
		\ac{CI}/\ac{CD} ist für jeweils beide Plattformen erhältlich. Unter GitHub bieten \textit{GitHub Actions} die Möglichkeit Build-, Test- und Deploymentprozesse zu automatisieren. In GitHub sind diese Abläufe in Form von \textit{Workflows} organisiert. Ein \textit{Workflow} wird durch ein Ereignis ausgelöst. Ein \textit{Workflow} ist in \textit{Jobs} aufgegliedert. \textit{Jobs} beinhalten Anweisungen bspw. in Form von Kommandozeilenskripts, die sequentiell ausgeführt werden. Eine \textit{Action} beschreibt eine Menge an wiederverwendbaren \textit{Jobs}. \textit{Workflows} werden auf einem Server bzw. einem \textit{Runner} ausgeführt. Für GitHub ist auch das eigene Hosten eines \textit{Runners} möglich. Die Verwendung von eigens gehosteten Runnern, sowie der von GitHub bereitgestellten Runnern ist für öffentliche Repositories kostenlos. Für private Repositories existiert ein Zeitbudget. \cite{GitHubcomHelpDocumentation} \cite{gitlab_gitlab_nodate}\\\\
		Beide Plattformen bieten KI-Assistenten an. Für GitHub existiert \textit{GitHub Copilot} und für GitLab \textit{GitLab Duo Agent}. Aktuell kann \textit{GitHub Copilot} mit einem eingeschränkten Zugriff auf Funktionalitäten, kostenlos verwendet werden. Im Gegensatz ist aktuell eine kostenfreie Nutzung von \textit{GitLab Duo Agent} nicht möglich. Copilot beschränkt sich auf alle Artefakte, die in einem Code-Repository liegen. \textit{GitLab Duo Agent} besitzt einen größeren Kontext, zu dem zusätzlich Dokumentation, Planung und Sicherheit gehören. Aufgrund der Aneignung von \textit{Visual Studio Code} durch Microsoft ist \textit{GitHub Copilot} nativ enthalten. Eine Unterstützung für \textit{GitLab Duo Agent} muss über die offizielle \href{https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow}{Erweiterung} ergänzt werden. Interaktionen mit \textit{GitHub Copilot} werden standardmässig von GitHub zum trainieren und verbessern von KI-Modellen verwendet. UM eine Weiterverarbeitung der Daten zu verhindern muss manuell widersprochen werden. Für beide KI-Assistenten kann das unterliegende Modell variiert werden. \cite{GitHubcomHelpDocumentation} \cite{gitlab_gitlab_nodate}\\\\
		Das Hosten von Code-Schnipseln ist in GitHub als \href{https://gist.github.com/}{Gist} und in GitLab unter \href{https://gitlab.com/dashboard/snippets}{Snippets} möglich. Organisationen können in GitHub ebenfalls abgebildet werden.
		
		\section{CI/CD}
		\authornote{Christopher Schmitt}

		Die Begriffe \ac{CI}, \ac{CD} und Continuous Deployment werden in der Literatur nicht einheitlich verwendet. Shahin et al.~\cite{shahin_continuous_2017} grenzen sie klar ab. \ac{CI} bezeichnet das automatische Übersetzen und Testen jeder Codeänderung gegen den gemeinsamen Hauptzweig. \ac{CD} ergänzt diesen Vorgang um die Eigenschaft, dass jeder geprüfte Stand jederzeit in eine produktionsnahe Umgebung ausgeliefert werden kann. Der Schritt in die Produktion bleibt dabei eine bewusste, manuelle Freigabe. Continuous Deployment automatisiert auch diesen letzten Schritt. Alle drei Stufen bildet GitLab mit denselben Bausteinen ab: Runner, Pipelines und Jobs. Gesteuert werden sie zentral über eine einzige Konfigurationsdatei im Repository \cite{cowell_automating_2023}.

		\subsection{GitLab Runner}

		Die GitLab-Instanz selbst führt keine \ac{CI}/\ac{CD}-Arbeit aus. Diese Aufgabe übernimmt ein separater Hilfsprozess, der \emph{Runner} \cite{gitlab_gitlab_nodate}. Ein Runner registriert sich einmal mit einem Token bei der Instanz und holt sich danach selbständig offene Aufgaben ab. Durch diese Trennung kann die Ausführung horizontal skaliert werden. Plattformabhängige Aufgaben lassen sich gezielt auf der passenden Hardware ausführen \cite{painter_practical_2024}. Runner können auf drei unterschiedlichen Ebenen registriert werden:
		\begin{itemize}
			\item \emph{Instanz} Auf Instanzebene registrierte Runner stehen allen Projekten der GitLab-Instanz zur Verfügung. Sie werden in der Regel von der Administration bereitgestellt.
			\item \emph{Gruppe} Auf Gruppenebene registrierte Runner nehmen Aufgaben aus sämtlichen Projekten innerhalb dieser Gruppe und ihrer Subgruppen an. Eingesetzt werden sie meistens dann, wenn eine Gruppe besondere Anforderungen an Hardware oder Software stellt.
			\item \emph{Projekt} Auf Projektebene registrierte Runner sind ausschliesslich an ein einzelnes Projekt gebunden. Diese Variante eignet sich für sensitive Projekte, bei denen kein gemeinsam genutzter Runner verwendet werden soll.
		\end{itemize}
		Wie ein Runner eine konkrete Aufgabe ausführt, hängt vom konfigurierten \emph{Executor} ab. Der Executor entscheidet, in welcher Umgebung das vom Anwender hinterlegte Skript läuft. Tabelle~\ref{tab:executors} listet die in der Praxis am häufigsten verwendeten Executors auf.
		\begin{table}[H]
			\centering
			\caption{Häufig verwendete Executors des GitLab Runners \cite{gitlab_gitlab_nodate}}
			\label{tab:executors}
			\resizebox{\columnwidth}{!}{%
				\begin{tabular}{@{}lll@{}}
					\toprule
					Executor & Ausführungsumgebung & Typischer Einsatz \\ \midrule
					\texttt{shell} & direkt auf dem Hostsystem & einfache Setups, Eigenbau-Server \\
					\texttt{docker} & je Aufgabe ein neuer Container & in der Praxis der Standardfall \\
					\texttt{docker-machine} & ephemere Cloud-VMs & elastische Skalierung \\
					\texttt{kubernetes} & ein Pod je Aufgabe & grosse Cluster, Autoskalierung \\
					\texttt{ssh} & entfernter Host über SSH & Legacy-Systeme \\ \bottomrule
				\end{tabular}%
			}
		\end{table}
		Die Wahl des Executors hat neben der technischen auch eine organisatorische Dimension. Nach Rostami Mazrae et al.~\cite{rostami_usage_2023} startet der \texttt{shell}-Executor zwar mit minimalem Aufwand, wird in produktiven Umgebungen aufgrund fehlender Isolation aber üblicherweise durch \texttt{docker} oder \texttt{kubernetes} ersetzt. Sicherheitsrisiken entstehen vor allem dann, wenn mehrere Projekte denselben \texttt{shell}-Runner verwenden und ein Skript das Hostsystem dauerhaft verändert.

		\subsection{Pipelines}

		Eine \emph{Pipeline} ist in GitLab die oberste Ebene der Automatisierung. Sie umfasst sämtliche Schritte, die als Reaktion auf ein Ereignis im Repository ablaufen \cite{gitlab_gitlab_nodate}. Ausgelöst wird eine Pipeline durch unterschiedliche Ereignisse. Dazu gehören ein Push, das Öffnen eines \emph{Merge Requests}, ein hinterlegter Zeitplan, ein manueller Klick in der Weboberfläche oder das Ende einer anderen Pipeline \cite{cowell_automating_2023}.

		Innerhalb einer Pipeline werden die einzelnen Arbeitsschritte zu sogenannten \emph{Stages} zusammengefasst. Alle Schritte einer Stage laufen parallel und müssen erfolgreich abgeschlossen sein, bevor die nächste Stage beginnt \cite{gitlab_gitlab_nodate}. Eine in der Praxis verbreitete Reihenfolge der Stages ist \texttt{lint}, \texttt{test}, \texttt{build} und \texttt{deploy}. Abbildung~\ref{fig:pipeline-stages} zeigt das Verhältnis von Pipeline, Stages und Jobs.

		\input{diagrams/pipeline_stages}

		Die gesamte Definition einer Pipeline liegt in einer einzigen Datei. Diese trägt den Namen \texttt{.gitlab-ci.yml} und befindet sich im Wurzelverzeichnis des Repositories \cite{gitlab_gitlab_nodate}. Damit folgt GitLab dem von Humble und Farley~\cite{humble_continuous_2010} eingeführten \emph{Pipeline-as-Code}-Prinzip. Die Beschreibung des Build- und Auslieferungsprozesses wird wie Anwendungscode versioniert und im Review geprüft. Listing~\ref{lst:gitlabciyml} zeigt einen minimalen Aufbau mit drei Stages.

		\begin{lstlisting}[language=yaml,caption={Minimaler Aufbau einer .gitlab-ci.yml},label={lst:gitlabciyml}]
stages:
  - test
  - build
  - deploy

unit-test:
  stage: test
  script:
    - npm ci
    - npm test

build-image:
  stage: build
  script:
    - docker build -t app:$CI_COMMIT_SHA .

deploy-staging:
  stage: deploy
  script:
    - ssh user@host 'docker pull app'
  only:
    - main
\end{lstlisting}

		Aus der starren Stage-Reihenfolge lässt sich mit dem Schlüsselwort \texttt{needs} ein gerichteter azyklischer Graph bilden, ein sogenannter \ac{DAG}. Ein Schritt darf dann starten, sobald seine konkret benannten Vorgänger fertig sind. Unnötige Wartezeiten entfallen \cite{cowell_automating_2023}. Wiederkehrende Pipeline-Bausteine können über das Schlüsselwort \texttt{include} aus anderen Repositories nachgeladen werden \cite{gitlab_gitlab_nodate}. Mit den in Abschnitt~\ref{subsec:komponenten} beschriebenen CI/CD-Komponenten existiert seit GitLab 16.0 ein weitergehender Mechanismus zur Wiederverwendung von Pipeline-Logik.

		\subsection{Jobs}

		Die eigentliche Arbeitseinheit innerhalb einer Pipeline ist der \emph{Job}. Ein Job führt ein vom Anwender festgelegtes Skript in einer isolierten Umgebung aus und ist genau einer Stage zugeordnet \cite{gitlab_gitlab_nodate}. Jobs derselben Stage sind voneinander unabhängig und werden parallel auf den verfügbaren Runnern ausgeführt. Ob die Pipeline weiterläuft, hängt vom Ergebnis sämtlicher Jobs einer Stage ab.

		Mit dem Schlüsselwort \texttt{rules} wird pro Job festgelegt, unter welchen Bedingungen dieser ausgeführt wird. Beispiele sind die Beschränkung auf bestimmte Branches, die Ausführung nur bei Änderungen an bestimmten Dateien oder die Abhängigkeit vom Ergebnis vorheriger Jobs \cite{cowell_automating_2023}. Ein als \texttt{manual} markierter Job läuft erst nach einer expliziten Freigabe über die Weboberfläche. Diese Konstruktion wird häufig für Auslieferungen in produktive Umgebungen genutzt.

		Während ein Job läuft, entstehen häufig Dateien, die spätere Jobs weiterverarbeiten. Beispiele sind ein gebautes Bundle, ein Container-Image oder ein Testbericht. GitLab unterscheidet dafür zwei Mechanismen mit unterschiedlicher Lebensdauer \cite{gitlab_gitlab_nodate}:
		\begin{itemize}
			\item \emph{Artefakte} sind benannte Ergebnisse eines Jobs. Sie werden nach dem erfolgreichen Abschluss eines Jobs an die GitLab-Instanz hochgeladen, stehen dort zum Download bereit und werden an spätere Jobs der Pipeline weitergegeben.
			\item \emph{Caches} dienen ausschliesslich dazu, wiederholte Ausführungen zu beschleunigen. Typisch ist das Zwischenspeichern heruntergeladener Abhängigkeiten zwischen Pipeline-Läufen. Über Jobgrenzen hinweg ist der Cache nicht garantiert verfügbar.
		\end{itemize}
		Das Ziel einer Auslieferung wird durch das Konzept der \emph{Environments} beschrieben \cite{cowell_automating_2023}. Jedes Environment fasst alle Auslieferungen in eine bestimmte Zielumgebung zusammen. In der Weboberfläche wird zusätzlich protokolliert, welche Version dort gerade läuft. Einen Sonderfall bilden \emph{Review-Apps}. Für jeden offenen Merge Request erzeugt GitLab automatisch eine isolierte, kurzlebige Auslieferung, in der die geänderte Anwendung vor dem Merge begutachtet werden kann \cite{gitlab_gitlab_nodate}. Nach Rostami Mazrae et al.~\cite{rostami_usage_2023} ist diese direkte Kopplung zwischen Review und laufender Vorschau eines der Merkmale, mit denen sich GitLab von alternativen Plattformen abgrenzt.

		Zampetti et al.~\cite{zampetti_empirical_2020} identifizieren in einer empirischen Untersuchung 79 wiederkehrende Anti-Muster in CI-Konfigurationen. Häufige Probleme sind unnötig sequentielle Stages, zu grobgranulare Jobs und das Vermischen von Cache und Artefakten. Lesbarkeit und Wartbarkeit der Pipeline-Definition sind damit ein eigenes Qualitätskriterium.

		\subsection{CICD-Komponenten}\label{subsec:komponenten}
		
		Mit dem Schlüsselwort \texttt{include} können bereits seit längerem ganze Pipeline-Fragmente aus anderen Repositories oder von einer entfernten \ac{URL} eingebunden werden \cite{gitlab_gitlab_nodate}. In der Praxis stellen sich dabei zwei wiederkehrende Probleme. Eingebundene Fragmente sind in den meisten Fällen weder versioniert noch besitzen sie eine eigene Schnittstelle. Eine Änderung am Fragment kann sämtliche Pipelines mit einbinden \cite{cowell_automating_2023}.

		Seit GitLab 16.0 lösen \emph{CI/CD-Komponenten} dieses Problem. Eine Komponente ist ein versionierter und parametrisierbarer Pipeline-Baustein, der ähnlich wie eine Software-Bibliothek verwendet wird \cite{gitlab_gitlab_nodate}. Komponenten werden in einem dedizierten Projekt entwickelt und veröffentlicht. Drei Bestandteile sind dabei zwingend vorgesehen:
		\begin{itemize}
			\item \emph{Manifest} In einer Datei \texttt{template.yml} beschreibt die Komponente ihre Eingabeparameter mit Datentyp und Defaultwert sowie die von ihr beigesteuerten Jobs.
			\item \emph{Versionsschild} Komponenten werden ausschliesslich über Git-Tags freigegeben. Ein Konsument referenziert eine Komponente immer mit einer konkreten Version. Damit kann sich der eingebundene Stand nicht unter dem Konsumenten verändern.
			\item \emph{Katalogeintrag} Ein Projekt, das den Status \textit{Components Project} erhält, erscheint im zentralen \emph{Component Catalog} der GitLab-Instanz. Die Suche nach geeigneten Komponenten erfolgt dort, ohne dass Repository-Pfade auswendig bekannt sein müssen.
		\end{itemize}
		Listing~\ref{lst:component} zeigt die Einbindung einer beispielhaften Lint-Komponente in eine bestehende Pipeline.

		\begin{lstlisting}[language=yaml,caption={Einbindung einer CI/CD-Komponente},label={lst:component}]
include:
  - component: $CI_SERVER_FQDN/team/lint@1.2.0
    inputs:
      stage: lint
      node-version: '20'

stages:
  - lint
  - test
\end{lstlisting}

		Im Gegensatz zum klassischen \texttt{include} besitzt die Komponente damit eine echte Aufrufsignatur. Die Eingabewerte werden vom Aufrufer im Block \texttt{inputs} gesetzt und sind unter dem Präfix \texttt{\$[[ inputs.<name> ]]} innerhalb der Komponente verfügbar \cite{gitlab_gitlab_nodate}. Nach Cowell et al.~\cite{cowell_automating_2023} ist diese Trennung zwischen Schnittstelle und Implementierung der wesentliche Schritt, der Pipeline-Logik in grösseren Organisationen wartbar hält. Die Anti-Muster, die Zampetti et al.~\cite{zampetti_empirical_2020} beschreiben, lassen sich auf diese Weise an einer einzigen Stelle korrigieren, ohne dass sämtliche Pipelines angefasst werden müssen.
		
		\subsection{Anwendungsbeispiel}
		
		Zur praktischen Demonstration der vorhergehenden Konzepte wurde eine kleine Webanwendung auf der in Abschnitt~\ref{sec:selfhosted} beschriebenen selbstgehosteten Instanz aufgesetzt. Die Anwendung ist bewusst minimal gehalten. So liegt der Fokus auf der \ac{CI}/\ac{CD}-Konfiguration und nicht auf dem Anwendungscode.

		Die Demoanwendung ist ein \texttt{HTTP}-Dienst, der in \emph{Node.js} mit dem Web-Framework \emph{Express} geschrieben ist. Bereitgestellt wird ein einzelner Endpunkt \texttt{GET /}, der eine kurze HTML-Seite mit der Bezeichnung der aktuellen Umgebung und der im Build verbauten Versionskennung ausliefert. Beide Werte werden zur Laufzeit über Umgebungsvariablen aus dem Container gelesen und im jeweiligen Deploy-Job gesetzt. Eine kleine Testsuite mit dem Framework \texttt{vitest} prüft, dass der Endpunkt eine HTML-Antwort mit Statuscode~200 und der erwarteten Versionsangabe liefert.

		Die zugehörige \texttt{.gitlab-ci.yml} definiert drei Stages: \texttt{lint}, \texttt{test} und \texttt{deploy}. Die Stage \texttt{deploy} enthält dabei zwei Jobs, die sich gegenseitig ausschliessen. Tabelle~\ref{tab:demo-pipeline} fasst zusammen, welcher Schritt unter welchen Bedingungen ausgeführt wird und welches Environment er bedient.
		\begin{table}[H]
			\centering
			\caption{Stages der Demo-Pipeline und ihre Auslöser}
			\label{tab:demo-pipeline}
			\resizebox{\columnwidth}{!}{%
				\begin{tabular}{@{}llll@{}}
					\toprule
					Stage / Job & Auslöser & Ergebnis & Environment \\ \midrule
					\texttt{lint} & jeder Push & Stilbericht & -- \\
					\texttt{unit-test} & jeder Push & Testbericht & -- \\
					\texttt{deploy:staging} & alle Branches ausser \texttt{main}, manuell & Container in Staging & \texttt{staging} \\
					\texttt{deploy:prod} & Push auf \texttt{main}, automatisch & Container in Produktion & \texttt{production} \\ \bottomrule
				\end{tabular}%
			}
		\end{table}
		Die ersten beiden Stages werden bei jedem Push auf jeden Branch ausgeführt. Sie entsprechen den klassischen \ac{CI}-Schritten nach Duvall et al.~\cite{duvall_continuous_2007} und Fowler~\cite{fowler_continuous_2006} und sollen ein schnelles, automatisches Feedback auf jeden Codestand erzeugen. Die Stage \texttt{deploy} deckt den Continuous-Delivery-Anteil ab. Auf einem Feature-Branch steht der Job \texttt{deploy:staging} als manueller Schritt in der Pipeline-Übersicht bereit. Eine Änderung kann so bei Bedarf in einer laufenden Vorschau begutachtet werden, bevor sie in den Hauptzweig wandert. Ein Push auf \texttt{main} liefert automatisch nach \texttt{production} aus. Nach der Begriffsabgrenzung von Shahin et al.~\cite{shahin_continuous_2017} entspricht der Pfad nach \texttt{main} damit Continuous Deployment, der manuelle Pfad nach Staging klassischem Continuous Delivery.

		Im Rahmen der Live-Präsentation wird der Lebenszyklus einer Codeänderung in drei Schritten gezeigt. Zunächst wird auf einem Feature-Branch eine sichtbare Änderung am Anwendungscode vorgenommen und in das Repository übertragen. Die Stages \texttt{lint} und \texttt{unit-test} laufen automatisch durch. Danach wird der Job \texttt{deploy:staging} über die Weboberfläche freigegeben. Die Änderung ist unmittelbar unter der Staging-Adresse sichtbar, ohne dass sie bereits im Hauptzweig liegt. Den Abschluss bildet der Merge Request gegen \texttt{main}. Wird er akzeptiert, durchläuft eine neue Pipeline auf \texttt{main} erneut \texttt{lint} und \texttt{unit-test} und löst anschliessend automatisch \texttt{deploy:prod} aus. Die neue Version ist damit ohne weiteren manuellen Eingriff in der produktiven Umgebung erreichbar.
		
		\section{Selbstgehostete Lösung}\label{sec:selfhosted}
		\authornote{Christopher Schmitt}
		
		Neben dem Bezug als \ac{SaaS} lässt sich GitLab auch auf eigener Hardware selbst betreiben. Diese Variante wird von GitLab als \emph{Self-Managed} bezeichnet \cite{gitlab_gitlab_nodate}. Sie kommt hauptsächlich in zwei Fällen zum Einsatz. Entweder erlauben Datenschutz- oder Compliance-Vorgaben nicht, dass Quellcode auf fremden Servern liegt. Oder die \ac{SaaS}-Variante wird mit steigender Nutzerzahl zu teuer. Installation, Konfiguration, Aktualisierungen und Sicherungen müssen dafür allerdings selbst übernommen werden \cite{painter_practical_2024}. Im Folgenden wird beschrieben, wie eine solche Instanz im Rahmen dieser Arbeit auf einem privaten Linux-Server aufgesetzt wurde und welcher Aufwand dabei anfiel.

		\subsection{Installation}

		Für die selbstgehostete \ac{CE} bietet GitLab das sogenannte \emph{Omnibus-Paket} an \cite{painter_practical_2024}. Im Paket enthalten sind sämtliche Komponenten, die GitLab im Betrieb benötigt. Dazu zählen der Webserver \texttt{nginx}, der Anwendungsserver \texttt{Puma}, die relationale Datenbank \texttt{PostgreSQL} und der Schlüssel-Wert-Speicher \texttt{Redis}. Weitere Hintergrundprozesse kommen hinzu \cite{gitlab_gitlab_nodate}. Abbildung~\ref{fig:omnibus-arch} zeigt das Zusammenspiel der einzelnen Bausteine.

		\input{diagrams/omnibus_arch}

		Der wesentliche Vorteil des Omnibus-Paketes ist, dass die einzelnen Komponenten nicht selbst installiert und aufeinander abgestimmt werden müssen. Ein einzelner Aufruf des Paketmanagers genügt. Auf debian-basierten Systemen wird das GitLab-Paketrepository einmalig hinzugefügt und anschliessend \texttt{apt install gitlab-ce} ausgeführt \cite{gitlab_gitlab_nodate}.

		Für diese Arbeit wurde GitLab \ac{CE} auf einem privaten Linux-Server installiert. Als Betriebssystem kam eine aktuelle LTS-Variante von Ubuntu zum Einsatz. GitLab empfiehlt für eine produktive Instanz mit bis zu 20 aktiven Nutzern mindestens vier Kerne und 8\,GiB Arbeitsspeicher \cite{gitlab_gitlab_nodate}. Da die verwendete Hardware diesen Richtwert beim Arbeitsspeicher nicht vollständig erreicht, wurde zusätzlich eine Swap-Datei eingerichtet, um Lastspitzen während des ersten \texttt{reconfigure}-Laufs aufzufangen. Die Installation selbst lief unauffällig. Das Paket wurde heruntergeladen und entpackt. Das mitgelieferte Skript \texttt{gitlab-ctl reconfigure} brachte die Instanz innerhalb weniger Minuten in einen lauffähigen Zustand. Eine erste Anmeldung über die Weboberfläche war direkt möglich.

		Eine Besonderheit des hier beschriebenen Aufbaus betrifft die Erreichbarkeit der Instanz. Anstatt die Instanz über eine öffentliche Domain freizugeben, wird die gesamte Kommunikation über ein privates Overlay-Netzwerk auf VPN-Basis abgewickelt. Der Webserver \texttt{nginx} bindet sich dadurch ausschliesslich an die lokale Schnittstelle. Externe Anfragen aus dem Overlay-Netzwerk werden über einen vorgelagerten Proxy entgegengenommen und auf den lokalen Port weitergereicht. Ein zugehöriges \ac{TLS}-Zertifikat wird vom Overlay-Dienst selbst bereitgestellt. Auf eine direkte Exposition der Ports 80 und 443 zum öffentlichen Internet wird auf diese Weise vollständig verzichtet.

		\subsection{Konfiguration}

		Eine Self-Managed-Instanz wird zentral über die Datei \texttt{/etc/gitlab/gitlab.rb} konfiguriert \cite{painter_practical_2024}. Sämtliche Komponenten des Omnibus-Pakets lesen ihre Einstellungen aus dieser Datei. Bei jedem Aufruf von \texttt{gitlab-ctl reconfigure} werden die Komponenten mit dem aktuellen Stand neu initialisiert. Tabelle~\ref{tab:gitlabrb} zeigt eine Auswahl der für den vorliegenden Aufbau relevanten Optionen.
		\begin{table}[H]
			\centering
			\caption{Auswahl an Konfigurationsoptionen aus \texttt{gitlab.rb} \cite{gitlab_gitlab_nodate, painter_practical_2024}}
			\label{tab:gitlabrb}
			\resizebox{\columnwidth}{!}{%
				\begin{tabular}{@{}lll@{}}
					\toprule
					Option & Wert & Zweck \\ \midrule
					\texttt{external\_url} & \texttt{https://<host>} & von aussen sichtbare \ac{URL} \\
					\texttt{nginx['listen\_addresses']} & \texttt{['127.0.0.1']} & nur lokales Binding \\
					\texttt{letsencrypt['enable']} & \texttt{false} & kein eigenes Zertifikat \\
					\texttt{registry['enable']} & \texttt{true/false} & Container Registry \\
					\texttt{gitlab\_rails['smtp\_*']} & Provider & Versand von Systemmails \\
					\texttt{puma['worker\_processes']} & \texttt{0--n} & Anzahl Anwendungsprozesse \\
					\texttt{sidekiq['max\_concurrency']} & \texttt{8--25} & Hintergrundjobs parallel \\
					\texttt{backup\_keep\_time} & in Sekunden & Aufbewahrungsdauer Backups \\ \bottomrule
				\end{tabular}%
			}
		\end{table}

		Eine geführte Erstkonfiguration, wie sie die \ac{SaaS}-Variante bietet, existiert nicht. Nach der Installation läuft die Instanz zwar, befindet sich aber in einem generischen Standardzustand. Alles Projektspezifische muss selbst zusammengesucht werden. Im hier beschriebenen Aufbau war dies der zeitaufwendigste Teil der Bereitstellung. Die reine Paketinstallation war in unter zehn Minuten abgeschlossen. Das anschliessende Einrichten von Erreichbarkeit, Mailversand, Container Registry und Runnern beanspruchte mehrere Stunden, weil die Optionen in \texttt{gitlab.rb} ohne Vorwissen über die jeweiligen Komponenten schwer einzuordnen sind \cite{painter_practical_2024}.

		\subsection{Betrieb}

		Im laufenden Betrieb wird GitLab über das Kommandozeilenwerkzeug \texttt{gitlab-ctl} gesteuert. Damit lassen sich die Hintergrunddienste starten, stoppen und überwachen \cite{painter_practical_2024}. Aktualisiert wird über den Paketmanager und das von GitLab vorgegebene Versionsschema. Beim Überspringen mehrerer Hauptversionen ist eine bestimmte Reihenfolge zwingend einzuhalten, da die enthaltenen Datenbankmigrationen aufeinander aufbauen. Ein direkter Sprung von einer alten auf eine deutlich neuere Version kann den Datenbestand inkonsistent zurücklassen \cite{gitlab_gitlab_nodate}. Sicherungen werden über den Befehl \texttt{gitlab-backup create} erzeugt und umfassen die \texttt{PostgreSQL}-Datenbank sowie alle Repositories und Artefakte.

		Welche Folgen ein nicht funktionierendes Backup haben kann, zeigt der bereits in Abschnitt~1.3 angesprochene \textit{GitLab.com Database Incident} aus dem Jahr 2017. Durch eine fehlerhafte manuelle Aktion gingen sechs Stunden Nutzerdaten verloren \cite{GitLabcomDatabaseIncident}. Betroffen war zwar die \ac{SaaS}-Instanz, das Beispiel ist aber auch für eine eigene Instanz von Bedeutung. Ein Backup, das nicht regelmässig in einem Restore-Test überprüft wird, ist im Ernstfall kein Backup. Painter~\cite{painter_practical_2024} weist zudem darauf hin, dass die eigentlichen Aufwände bei einer Self-Managed-Instanz nicht in der Erstinstallation, sondern über die Lebensdauer hinweg anfallen. Dazu zählen Sicherheitsaktualisierungen, regelmässige Restore-Tests und die Überwachung der Datenbankkonsistenz.
		
		\section{Evaluierung}
		
		\subsection{Vorgehensweise}
		
		%Kriterien ausdenken
		
		\subsection{Funktionalität}
		
		\subsection{Performanz}
		
		\subsection{Nachhaltigkeit}
		
		Unter Betrachtung der in \ref{sec:scalability} erwähnten Referenzarchitektur wird betrachtet inwiefern die von GitLab vorgeschlagenen Architekturen sich bezüglich ihres Stromverbrauchs bemessen. GitLab liefert Empfehlungen für virtuelle Server für die Anbieter \ac{GCP}, \ac{AWS} und Azure. Ausgenommen von GPUs sind CPU und Arbeitsspeicher die Komponenten mit dem höchsten Stromverbrauch \cite{davyEstimatingAWSEC22022}. im folgenden wird eine Schätzung abgeben, die auf Daten von \ac{AWS} Instanzen basieren und sich auf die Leistung von CPU und Arbeitsspeicher beschränkt. Im konkreten werden Instanzen der Typen \texttt{c5, c5n} und \texttt{m5} in der GitLab Empfehlung erwähnt. \\ 
		Für unterschiedliche \ac{AWS}-Instanzen liefert \cite{davyEstimatingAWSEC22022} einen Datensatz der Auskunft über die Leistung in Watt nach Anzahl der vCPUS ,unter einer bestimmten Auslastung, gibt. Eine \ac{vCPU} bezeichnet eine virtualisierte Variante einer physischen CPU \cite{VCPUWasIst2023}. Es ist zu beachten, dass die Testdaten aus \ref{tab:power_consumption} untertakteten Instanzen stammen und bieten eine untere Schätzung. Ebenso wird angenommen, dass der Arbeitsspeicher immer in Relation zur Anzahl von \ac{vCPU}s liegt und ist in \ref{tab:power_consumption} miteinbezogen.
		\begin{table}[H]
			\centering
			\resizebox{\columnwidth}{!}{%
				\begin{tabular}{@{}llllllllllll@{}}
					\toprule
					Typ & 0\% & 10\% & 20\% & 30\% & 40\% & 50.00\% & 60\% & 70\% & 80\% & 90\% & 100\% \\ \midrule
					c5            & 2      & 2.3     & 2.7     & 3.1     & 3.5     & 3.8     & 4.2     & 4.6     & 5       & 5.4     & 5.7      \\
					m5            & 2.1    & 2.4     & 2.8     & 3.1     & 3.4     & 3.7     & 4.1     & 4.4     & 4.7     & 5       & 5.4  \\ \bottomrule   
				\end{tabular}%
			}
			\caption{Leistung in Watt für eine vCPU abgestuft nach Auslastung \cite{davyEstimatingAWSEC22022}}
			\label{tab:power_consumption}
		\end{table}
		Da in \ref{tab:power_consumption} keine Daten zu \texttt{c5n} enthalten sind, werden die Werte mit denen von \texttt{c5} geschätzt. Abbildung \ref{fig:estimation_power} zeigt die Schätzung der Leistung für die empfohlenen Referenzarchitekturen nach Benutzern für eine Abstufung nach Auslastung. 
		\begin{figure}[H]
			\includegraphics[width=\columnwidth]{./bilder/power_consumption.png}
			\caption{Schätzung der Leistung nach Anzahl der Nutzer}
			\label{fig:estimation_power}
		\end{figure}
		Die grösstmögliche Architektur kann dabei eine Leistung von ca. 1548 Watt bis zur Höchstlast von 4412 Watt in Anspruch nehmen. Die kleinste Architektur liegt bei ungefähr maximal 46 Watt. Ein durchschnittlicher Office-PC benötigt 135 bis 200 Watt die Stunde. Ein Gaming-PC üblicherweise bis zu 350 Watt \cite{WievielStromVerbraucht}.
		
		\subsection{Sicherheit}
		
		Eine eigene GitLab-Instanz kann so konfiguriert werden, dass diese dem US-amerikanischen Sicherheitsstandard \acs{NIST} \acs{SP} 800-53 für Sicherheitskontrolle in Informationssystemen des \acl{NIST} entsprechen \cite{gitlab_gitlab_nodate}. Die Angebote von GitLab, damit die \ac{SaaS}-Version bzw. GitLab.com und GitLab Dedicated sind nach \acs{ISO}/\acs{IEC} 27001:2022 zertifiziert \cite{GitLab16522166}. Diese Norm spezifiziert Anforderungen an Informationssicherheitsmanagement im Kontext von Organisationen. Für dieselben Angebote besitzt GitLab eine Zertifizierung nach Norm \acs{ISO}/\acs{IEC} 27017:2015, welche Richtlinien zur Kontrolle der Informationssicherheit von Cloud-Services festlegt \cite{gitlab_gitlab_nodate}. Es ist zu erwarten, dass diese Norm bald erneuert wird \cite{ISOIEC27017}.
		Im folgenden Abschnitt wird darauf eingegangen mit welchen Möglichkeiten wie GitLab vor Angriffen von ausserhalb geschützt werden kann. Die GitLab-Dokumentation unterteilt Schutzmassnahmen in die Kategorien \cite{gitlab_gitlab_nodate}:
		\begin{itemize}
			\item Anwendungseinstellungen
			\item \acs{CI}/\acs{CD} Einstellungen
			\item Konfigurationseinstellungen
			\item Betriebssystemeinstellungen
		\end{itemize}
		Innerhalb der Anwendungseinstellungen können Push-Regeln festgelegt werden, sodass unverifizierte Nutzer keinen Code hochladen können. Es kann sichergestellt werden, dass geheime Dateien nicht versehentlich gepusht werden. Ebenso sollen projektspezifische Keys/Schlüssel für Deployment-Prozesse eingerichtet werden. Die Sichtbarkeit von Gruppen, Snippets und Projekten soll als \textit{privat} gesetzt werden. Benutzer können gezwungen werden komplexere Passwörter für ihren GitLab Account zu wählen. Eine 2-Faktor Authentifizierung kann eingerichtet werden. Die Kommunikation mit aussenstehenden Systemen kann konkret festgelegt werden, indem externe Systeme zuerst anhand ihrer IP-Adresse für ausgehende anfragen in GitLab eingetragen werden müssen. Für die GitLab-Instanz kann ein Rate-Limit, mit Ausnahmen für bestimmte Nutzer, eingestellt werden \cite{gitlab_gitlab_nodate}.\\
		Für \acs{CI}/\acs{CD}-Pipelines besteht die Möglichkeit sensitive Daten wie bspw. Passwörter oder Tokens in Form von \textit{Secrets} zu speichern. \textit{Secrets} werden durch externe Dienstleister gespeichert. Neben \textit{Secrets} besteht die weniger empfohlene Variante Daten in Form von \textit{CI/CD Variablen} zu speichern. Eine solche Variable kann maskiert werden und wird damit in Logs durch einen definierten Platzhalter ersetzt. Zusätzlich zu einer Maskierung erlaubt GitLab \textit{CI/CD Variablen} verstecken. Die Variable wird nicht mehr auf der Einstellungsseite für \acs{CI}/\acs{CD} angezeigt. Ebenso kann eine Variable geschützt werden, sodass nur auf geschützten Branches  Zugriff besteht \cite{gitlab_gitlab_nodate}.\\
		Eine GitLab-Instanz kann konfiguriert werden, sodass Nutzer per \ac{SSH} oder über \ac{HTTPS} zugreifen können \cite{gitlab_gitlab_nodate}. Ein Zugang kann auf eine der beiden Protokolle beschränkt werden. \ac{HTTPS} ist meist zugänglicher für Nutzer, da wenig Konfiguration vorgenommen werden muss. Allerdings wird die Authentifizierung per Nutzername und \textit{Access Token} oder Passwort vorgenommen, welche häufig erneut abgefragt werden. \ac{SSH} bietet eine höhere Sicherheit. Es ist sichergestellt, dass keine Daten während der Übertragung unbemerkt verändert werden. Die Konfiguration ist komplexer. \ac{SSH} basiert auf einer \textit{Public-Key}-Infrastruktur, wobei der öffentliche Schlüssel auf GitLab zuvor hinterlegt werden muss \cite{marijanSSHVsHTTPS2025}. GitLab kann ebenso E-Mails versenden und empfangen. Versendete E-mails können mit \ac{S/MIME} versendet signiert werden, um deren Legitimität zu sichern \cite{gitlab_gitlab_nodate}. \ac{S/MIME} ist ein Verschlüsselungsstandard für E-Mails.\\
		Die GitLab-Dokumentation bietet zusätzlich Konfigurationen für das unterliegende Betriebssystem, wie \ac{SSH}-Konfiguration, Firewall Einstellungen und Änderungen am Kernel \cite{gitlab_gitlab_nodate}.
		
		\subsection{Kompatibilität}
		
		GitLab als Code-Hosting Plattform ist ausschließlich für Linux-Distributionen erhältlich. Es wird differenziert in die kostenpflichtige Variante \ac{EE} und die kostenlose \ac{CE} erhältlich.
		GitLab plant Pakete hauptsächlich für Betriebssysteme, mit \ac{LTS} Versionen zu veröffentlichen. Releases werden nicht mehr publiziert, wenn der Anbieter des Betriebssystems \ac{EOL} des Systems bekannt gibt. GitLab nimmt sich die Freiheit unter anderen Gründen den Support für ein Betriebssystem einzustellen \cite{gitlab_gitlab_nodate}:
		\begin{itemize}
			\item \emph{keine Wirtschaftlichkeit}, da zu hohe Wartungskosten oder zu wenig Kunden auf die Technologien setzen
			\item \emph{technische Einschränkungen} wie bspw. zusätzliche Abhängigkeiten, Sicherheitsanforderungen oder technologische Veränderungen die eine Erstellung von Paketen erschwert oder unmöglich gestaltet.
		\end{itemize}
		Die folgende Tabelle \ref{tab:supported_os} zeigt eine Auflistung aller aktuell (zum 15.05.2026) von GitLab unterstützten Betriebssysteme und ihrer Architekturen (Siehe \url{https://docs.gitlab.com/install/package/#supported-platforms}). Neben den offiziellen GitLab-Paketen existieren ebenso inoffizielle Pakete der GitLab-Community.
		\begin{table}[H]
			\centering
			\resizebox{\columnwidth}{!}{%
				\begin{tabular}{@{}llll@{}}
					\toprule
					Betriebsystem                & OS-Version   & CE & EE  \\ \midrule
					AlmaLinux                    & 8-10         & X  & X \\
					Amazon Linux                 & 2, 2023      & X  & X \\
					Debian                       & 11-13        & X  & X  \\
					openSUSE Leap                & 15.6         & X  & X  \\
					\makecell[cl]{SUSE Linux Enterprise Server} & 12           &    & X  \\
					Oracle Linux                 & 8-9          & X  & X  \\
					\makecell[cl]{Red Hat Enterprise Linux }    & 8-10         & X  & X\\
					Ubuntu                       & \makecell[cl]{22.04, 24.04} & X  & X\\ \bottomrule
				\end{tabular}%
			}
			\caption{unterstützte Betriebssysteme für GitLab}
			\label{tab:supported_os}
		\end{table}
		 Folgende Installationsmöglichkeiten existieren für \ac{CE} und \ac{EE} sowie für GitLab Runner:
		\begin{itemize}
			\item Installation als Linux-Paket für das jeweilige unterstützte Betriebssystem
			\item Betrieb mithilfe des offiziellen Docker-Images von GitLab (Siehe Dockerhub:  \url{https://hub.docker.com/u/gitlab})
			\item In Kubernetes als Helm-Chart, einem speziellen Paketformat für Kubernetes
			\item Installation per GitLab Operator unter Kubernetes. Ein Kubernetes Operator erlaubt Erweiterung bzgl. des Verhaltens von Clustern, ohne dabei den ursprünglichen Quellcode von Kubernetes zu modifizieren.
		\end{itemize}
		GitLab Runner kann für eine grössere Auswahl an Betriebssystemen installiert werden. Tabelle \ref{tab:runner_os} zeigt eine Auflistung unterstützter Versionen von Betriebssystemen für GitLab Runner. Wird - verwendet, so ist keine Version von GitLab für das jeweilige Betriebssystem spezifiziert.
		\begin{table}[H]
			\centering
			\resizebox{\columnwidth}{!}{%
				\begin{tabular}{@{}ll@{}}
					\toprule
					Betriebsystem                & OS-Version                       \\ \midrule
					Debian                       & 11-15                            \\
					Mint                         & 21-22.1                          \\
					Raspbian                     & 11-15                            \\
					Ubuntu                       & 25.10, 24.04, 22.04, 20.4, 18.04 \\
					Amazon Linux                 & 2, 2023, 2025                    \\
					\makecell[cl]{Red Hat\\Enterprise Linux}     & 7-10                             \\
					Fedora                       & 42, 43                           \\
					Oracle Linux                 & 10, 9, 8, 7                      \\
					openSUSE                     & 16.0, 15.6                       \\
					\makecell[cl]{SUSE Linux\\Enterprise Server} & 15.7, 15.6, 15.5, 15.4, 12.5     \\
					FreeBSD                      & -                                \\
					Windows                      & -                                \\
					macOS                        & -                                \\ \bottomrule
				\end{tabular}%
			}
		\caption{Unterstützte Betriebssysteme für GitLab Runner}
		\label{tab:runner_os}
		\end{table}
		Zur Kompatibilität zählt ebenso die Möglichkeit von anderen Code-Hosting Plattformen zu GitLab zu migrieren. GitLab bietet nur die Möglichkeit an automatische Migrationen von Git-Repositories durchzuführen. Auf \ac{SVN} basierende Repositories müssen externe Werkzeuge (wie bspw. \href{https://git-scm.com/book/en/v2/Git-and-Other-Systems-Migrating-to-Git}{git svn} oder  \href{http://www.catb.org/~esr/reposurgeon/repository-editing.html}{Reposurgeon})verwendet werden um diese in Git-Repositories umzuwandeln. Für eine Auswahl an Plattformen bietet GitLab ein Migrationswerkzeug. Bei der Migration werden, bspw. für Autoren von Commits, Platzhalter für Nutzer eingeführt. Es besteht die Möglichkeit Platzhalter-Nutzer wieder realen Nutzern der GitLab-Instanz zuzuordnen. Dieser Vorgang wird als \textit{Post-migration Mapping} bezeichnet. Wird das Projekt in den Namensraum eines Nutzers exportiert, ist eine solche Zuordnung nicht möglich. Stattdessen wird dem Besitzer des Namensraum jeder Beitrag zugeordnet.  \cite{gitlab_gitlab_nodate}. Tabelle \ref{tab:migration_platforms} zeigt eine Auflistung an Plattformen bzw. Repositories, für die Gruppen oder Projekte, unter der Verwendung des Migrationswerkzeug und \textit{Post-migration Mapping} importiert werden können.
		\begin{table}[H]
			\centering
			\resizebox{\columnwidth}{!}{%
				\begin{tabular}{@{}lllll@{}}
					\toprule
					Ursprung                   & Gruppen & Projekte & Werkzeug & Post-Mapping \\ \midrule
					GitLab (direkter Transfer) & X       & X        & X        & X            \\
					GitLab (Datei-Export)      & X       & X        & X        & -            \\
					Bitbucket Server           & -       & X        & X        & X            \\
					GitHub                     & -       & X        & X        & X            \\
					Gitea                      & -       & X        & X        & X            \\
					Bitbucket Cloud            & -       & X        & X        & -            \\
					FogBugz                    & -       & X        & X        & -            \\
					Git Repo (Manifest)        & -       & X        & X        & -            \\
					Git Repo (URL)             & -       & X        & X        & -            \\
					IBM Devops ClearCase       & -       & X        & -        & -            \\
					\acs{CVS}                        & -       & X        & -        & -            \\
					Perforce P4                & -       & X        & -        & -            \\
					Subversion                 & -       & X        & -        & -            \\
					\acs{TFVC}                       & -       & X        & -        & -            \\
					Jira (Issues)              & -       & -        & X        & -            \\ \bottomrule
				\end{tabular}}
			\caption{Migrations-Unterstützung von GitLab}
			\label{tab:migration_platforms}
		\end{table}
		\subsection{Skalierbarkeit}
		
		\label{sec:scalability}
		
		GitLab bietet Empfehlungen für Referenz-Architekturen, welche versuchen einen Kompromiss zwischen den Kriterien Performanz, Resilienz und finanzieller Kosten herzustellen. Um eine passende Architektur zu wählen orientiert sich GitLab an der Metrik: \ac{RPS}. Die RPS lassen sich nach Anfrage in folgende Typen aufgliedern \cite{gitlab_gitlab_nodate}:
		\begin{itemize}
			\item API-Anfragen, zu welchen Integrationen, Automatisierungsmechanismen, Webhooks und sonstige Dienste, die direkt auf die API zugreifen, gehören. Üblicherweise machen API-Anfragen ca. 80 \% der gesamten \ac{RPS}-Anfragen aus
			\item Web-Anfragen, dazu zählen beispielsweise Interaktionen mit der Weboberfläche. Dies sind meist 10 \% aller Anfragen.
			\item Git-Operationen, hier aufgeschlüsselt in Pull und Push-Operationen. Git-Operationen entsprechen ca. den restlichen 10 \%.
		\end{itemize}
		Mithilfe von Abbildung \ref{fig:reference_architecture_users} lassen sich ungefähre Anzahlen an \ac{RPS} nach Benutzern einer GitLab-Instanz schätzen. In einigen Umgebungen können die vorgegebenen Schätzungen von der Realität stark abweichen. Es ist notwendig selbst zu evaluieren wie das System aufgebaut werden soll bzw. welche Anpassungen gemacht werden müssen.
		\begin{figure}[H]
			\includegraphics[width=\columnwidth]{bilder/gitlab_reference_architecture_users_rps.png}
			\caption{RPS-Schätzung nach Benutzeranzahl für das Linux-Paket \cite{gitlab_gitlab_nodate}}
			\label{fig:reference_architecture_users}
		\end{figure} Im Grunde gibt es zwei Möglichkeiten zu skalieren. Dazu zählt die Verwendung einer höher liegenden Referenzarchitektur oder die horizontale oder Vertikale Skalierung einzelner Komponenten. Bei der horizontalen Skalierung müssen Lastverteiler hinzugefügt und konfiguriert werden.
		GitLab bietet für einige Intervalle an zu erwartenden Nutzern (bzw. \ac{RPS}) Empfehlungen für \href{https://docs.gitlab.com/administration/reference_architectures/}{Architekturen}. Alle Architekturen sind auf eine Skalierung ausgelegt. Weitere Funktionalitäten ergeben erst ab einer gewissen Anzahl an Benutzern Sinn. Der Betrieb von GitLab im High Availability Modus stellt sicher, dass einzelne Komponenten bei Ausfällen kompensiert werden können. Durch Redundanz ergeben sich höhere finanzielle Kosten. GitLab gibt an, dass die Schwelle für den Betrieb im High Availability Modus bei ungefähr 3000 Nutzern liegt \cite{gitlab_gitlab_nodate}. Um die Ausfallsicherheit weiter zu erhöhen kann GitLab in mindestens zwei Umgebungen innerhalb unterschiedlicher Regionen betrieben werden. Dies führt zu höheren Kosten und einem komplexeren Systemaufbau. Einzelne Komponenten von GitLab können in die Cloud ausgelagert werden. Grössere Repositories, sogenannte \textit{Monorepos} mit einer Grösse von mehreren Gigabytes, können zu hohen Auslastungen führen. Die hohe Last ist softwareseitig begründet, weshalb die Skalierung durch zusätzliche Hardware kaum Nutzen erweist. Die Auslastung kann durch Optimierungsmassnahmen am Repository verringert werden \cite{gitlab_gitlab_nodate}. Eine Gefahr beim Skalieren einer einzelnen Komponente kann zu ungewollten Konsequenzen führen. Die empfohlenen Architekturen sind so ausgelegt, dass die Skalierung der einzelnen Komponenten in einem passenden Verhältnis zueinander stehen. Besitzt eine skalierte Komponente einen höheren Durchlauf kommt die Last, bei abhängigen Komponenten an. Diese müssen zwangsweise ebenso skaliert werden \cite{gitlab_gitlab_nodate}.
		
		
		\subsection{Dokumentation}
		
		Alle GitLab-Lösungen sind umfassend auf der offiziellen Seite \url{https://docs.gitlab.com/} dokumentiert. Jeder Release von GitLab besitzt bezüglich Haupt- und Nebenversionsnummer eine eigene Version der Dokumentation. Online kann auf eine eingeschränkte Auswahl zugegriffen werden. Nach den Ausgaben der Dokumentation kann unter \url{https://archives.docs.gitlab.com/} gesucht werden. Diese Suche reicht zurück bis zur Version 16.0. Nach Bedarf können ältere Versionen im Offline-Archiv \url{https://docs.gitlab.com/archives/#offline-archives} als Docker-Container heruntergeladen und gestartet werden. Das Offline Archiv reicht bis zu der Version 10.3 zurück. Die Dokumentation wird aus den Quellcode-Repositories der GitLab Projekte gebaut und in regelmässigen Abständen aktualisiert \cite{gitlab_gitlab_nodate}.
		
		\section{Diskussion}
		
		\section{Ausblick}
		
		\section{Zusammenfassung}
		
		
		
		\section*{Abkürzungsverzeichnis}
		\begin{acronym}[Abkürzungsverzeichnis]
			\acro{IDE}{Integrated Development Environment}
			\acro{CD}{Continuous Delivery, kontinuierliche Auslieferung}
			\acro{SaaS}{Software as a Service}
			\acro{CI}{Continuous Integration, kontinuierliche Integration}
			\acro{NASDAQ}{National Association of Securities Dealers Automated Quotations}
			\acro{GLFM}{Gitlab Flavored Markdown}
			\acro{EOL}{End of Life}
			\acro{LTS}{Long Term Support}
			\acro{CE}{Community Edition}
			\acro{EE}{Enterprise Edition}
			\acro{OS}{Operating System}
			\acro{SVN}{Subversion}
			\acro{TFVC}{Team Foundation Version Control (TFVC)}
			\acro{CVS}{Concurrent Versions System}
			\acro{OSS}{Open Source Software}
			\acro{TLS}{Transport Layer Security}
			\acro{DAG}{Directed Acyclic Graph}
			\acro{URL}{Uniform Resource Locator}
			\acro{SP}{Special Publication}
			\acro{NIST}{National Institute of Standards and Technology}
			\acro{ISO}{Internationale Organisation für Normung}
			\acro{IEC}{International Electrotechnical Commission}
			\acro{HTTPS}{Hypertext Transfer Protocol Secure}
			\acro{SSH}{Secure Shell}
			\acro{S/MIME}{Secure/Multipurpose Internet Mail Extensions}
			\acro{RPS}{Requests per Second}
			\acro{GCP}{Google Cloud Platform}
			\acro{AWS}{Amazon Web Services}
			\acro{vCPU}{virtual Central Processing Unit}
		\end{acronym}
		
		\printbibliography
	\end{multicols}
	
\end{document}
