Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Cloud / Hosting 14.08.2026 · 9 min Lesezeit Geprüft 30.09.2026

Harness Open Source mit Docker installieren: End-to-End-DevOps-Plattform mit Git, CI/CD und Artifact-Registry

Harness Open Source vereint Git-Hosting, CI/CD-Pipelines und Artifact-Registry in einem Docker-Container. Die Anleitung zeigt den Aufbau mit Docker Compose und PostgreSQL, die kritischen Variablen und typische Fehler.

Werbung Mit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Mehr dazu

Titelbild: Harness mit Docker installieren, Git, CI/CD, Registry

Für einen selbst gehosteten DevOps-Stack kombinieren viele Teams Gitea, ein CI-System wie Jenkins oder Drone und eine separate Artifact-Registry. Harness Open Source (bis Version 3.0 unter dem Namen Gitness bekannt) bündelt Git-Hosting mit Code-Review und Vulnerability-Scanning, CI/CD-Pipelines mit wiederverwendbaren Templates, sogenannte Gitspaces als vorkonfigurierte Dev-Environments und eine Artifact-Registry für Container-Images und andere Artefakte in einem Docker-Image. Die Lizenz ist Apache 2.0. Die aktuelle stabile Version ist 3.3.0 vom August 2025; entwickelt wird weiter im Tag unstable.

Voraussetzungen

  • Linux-Host oder VM (x86_64 oder arm64): Ubuntu 22.04/24.04, Debian 12 oder vergleichbar; läuft ebenso auf einem NAS mit Docker-Unterstützung
  • Ressourcen: mindestens 2 CPU-Kerne und 2 GB RAM für den Basis-Betrieb; für aktive CI/CD-Workloads empfehlen sich 4 Kerne und 4 bis 8 GB RAM, da Pipeline-Container direkt auf dem Host-Docker laufen
  • Docker Engine 20.10+ mit Docker Compose v2 (Plugin, nicht das veraltete docker-compose v1). Falls noch nicht installiert, hilft die Anleitung Docker und Docker Compose auf Linux installieren
  • openssl zur Schlüsselgenerierung (auf allen gängigen Distributionen vorinstalliert)
  • Ports 3000 und 3022 in Ihrer Firewall/Security-Group freigegeben: 3000 für Web-UI, REST-API und Git-HTTP, 3022 für SSH-Git-Zugriff
  • Mindestens 20 GB freier Speicherplatz für Repositories, Datenbank und Artifact-Registry
  • Optional: Domain und Reverse Proxy (Nginx, Caddy, Traefik) für HTTPS, siehe Caddy als Reverse Proxy mit automatischem HTTPS

Schritt 1: Projektordner anlegen

Legen Sie einen eigenen Ordner für den Harness-Stack an. Alle Konfigurationsdateien gehören dort hinein:

$ sudo mkdir -p /opt/harness
$ cd /opt/harness

Wer keinen root-Zugriff hat oder lieber im Home-Verzeichnis arbeitet, kann auch ~/harness verwenden. Die Compose-Konfiguration funktioniert in beiden Fällen identisch.

ls -la /opt/harness zeigt das leere Verzeichnis. Der Ordner muss existieren, bevor Sie die nächsten Dateien anlegen.

Schritt 2: .env-Datei mit Secrets befüllen

Die .env-Datei enthält alle sensitiven Werte. Docker Compose liest sie automatisch ein, wenn sie im selben Verzeichnis wie die compose.yaml liegt. Erstellen Sie sie mit folgendem Inhalt und passen Sie die Werte an:

# Harness Open Source: Umgebungsvariablen
# /opt/harness/.env

# Admin-Konto (NUR beim allerersten Start mit leerer DB wirksam!)
HARNESS_ADMIN_EMAIL=admin@example.com
HARNESS_ADMIN_PASSWORD=IHR_ADMIN_PASSWORT

# AES-Verschlüsselungsschlüssel für Connector-Secrets in der DB
# Generieren: openssl rand -hex 16
# ACHTUNG: Diesen Wert nach dem ersten Start NIEMALS ändern!
HARNESS_SECRET_KEY=IHR_HEX_SCHLUESSEL

# PostgreSQL-Datenbankpasswort
POSTGRES_PASSWORD=IHR_DB_PASSWORT

# Öffentlich erreichbare URL Ihres Servers (ohne Schrägstrich am Ende)
# Für lokalen Test: http://localhost:3000
# Für Remote-Zugriff: http://SERVER-IP:3000
# Hinter Reverse Proxy: https://git.example.com
HARNESS_URL_BASE=http://SERVER-IP:3000

Den Schlüssel für HARNESS_SECRET_KEY erzeugen Sie einmalig per:

$ openssl rand -hex 16

Kopieren Sie die Ausgabe in die .env-Datei. Dieser Wert darf später nicht mehr verändert werden, sonst können gespeicherte Connector-Secrets (z. B. GitHub-Tokens) nicht mehr entschlüsselt werden.

cat /opt/harness/.env zeigt alle fünf Variablen ohne Leerzeilen oder Sonderzeichen-Fehler. Die Datei darf nur für den eigenen Benutzer lesbar sein: chmod 600 /opt/harness/.env.

Schritt 3: compose.yaml erstellen

Die folgende Konfiguration startet Harness zusammen mit einer PostgreSQL 16-Datenbank. Der depends_on-Block mit condition: service_healthy stellt sicher, dass Harness erst startet, wenn PostgreSQL bereit ist.

services:
  harness:
    image: harness/harness:3.3.0
    container_name: harness
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "3000:3000"
      - "3022:3022"
    volumes:
      - harness_data:/data
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - GITNESS_PRINCIPAL_ADMIN_EMAIL=${HARNESS_ADMIN_EMAIL:-admin@example.com}
      - GITNESS_PRINCIPAL_ADMIN_PASSWORD=${HARNESS_ADMIN_PASSWORD}
      - GITNESS_ENCRYPTER_SECRET=${HARNESS_SECRET_KEY}
      - GITNESS_DATABASE_DRIVER=postgres
      - GITNESS_DATABASE_DATASOURCE=host=db port=5432 sslmode=disable dbname=harness user=harness password=${POSTGRES_PASSWORD}
      - GITNESS_URL_BASE=${HARNESS_URL_BASE:-http://localhost:3000}
      - GITNESS_URL_CONTAINER=http://harness:3000
      - GITNESS_URL_REGISTRY=http://harness:3000
      - GITNESS_CI_CONTAINER_NETWORKS=harness_network
      - GITNESS_CI_PARALLEL_WORKERS=2
      - GITNESS_USER_SIGNUP_ENABLED=false
      - GITNESS_METRIC_ENABLED=false
    networks:
      - harness_network

  db:
    image: postgres:16-alpine
    container_name: harness_db
    restart: unless-stopped
    environment:
      - POSTGRES_DB=harness
      - POSTGRES_USER=harness
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U harness -d harness"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - harness_network

volumes:
  harness_data:
  postgres_data:

networks:
  harness_network:
    driver: bridge

Der Docker-Socket /var/run/docker.sock ist Pflicht, damit CI/CD-Pipelines und Gitspaces Container auf dem Host starten können. Damit hat Harness faktisch Root-Rechte auf dem Host: Betreiben Sie es nur auf einem dafür vorgesehenen Server. Die Variable GITNESS_CI_CONTAINER_NETWORKS=harness_network sorgt dafür, dass diese Pipeline-Step-Container ebenfalls im selben Netzwerk landen und die Harness-API über GITNESS_URL_CONTAINER=http://harness:3000 erreichen können.

GITNESS_USER_SIGNUP_ENABLED=false deaktiviert die offene Selbstregistrierung; neue Nutzer legt der Admin an. GITNESS_METRIC_ENABLED=false schaltet die Nutzungsstatistik ab, die Harness sonst an stats.drone.ci sendet.

ParameterWertHinweis
Imageharness/harness:3.3.0Ehemals harness/gitness (veraltet seit v3.0)
Port 3000Web-UI, REST-API, Git-HTTPHaupt-Einstiegspunkt
Port 3022SSH-Git-ZugriffOptional, für git clone ssh://...
Volume harness_data/data im ContainerRepos, Cache, Artifact-Registry
Volume postgres_dataPostgreSQL-DatenbankdateienGetrennt von Harness-Daten
Docker Socket/var/run/docker.sockPflicht für CI/CD-Pipelines
DatenbankPostgreSQL 16Standard wäre SQLite3 (nicht empfohlen)
LizenzApache 2.0Kein Cloud-Konto nötig

Syntax vor dem Start prüfen:

$ docker compose -f /opt/harness/compose.yaml config --quiet && echo "Syntax OK"

Die Ausgabe Syntax OK bestätigt eine valide YAML-Struktur. Fehlende .env-Werte werden hier als Warnung angezeigt.

Schritt 4: Stack starten

Wechseln Sie in den Projektordner und starten Sie den Stack:

$ cd /opt/harness
$ docker compose up -d

Docker zieht beide Images (harness/harness:3.3.0 und postgres:16-alpine), erstellt die Named Volumes und das Bridge-Netzwerk, wartet auf den PostgreSQL-Healthcheck und startet danach Harness. Beim allerersten Start legt Harness alle Datenbanktabellen an und erstellt das Admin-Konto aus den .env-Variablen.

Status beider Container prüfen:

$ docker compose ps

Erwartete Ausgabe (beide Container Up, db mit healthy):

NAME          IMAGE                    STATUS
harness       harness/harness:3.3.0    Up About a minute
harness_db    postgres:16-alpine       Up About a minute (healthy)

Logs von Harness ansehen:

$ docker compose logs harness --tail=30

Eine Startmeldung ohne Fehler zeigt einen erfolgreichen Start. Fehlermeldungen zu Datenbankverbindungen deuten auf ein Problem mit der .env oder dem PostgreSQL-Container hin.

Abschließend per HTTP-Check:

$ curl -I http://localhost:3000/api/v1/system/health

Erwartete Antwort: HTTP/1.1 200 OK.

Schritt 5: Erst-Einrichtung im Browser

Öffnen Sie http://SERVER-IP:3000 im Browser und melden Sie sich mit der E-Mail und dem Passwort aus der .env-Datei an.

Nach dem Login empfehlen sich folgende erste Schritte in der Web-UI:

  1. Projekt anlegen: Über „New Project“ ein Projekt für Ihr Team erstellen. Repositories, Pipelines und Einstellungen werden darunter gruppiert.
  2. Repository erstellen oder importieren: Unter „Repositories“ über „New Repository“ ein Repo anlegen oder ein bestehendes von GitHub/GitLab mit Code-History importieren.
  3. Clone-URL prüfen: Öffnen Sie ein Repository und kontrollieren Sie die Clone-URL. Sie muss mit dem Wert von HARNESS_URL_BASE beginnen, nicht mit http://localhost. Zeigt sie localhost, stimmt die Variable nicht.
  4. CI-Pipeline testen: Legen Sie eine Pipeline im Repository an und starten Sie sie manuell. Das testet die Docker-Socket-Integration und das Netzwerk-Routing der Pipeline-Steps.

http://SERVER-IP:3000/api/v1/system/version liefert die Version 3.3.0 als JSON. Eine erfolgreiche Anmeldung und das Erscheinen der Dashboard-Übersicht zeigen, dass das Admin-Konto korrekt angelegt wurde.

Schritt 6: Updates und Backups

Harness führt Datenbankmigrationen automatisch beim Start durch. Erstellen Sie vor jedem Update trotzdem ein Backup:

# Stack stoppen (Konsistenz-Sicherung)
cd /opt/harness
docker compose stop

# Harness-Daten sichern (Named Volume)
docker run --rm \
  -v harness_harness_data:/data \
  -v $(pwd)/backups:/backup \
  alpine tar czf /backup/harness-backup-$(date +%Y%m%d).tar.gz /data

# PostgreSQL-Dump
docker compose start db
docker exec harness_db pg_dump -U harness harness \
  > ./backups/harness-db-$(date +%Y%m%d).sql

# Neue Version in compose.yaml eintragen, dann:
docker compose pull
docker compose up -d

Für Update-Benachrichtigungen ohne automatische Updates eignen sich DIUN oder WUD, mehr dazu in der Anleitung Docker-Container automatisch aktualisieren nach dem Watchtower-Aus.

Nach dem Update:

$ docker compose ps
$ docker compose logs harness --tail=20

Beide Container zeigen Up, keine Fehlermeldungen zu Datenbankmigrationen in den Logs. Die Web-UI ist weiterhin erreichbar und zeigt die bisherigen Daten.

Troubleshooting / Typische Fehler

  1. Clone-URLs zeigen localhost statt Server-IP: GITNESS_URL_BASE ist nicht gesetzt oder enthält noch den Platzhalterwert. In der .env auf http://SERVER-IP:3000 (oder die HTTPS-Domain) setzen, dann docker compose up -d.
  2. CI/CD-Pipelines starten nicht / Steps erreichen Harness-API nicht: GITNESS_URL_CONTAINER zeigt auf localhost statt auf den Container-Namen harness, oder GITNESS_CI_CONTAINER_NETWORKS ist nicht auf das Compose-Netzwerk gesetzt. Beide Variablen wie in der compose.yaml oben konfigurieren.
  3. Datenverlust nach Neustart: Quick-Start-Beispiele aus der offiziellen Doku nutzen /tmp/harness als Bind-Mount. /tmp wird auf vielen Systemen beim Reboot geleert. Immer ein Named Volume oder einen Pfad außerhalb /tmp (z. B. /opt/harness/data) verwenden.
  4. permission denied auf /var/run/docker.sock: Standardmäßig läuft Harness als root, was ausreicht. Läuft der Container mit anderem Benutzer, muss dieser Mitglied der docker-Gruppe auf dem Host sein.
  5. Admin-Konto funktioniert nicht nach Passwort-Änderung in .env: GITNESS_PRINCIPAL_ADMIN_EMAIL und GITNESS_PRINCIPAL_ADMIN_PASSWORD werden ausschließlich beim allerersten Start (leere Datenbank) ausgewertet. Passwort-Reset erfolgt über die Web-UI oder direkt in PostgreSQL.
  6. PostgreSQL-Healthcheck schlägt fehl / Harness startet zu früh: Nur relevant, wenn depends_on ohne condition: service_healthy genutzt wird. Die compose.yaml dieser Anleitung enthält den Healthcheck.
  7. SSH-Port 3022 bereits belegt: Einen alternativen Host-Port wählen ("2222:3022") und den SSH-Client entsprechend konfigurieren: git clone ssh://git@SERVER-IP:2222/org/repo.
  8. Altes harness/gitness-Image im Einsatz: Dieses Image erhielt seit v3.0.0-beta.12 keine Updates mehr. Stattdessen harness/harness mit fester Version verwenden.
  9. GITNESS_ENCRYPTER_SECRET nachträglich gesetzt oder geändert: Alle bisher gespeicherten Connector-Secrets können danach nicht mehr entschlüsselt werden. Den Schlüssel beim ersten Start setzen und in einem Passwortmanager sichern.

Häufige Fragen

Brauche ich zwingend PostgreSQL, oder reicht SQLite?

SQLite (Standard ohne GITNESS_DATABASE_DRIVER) reicht für Einzelpersonen und sehr kleine Teams. Bei vielen parallelen Schreibzugriffen entstehen Sperrkonflikte. Für Teams empfiehlt sich PostgreSQL von Anfang an. Ein nachträglicher Wechsel erfordert eine manuelle Datenmigration.

Wie importiere ich bestehende Repositories von GitHub oder GitLab?

Die Web-UI bietet einen Import für einzelne Repositories und für ganze Projekte (z. B. GitLab-Gruppen oder GitHub-Organisationen). Code-History, Branches und Tags werden übertragen.

Wie funktioniert der Update-Prozess?

Neue Versionsnummer in der compose.yaml eintragen, dann docker compose pull && docker compose up -d. Harness führt Datenbankmigrationen automatisch beim nächsten Start durch. Legen Sie vorher ein Backup an (Schritt 6), um im Fehlerfall zurückkehren zu können.

Kann ich Harness hinter einem Reverse Proxy mit HTTPS betreiben?

Ja. Sie stellen einen Reverse Proxy (Nginx, Caddy, Traefik) bereit, der Port 443 auf Port 3000 weiterleitet, und setzen HARNESS_URL_BASE=https://git.example.com in der .env. Für SSH-Git-Zugriff muss Port 3022 separat erreichbar sein. Anleitung für Caddy: Caddy als Reverse Proxy mit automatischem HTTPS.

Wie viele Ressourcen benötigt Harness im laufenden Betrieb?

Im Leerlauf ohne aktive Pipelines genügen 2 CPU-Kerne und 2 GB RAM. Sobald CI/CD-Pipelines laufen, starten die Steps als eigenständige Docker-Container direkt auf dem Host, deren Ressourcenbedarf sich zum Harness-Prozess selbst addiert. Für Teams mit mehreren gleichzeitigen Pipeline-Runs empfehlen sich 4 Kerne und 4 bis 8 GB RAM. GITNESS_CI_PARALLEL_WORKERS (Standard: 2) lässt sich passend zu den verfügbaren Kernen erhöhen.

Gibt es Telemetrie oder Cloud-Pflichtkomponenten?

Cloud-Pflichtkomponenten gibt es nicht, ein Harness-Konto ist nicht nötig. Standardmäßig sendet Harness Nutzungsstatistiken an stats.drone.ci; GITNESS_METRIC_ENABLED=false schaltet das ab.

Fazit

Harness Open Source ersetzt mit einem Docker-Stack Git-Server, CI-System und Artifact-Registry. Entscheidend sind GITNESS_URL_BASE, GITNESS_URL_CONTAINER und GITNESS_ENCRYPTER_SECRET sowie PostgreSQL für Teams. Die letzte stabile Version stammt vom August 2025; prüfen Sie vor dem Einsatz den Projektstand auf GitHub. Wer eine sichere Docker-Compose-Umgebung aufbauen möchte, findet weitere Hinweise zu Secrets-Handling und Healthchecks in der Anleitung Docker Compose absichern: Secrets, Healthchecks, Non-Root.

Weiterführende Anleitungen und Quellen

  1. Docker und Docker Compose auf Linux installieren: die Self-Hosting-Grundlage
  2. Caddy als Reverse Proxy mit automatischem HTTPS einrichten
  3. Docker Compose absichern: Secrets, Healthchecks, Non-Root und Read-Only
  4. 3-2-1-Backup-Strategie umsetzen mit Restic, USB-Disk und S3-Cloud
  5. Docker-Container automatisch aktualisieren: Diun, WUD und Renovate im Vergleich
  6. Gitea mit Docker: eigener Git-Server als GitHub-Alternative

Quellen: Harness Open Source auf GitHub (harness/harness): offizielle Codebasis, Dockerfile, Releases; Harness Developer Hub: Quick Start; Harness Developer Hub: Konfigurationsreferenz (Settings); Docker Hub: harness/harness.