Harness Open Source on Ubuntu 24.04 on Azure User Guide
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
@sha256digest - 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.serviceas systemd units, enabled and active- An unauthenticated
/healthzendpoint 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.

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.

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.

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.

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.

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.

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.

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/harnesson the instance disk; back that path up to preserve your data. - Upgrades: Harness runs as the
harnesscontainer from the official image pinned by digest. To upgrade an already running VM, pull the new tag withsudo 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:/databinding 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.