Developer Tools Azure

Harness Open Source on Ubuntu 24.04 on Azure User Guide

| Product: Harness Open Source on Ubuntu 24.04 LTS on Azure

Overview

Harness Open Source, formerly Gitness and built by the team behind Drone, is an all in one self hosted software delivery platform. It brings together Git repository hosting, pull requests and code review, CI and CD pipelines, and a built in artifact registry inside a single web application backed by an embedded database, so a team can host code and ship it without stitching together several separate services. The cloudimg image installs Docker CE from the official Docker repository and runs the official Harness image as a container (managed by Docker with a restart policy), pinned by its @sha256 digest. The web UI and Git over HTTP are served on the loopback connector 127.0.0.1:3000 behind an nginx reverse proxy on port 80, the built in Harness SSH server handles Git over SSH on port 3022, and the container mounts the host Docker socket so pipeline steps run as containers on the instance. Because Harness makes the first account that registers an administrator, this image seeds the admin with a unique password generated on the first boot of every VM and switches off open self registration, so no default credential works and no attacker can register the first account and seize the server. Backed by 24/7 cloudimg support.

What is included:

  • Harness Open Source running as a container managed by Docker, the official image pinned by @sha256 digest
  • Docker CE preinstalled from the official Docker apt repository, with the socket mounted so pipeline steps run as containers
  • The Harness web UI and Git over HTTP on :80, fronted by nginx; Git over SSH on :3022
  • An embedded SQLite database, so there is no separate database server to run
  • A unique administrator password generated on first boot and recorded in a root only file
  • Open self registration switched off, so no second account can be created from the sign in page
  • A database created fresh per instance with no baked users, tokens or secrets
  • docker.service + nginx.service as systemd units, enabled and active
  • An unauthenticated /healthz endpoint for Azure Load Balancer health probes
  • 24/7 cloudimg support

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a comfortable starting point for the core git hosting, web UI and registry. NSG inbound: allow 22/tcp from your management network, 80/tcp for the web UI and Git over HTTP, and 3022/tcp for Git over SSH. Harness serves plain HTTP on port 80; for production, terminate TLS in front of it with your own domain and consider adding 443/tcp (see Maintenance).

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Harness Open Source by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTP (80). Then Review + create -> Create. After deployment, open ports 80, 3022 (and optionally 443) on the network security group.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name harness \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard

az vm open-port --resource-group <your-rg> --name harness --port 80 --priority 1010
az vm open-port --resource-group <your-rg> --name harness --port 3022 --priority 1020

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

systemctl is-active docker.service nginx.service
docker ps --filter name=harness --format 'table {{.Names}}\t{{.Status}}'

Both systemd units report active, and Docker shows the harness container Up. Docker manages the Harness service (the web UI and Git over HTTP bound to the loopback connector 127.0.0.1:3000, and Git over SSH on 3022), and nginx fronts it on port 80. The container mounts the host Docker socket so CI and CD pipeline steps run as containers.

docker.service and nginx.service active, the harness container up, the Docker socket and the persistent data directory mounted, and the listeners on nginx port 80, Harness 3000 on loopback and the docker gateway, and Git over SSH on 3022

Step 5 - Retrieve your administrator credentials

Harness makes the first account that registers an administrator, so this image pre-seeds that admin with a unique password generated on the first boot of your VM and written to a root only file:

sudo cat /root/harness-credentials.txt

This file contains HARNESS_URL, HARNESS_USERNAME (which is admin) and HARNESS_PASSWORD. Store the password somewhere safe. The official Harness image is pinned by its @sha256 digest, so every instance runs the exact same verified build.

The pinned Harness image digest and the per-VM credentials file with the generated administrator password and URL, password masked

Step 6 - Confirm there is no default credential and no open sign up

nginx serves an unauthenticated health endpoint for load balancers:

curl -s http://localhost/healthz

It returns ok. Now confirm the security posture. The admin signs in with the per instance password, the well known admin / admin default is rejected, and public self registration is disabled:

curl -s -o /dev/null -w 'admin + per-VM password: %{http_code}\n' -X POST 'http://127.0.0.1/api/v1/login?include_cookie=false' -H 'Content-Type: application/json' -d '{"login_identifier":"admin","password":"<HARNESS_PASSWORD>"}'
curl -s -o /dev/null -w 'admin / admin (default): %{http_code}\n' -X POST 'http://127.0.0.1/api/v1/login?include_cookie=false' -H 'Content-Type: application/json' -d '{"login_identifier":"admin","password":"admin"}'
curl -s -o /dev/null -w 'public self-registration: %{http_code}\n' -X POST 'http://127.0.0.1/api/v1/register?include_cookie=false' -H 'Content-Type: application/json' -d '{"uid":"attacker","email":"a@b.c","display_name":"a","password":"Sup3rSecret1"}'

The per instance password returns 200 (authenticated), the default admin / admin returns 404 (Harness deliberately hides whether the user exists on a bad password), and the public register endpoint returns 403 with User sign-up is disabled. So no default or blank credential works and no one can register the first account and seize the server.

The security round trip showing the admin with the per-VM password authenticating with HTTP 200, the default admin password rejected with HTTP 404, and public self-registration blocked with HTTP 403

Step 7 - Sign in to the web UI

Browse to http://<vm-public-ip>/. Harness shows its sign in page. Enter the user id admin and the password from Step 5, then Sign In. Open self registration is disabled, so the sign in page is the only way in and only your seeded admin can authenticate.

The Harness Open Source sign in page with the Email or User ID and Password fields and the Sign In button

Step 8 - Browse your repositories

After signing in, select a project (Harness groups repositories, pipelines and secrets into projects, also called spaces). Inside a project the Repositories page lists every repository with its description and last update, alongside the Artifact Registries, Gitspaces, Secrets, Members and Settings sections in the left rail.

The Harness repositories list inside a project, showing three private repositories with descriptions and last updated times, and the New Repository button

Step 9 - Create a repository

Choose New Repository. Give it a name and an optional description, pick a default branch, optionally add a licence, a .gitignore and a README, then Create Repository. Your new repository is ready to clone and push to immediately.

The Create a repository dialog with fields for name, description, default branch, licence, gitignore and an add a README file option

Step 10 - Push code over HTTPS or SSH

Each repository exposes a clone URL over HTTP (through nginx on port 80) and over the Harness SSH server (port 3022). Clone, commit and push as usual, authenticating with your admin credentials or a personal access token you create under your profile:

# Over HTTPS (through nginx on port 80)
git clone http://<vm-public-ip>/git/<space>/<repo>.git

# Over SSH (the Harness built-in SSH server on port 3022; add your SSH key to your Harness profile first)
git clone ssh://git@<vm-public-ip>:3022/<space>/<repo>.git

cd <repo>
git add .
git commit -m "First commit"
git push origin main

Step 11 - Open a pull request

Push a feature branch, then open a pull request to propose merging it into your default branch. The pull request view shows the commits and changes, whether the branch merges cleanly, review requirements, and a conversation timeline, with a Squash and merge action when it is ready.

A Harness pull request titled Document getting started, showing the open status, the Conversation, Commits, Changes and Checks tabs, a mergeable status with no conflicts, and the reviewers and labels panel

Step 12 - Run CI and CD pipelines

Harness runs pipeline steps as Docker containers on this instance through the host Docker socket, which the Harness container has mounted:

docker inspect harness --format '{{range .Mounts}}{{.Source}} -> {{.Destination}};{{end}}' | tr ';' '\n' | grep docker.sock

You see /var/run/docker.sock -> /var/run/docker.sock. Define a pipeline in a repository (Harness stores pipeline definitions as code), and its steps execute in containers on this VM, so you get CI and CD next to your Git hosting with nothing else to install.

Maintenance

  • Admin password: the administrator password is generated on first boot and stored in /root/harness-credentials.txt. To change it, sign in and use the web UI (your profile, then Password). A password you set in the UI persists across reboots.
  • Data: all repositories, pull requests, pipeline definitions, registry blobs and the embedded SQLite database live under /var/lib/harness on the instance disk; back that path up to preserve your data.
  • Upgrades: Harness runs as the harness container from the official image pinned by digest. To upgrade an already running VM, pull the new tag with sudo docker pull harness/harness:<new-tag>, then recreate the container with the same -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/harness:/data binding and the environment file at /etc/cloudimg/harness.env.
  • TLS: Harness serves plain HTTP on port 80; front it with TLS (for example certbot with your own domain) before production use.
  • Security patches: unattended-upgrades remains enabled so the OS continues to receive security updates automatically.
  • License: Harness Open Source is Apache 2.0 licensed. This image ships the open source project; the cloudimg charge covers packaging, security patching, image maintenance and support.

Support

cloudimg provides 24/7 expert support for this image. Contact support@cloudimg.co.uk.