SCM-Manager on Ubuntu 24.04 on Azure User Guide
Overview
This image runs SCM-Manager, the open source, self-hosted repository manager that hosts your Git, Mercurial and Subversion repositories behind a single web interface and REST API. It gives teams one place to create and browse repositories, review code, and manage users, groups and fine-grained permissions, with support for all three version control systems built in.
SCM-Manager is a Java application served by an embedded Jetty server. It runs behind nginx as a reverse proxy: the server listens on 127.0.0.1:8080 at the root context path and is reached through nginx on port 80 (and 443 once you add TLS). The application binds to the loopback interface only, so nginx is the single network entry point.
On the first boot of every deployed VM, a one-shot service generates a per-VM administrator password, seeds the administrator account with it, resolves the VM's address, and then opens the network port. The well-known upstream default login (scmadmin / scmadmin) is never shipped reachable: the per-VM password replaces it, the default is proven rejected, and nginx stays closed until first boot has seeded the secret. The login is written to /root/scm-manager-credentials.txt with mode 0600.
What is included:
- SCM-Manager 3.11 installed from the official upstream apt repository as the
scm-serverpackage, behind nginx on:80 - Built-in support for Git, Mercurial and Subversion repositories (the core plugins ship bundled)
- The application bound to loopback only, reverse-proxied by nginx, with forwarded-header handling for correct URLs
- A per-VM administrator password generated at first boot, in a root-only file, with the upstream default disabled
scm-server.serviceandnginx.serviceas systemd units, enabled and active- OpenJDK 17 as the system-managed Java runtime, fully patched with unattended security upgrades enabled
- 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 good starting point; scale up for larger teams or heavier repository workloads. NSG inbound: allow 22/tcp from your management network (SSH admin access) and 80/tcp (plus 443/tcp once you enable TLS) from the networks your users reach SCM-Manager on.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for SCM-Manager 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 then Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name scm-manager \
--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 scm-manager --port 80 --priority 1010
First boot initialisation takes under a minute after the VM reaches the Running state (the Java service warms up on first start).
Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4 - Confirm the services are running
systemctl is-active scm-server.service nginx.service
curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1/api/v2
Both units report active and the REST API index returns 200, confirming the full stack - nginx and the SCM-Manager server - is serving. The server listens on 127.0.0.1:8080 and nginx is the only process bound to the public :80.

Both services active, the REST API answering, and the server bound to loopback behind nginx.
Step 5 - Retrieve the administrator login
The administrator account is created uniquely on the first boot of your VM and its login written to a root-only file:
sudo cat /root/scm-manager-credentials.txt
You will see a plain text file containing the SCM-Manager URL, the administrator username (scmadmin) and the per-VM password. The upstream default password is not used: signing in with scmadmin / scmadmin is rejected.

The per-VM administrator login, the API rejecting unauthenticated requests and the upstream default, and the per-VM password authenticating.
Step 6 - First sign-in
Open a web browser and navigate to http://<vm-public-ip>/. SCM-Manager presents its sign-in page. Enter the username scmadmin and the password from /root/scm-manager-credentials.txt, then select Login.

The SCM-Manager sign-in, served on first boot with a per-VM administrator login.
After signing in you land on the repositories overview - the central list of every repository across your namespaces, with search and filtering, and a Create Repository action.

The repositories overview - the central list of Git, Mercurial and Subversion repositories.
Step 7 - Create a repository
Select Create Repository, choose the type (Git, Mercurial or Subversion), give it a namespace and name, optionally initialise it, and create. The repository opens on its own page with the sources, branches, code, commits, and the clone information.

Creating a repository - SCM-Manager supports Git, Mercurial and Subversion in the same interface.

A repository page - sources, branches, commits and the clone URL.
You can also create a repository from the command line through the REST API and list what exists:
sudo bash -c '
PASS=$(grep "^scm.admin.pass=" /root/scm-manager-credentials.txt | cut -d= -f2-)
curl -s -u "scmadmin:$PASS" -X POST "http://127.0.0.1/api/v2/repositories?initialize=true" \
-H "Content-Type: application/vnd.scmm-repository+json;v=2" \
-d "{\"name\":\"hello-world\",\"namespace\":\"scmadmin\",\"type\":\"git\",\"description\":\"Sample repository\"}" \
-w "HTTP %{http_code}\n"
'

Creating a Git repository and listing it back through the REST API.
Step 8 - Clone and push code
Clone a repository over HTTP (replace the placeholders), commit, and push back:
git clone http://scmadmin@<vm-public-ip>/repo/scmadmin/hello-world
cd hello-world
echo "# Hello World" > README.md
git add README.md && git commit -m "first commit"
git push origin main
You will be prompted for the scmadmin password from /root/scm-manager-credentials.txt. Mercurial and Subversion repositories are cloned the same way with hg clone and svn checkout against the same http://<vm-public-ip>/repo/<namespace>/<name> URL.
Step 9 - Confirm the runtime and use the API
dpkg-query -W -f='${Package} ${Version}\n' scm-server

The installed SCM-Manager package version and the SCM_HOME layout.
Every action in the web app is also available through the REST API at http://<vm-public-ip>/api/v2/. Requests authenticate with HTTP Basic auth (the scmadmin login) or with an API key you create under scmadmin -> Settings -> API Keys. The index at /api/v2 lists the available resources.
Enabling HTTPS
For any production deployment serve SCM-Manager over HTTPS so logins and Git operations cannot be intercepted. The image ships with nginx, which certbot can configure automatically. The following assumes you have a DNS record pointing your fully qualified domain name at the VM's public IP address, and that port 443 is open in the NSG:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d scm.your-domain.example \
--non-interactive --agree-tos -m you@your-domain.example \
--redirect
Because the server has forwardHeadersEnabled set and nginx passes the X-Forwarded-* headers, SCM-Manager builds correct links and clone URLs automatically once TLS is in front.
Backup and maintenance
SCM-Manager keeps all of its state - the repositories, users, groups, permissions and configuration - under the home directory /var/lib/scm. Back it up regularly:
cd /tmp
sudo systemctl stop scm-server.service
sudo tar czf /tmp/scm-backup-$(date +%F).tgz -C /var/lib/scm .
sudo systemctl start scm-server.service
ls -lh /tmp/scm-backup-$(date +%F).tgz
Move the archive off the VM (for example to an Azure storage account), or take an Azure disk snapshot of the OS disk while the service is stopped. To upgrade SCM-Manager, run sudo apt-get update && sudo apt-get install --only-upgrade scm-server and restart the service; keep the OS patched with sudo apt update && sudo apt upgrade. See https://scm-manager.org/docs/.
Scaling and operations
- Put the web tier behind Azure Application Gateway or a load balancer if you need high availability
- Move
/var/lib/scmonto a dedicated Azure data disk and snapshot it independently for larger repository sets - Add plugins from the built-in plugin catalog (pull requests, code review, mirroring, authentication backends) under Administration -> Plugins
Each of these is documented in the official SCM-Manager documentation at https://scm-manager.org/docs/.
Support
cloudimg provides 24/7/365 expert technical support for this image. Guaranteed response within 24 hours, one hour average for critical issues. Contact support@cloudimg.co.uk.
For general SCM-Manager questions consult the documentation at https://scm-manager.org/docs/. SCM-Manager is licensed under the GNU Affero General Public License v3.0; the unmodified upstream package is shipped on this image. SCM-Manager is a trademark of its respective owner; use here is nominative and does not imply affiliation or endorsement. All product and company names are trademarks or registered trademarks of their respective holders.