Jenkins LTS on Ubuntu 24.04 LTS on Azure User Guide
Overview
Jenkins is the industry-standard open-source automation server for CI/CD pipelines, build automation, and scheduled jobs. The cloudimg image runs Jenkins LTS 2.555.1 on Ubuntu 24.04 LTS with OpenJDK 21, fronted by nginx 1.24 on port 80 (X-Forwarded-* headers and websocket upgrade are pre-configured for the build console). Per-VM admin credentials are bootstrapped at first boot via a Groovy init script, so you skip the upstream initial-admin-password setup wizard entirely.
What is included:
- Jenkins LTS 2.555.1 from the official
pkg.jenkins.io/debian-stableAPT repo, signed with thejenkins.io-2026.key(valid through 2028-12-21) - OpenJDK 21 JRE headless plus
fontconfig,libharfbuzz0b, andfonts-dejavu-core(required by Jenkins's Jetty font subsystem on noble) jenkins.servicelistening on127.0.0.1:8080, with the upstream setup wizard disabled via-Djenkins.install.runSetupWizard=false- nginx 1.24 reverse proxy on
:80withX-Forwarded-*headers and websocket upgrade for/wsagents/,/cli, and/websocket /var/lib/jenkins/init.groovy.d/cloudimg-init.groovyprovisioning theadminuser from/etc/jenkins/admin-password.txton every Jenkins startjenkins-2-firstboot.servicerotating the admin password (openssl rand -hex 16) on first boot and writing/etc/cloudimg-credentials.txt(mode 0600 root:root)- 24/7 cloudimg support
Prerequisites
Active Azure subscription, SSH key, VNet plus subnet, NSG allowing TCP 22 (SSH) and TCP 80 (web UI). Standard_B2s (4 GB RAM) is suitable for small teams running a handful of pipelines. For larger workloads with concurrent builds, distributed agents, or heavy plugin usage, scale up to D4s_v5 or D8s_v5 and consider switching from H2 to a managed PostgreSQL backend for the Jenkins state.
Step 1: Deploy from Azure Marketplace
Search the Azure Marketplace for "cloudimg Jenkins LTS Ubuntu 24.04" and click Create. Pick the Standard_B2s size, choose your VNet plus subnet, and ensure the NSG attached to the VM allows inbound TCP 22 and TCP 80 from your trusted CIDR.
Step 2: SSH In
ssh azureuser@<vm-ip>
Step 3: Service Status
Confirm both services are active.
sudo systemctl status jenkins.service nginx.service --no-pager | head -20

Step 4: Read Per-VM Admin Credentials
The first-boot service rotates the Jenkins admin password and writes the cloudimg credentials file. Read it now.
sudo cat /etc/cloudimg-credentials.txt
Pick up JENKINS_URL, JENKINS_ADMIN_USER (always admin), and JENKINS_ADMIN_PASSWORD. Keep this terminal open while you log in.
Step 5: Open Jenkins in Your Browser
Browse to http://<vm-ip>/ (nginx forwards to Jenkins on 127.0.0.1:8080). The Jenkins sign-in page appears.
Step 6: Sign In
Enter admin plus the password from /etc/cloudimg-credentials.txt. The Jenkins dashboard loads — the upstream setup wizard is already complete (security realm, authorization strategy, and admin user are provisioned by cloudimg-init.groovy).

Step 7: Create Your First Job
Click New Item in the left sidebar. Type a name, pick a project type (the base image ships with Freestyle project out of the box; install the Pipeline plugin from Manage Jenkins → Plugins for declarative-pipeline support), and click OK to open the job configuration page.

Step 8: Configure Jenkins
Browse to Manage Jenkins in the left sidebar to access System Configuration, Plugins, Tools, Nodes, Credentials, and Security. Plugins can be installed without restarting from the Plugin Manager.

Step 9: API Round-Trip
Confirm the REST API is reachable with the same credentials.
PASS=$(sudo grep '^JENKINS_ADMIN_PASSWORD=' /etc/cloudimg-credentials.txt | cut -d= -f2-)
curl -sf -u "admin:${PASS}" http://127.0.0.1/api/json | head -c 200
A 200 response confirms admin auth via nginx → Jenkins is wired correctly. Use the same Basic auth from your CI scripts and external triggers.
Step 10: Production Hardening Checklist
Before exposing to the internet, work through these:
- TLS termination. Add a Let's Encrypt cert via
certbot --nginxand uncomment the HTTPS server block. SetJENKINS_URLto thehttps://form in Manage Jenkins → System so absolute URLs in emails are correct. - Restrict the admin user. Rotate the admin password (System → Manage Users → admin → Configure) and create per-user accounts under Manage Jenkins → Security.
- Authorization strategy. Switch from "Logged-in users can do anything" to Matrix-based or Role-based authorization for fine-grained per-job permissions.
- Plugin updates. Run Manage Jenkins → Plugins → Updates to apply security patches; subscribe to the Jenkins security advisory feed.
- Backup the JENKINS_HOME.
/var/lib/jenkinsholds all jobs, configs, and credentials — back it up to Azure Blob storage withazcopyon a schedule. - Distributed builds. Add Linux or Windows agents under Manage Jenkins → Nodes to offload builds from the controller.
Architecture
| Component | Path | Notes |
|---|---|---|
| Jenkins JAR | /usr/share/java/jenkins.war |
Started by jenkins.service |
JENKINS_HOME |
/var/lib/jenkins/ |
Job configs, build history, plugins, credentials |
| Jenkins systemd | /etc/systemd/system/jenkins.service.d/cloudimg-overrides.conf |
JENKINS_OPTS + JAVA_OPTS (setup wizard disabled, bind 127.0.0.1:8080) |
| Groovy init | /var/lib/jenkins/init.groovy.d/cloudimg-init.groovy |
Idempotent admin provisioning at every Jenkins start |
| Per-VM password | /etc/jenkins/admin-password.txt |
Mode 0640 root:jenkins; rotated by firstboot |
| Per-VM URL | /etc/jenkins/jenkins-url.txt |
Mode 0644 root:jenkins; consumed by JenkinsLocationConfiguration |
| nginx vhost | /etc/nginx/sites-available/jenkins |
Reverse proxy with X-Forwarded-* + websocket upgrade |
| Customer creds | /etc/cloudimg-credentials.txt |
Mode 0600 root:root; JENKINS_URL, admin user, admin password |
| Firstboot script | /usr/local/sbin/jenkins-2-firstboot.sh |
Rotates password, writes URL, restarts Jenkins, writes credentials file |
| Firstboot sentinel | /var/lib/cloudimg/jenkins-2-firstboot.done |
Created when firstboot completes |
Support
cloudimg provides 24/7 support for this image. Open a ticket at https://cloudimg.co.uk/support/ with your subscription ID, VM name, and a brief description of the issue. Common asks: scaling the controller, adding distributed agents, switching to PostgreSQL/MySQL state backend, integrating with Azure AD via the SAML or OpenID plugin.