Home / Docs / DCA Hardened CI Server — for Jenkins® / Configuration
Jenkins® LTS 2.580 with 70 pinned, checksum-verified plugins, the web UI on loopback, and the setup wizard kept: the unlock password and keys are generated on each VM's first start.
On this page: Installed version · First-start credentials and the setup wizard · Unlock and log in · Plugins: the 70 pinned, and what is held back · Network access · Data and logs · Upgrades · Backup and restore
Jenkins® LTS 2.580.1 — the upstream jenkins.war, verified when the image was built (a pinned sha256 equal to the release's own .sha256 and to repo.jenkins-ci.org's, plus the Jenkins Project's GPG signature) and installed as /opt/jenkins/jenkins.war, with the version in /opt/jenkins/version.txt. It runs on Ubuntu's OpenJDK 21 as the jenkins user under jenkins.service (java -jar; not the pkg.jenkins.io package). Base OS: Ubuntu 24.04 LTS. Image built 2026-10-07; every build is gated on zero fixable HIGH or CRITICAL vulnerability findings across the OS, the WAR and every plugin.
cat /opt/jenkins/version.txt
curl -sI http://127.0.0.1:8080/login | grep -i '^x-jenkins:'The setup wizard is kept, not skipped, and nothing credential-like ships: JENKINS_HOME (/var/lib/jenkins) holds only the pinned plugin archives. On its first start on your VM, Jenkins itself generates the unlock password and its keys. jenkins-verify-firstboot.service then proves the unlock password signs in as admin, a wrong one gets 401 and anonymous access gets 403, and that the version and every pinned plugin are the ones this image ships.
| File | Owner / mode | Contents |
|---|---|---|
/var/lib/jenkins/secrets/initialAdminPassword | jenkins, not world-readable | The setup wizard's unlock password. Jenkins deletes it when the wizard completes |
/var/lib/jenkins/secrets/master.key | jenkins, not world-readable | Encrypts every credential Jenkins stores — unique to this VM; back it up with JENKINS_HOME, never share it |
/var/lib/jenkins/secret.key, /var/lib/jenkins/identity.key.enc | jenkins | This instance's secret and identity, also generated on first start |
gcloud compute ssh INSTANCE_NAME --zone ZONE --tunnel-through-iap. The deployment package enables OS Login, so IAM decides who can SSH in; reading the credential files needs sudo, which OS Login grants to principals with the OS Admin Login role (roles/compute.osAdminLogin). IAP TCP forwarding needs a firewall rule that allows 35.235.240.0/20 to tcp:22 on the VM's network — the deployment package does not create one.gcloud compute ssh INSTANCE_NAME --zone ZONE --tunnel-through-iap -- -L 8080:127.0.0.1:8080
sudo cat /var/lib/jenkins/secrets/initialAdminPasswordThe image ships 70 plugins in /var/lib/jenkins/plugins, pinned by name, version and sha256 in /opt/jenkins/plugins.lock: the setup wizard's own suggested set for 2.580.1 with its dependencies, minus the plugins held back below. The first-boot check confirmed every one is loaded and active at its pinned version.
Held back because, on 2026-10-07, libraries they bundle had fixable HIGH-severity findings and no fixed plugin release existed:
jackson2-api 2.22.2-445 — bundles jackson-core and jackson-databind 2.22.2, fixed upstream in 2.22.3. Everything that needs it is held back with it: Declarative Pipeline (workflow-aggregator and the pipeline-model-* plugins), gradle, github-branch-source, pipeline-graph-view and email-ext.ldap 825 — bundles spring-ldap-core 3.2.11, fixed in 3.3.8.Scripted Pipeline ships (workflow-job, workflow-cps, workflow-multibranch and the steps they need). The setup wizard still offers the held-back plugins: "Install suggested plugins" downloads them from the Jenkins update center, while "Select plugins to install" lets you leave them out. Installing them is your choice — weigh the findings above, and check the Plugin Manager for newer releases first. The lock file records what the image shipped; it does not stop you updating plugins later (Manage Jenkins → Plugins → Updates).
The 70 pinned plugins: ant, antisamy-markup-formatter, apache-httpcomponents-client-4-api, asm-api, bootstrap5-api, bouncycastle-api, branch-api, build-timeout, caffeine-api, checks-api, cloudbees-folder, commons-lang3-api, commons-text-api, credentials, credentials-binding, dark-theme, display-url-api, durable-task, echarts-api, eddsa-api, font-awesome-api, git, git-client, gson-api, instance-identity, ionicons-api, jackson-annotations2-api, jackson3-api, jakarta-activation-api, jakarta-mail-api, jquery3-api, json-path-api, junit, mailer, matrix-auth, matrix-project, mina-sshd-api-common, mina-sshd-api-core, pipeline-build-step, pipeline-github-lib, pipeline-groovy-lib, pipeline-input-step, pipeline-milestone-step, pipeline-stage-step, plain-credentials, plugin-util-api, prism-api, resource-disposer, scm-api, script-security, snakeyaml-engine-api, ssh-credentials, ssh-slaves, structs, theme-manager, timestamper, token-macro, trilead-api, variant, woodstox-core-api, workflow-api, workflow-basic-steps, workflow-cps, workflow-durable-task-step, workflow-job, workflow-multibranch, workflow-scm-step, workflow-step-api, workflow-support, ws-cleanup. On the VM: cat /opt/jenkins/plugins.lock.
| Port | Bound to | Deployment package |
|---|---|---|
| 8080 (web UI and API) | 127.0.0.1 — JENKINS_LISTEN_ADDRESS in /etc/jenkins/jenkins.env | tcp:8080 toggle, off by default |
| Inbound-agent TCP port | disabled | none |
| 22 (SSH) | all interfaces | no rule — your VPC's own firewall rules apply |
Jenkins serves plain HTTP. To give users on your network access:
127.0.0.1:8080 — so Jenkins itself stays on loopback. Then set Manage Jenkins → System → Jenkins URL to the HTTPS address.JENKINS_LISTEN_ADDRESS in /etc/jenkins/jenkins.env to the VM's internal IP (or 0.0.0.0, which keeps the tunnel working) and restart:# /etc/jenkins/jenkins.env
JENKINS_LISTEN_ADDRESS=0.0.0.0
sudo systemctl restart jenkinsDEPLOYMENT-tcp-8080, allowing tcp:8080 from those ranges to VMs tagged DEPLOYMENT-deployment (DEPLOYMENT is your deployment name; the VM is DEPLOYMENT-vm). Use the narrowest ranges that work — 0.0.0.0/0, which the field shows only as a format example, would publish the port through the VM's external IP. Already deployed without the toggle? Create the same rule yourself:gcloud compute firewall-rules create DEPLOYMENT-tcp-8080 \
--network NETWORK --direction INGRESS --allow tcp:8080 \
--source-ranges 10.10.0.0/24 --target-tags DEPLOYMENT-deploymentAgents: the SSH Build Agents plugin (ssh-slaves) ships, and SSH agents are connected from the controller outward, so they need no inbound port on the controller.
default network that still has its pre-created default-allow-internal rule (all ports from 10.128.0.0/9), every VM in that network can connect as soon as the service listens on the internal IP — toggle or not. And the deployment package gives the VM an ephemeral external IP by default (its External IP field), so a rule open to 0.0.0.0/0 would put the service on the internet. Put authentication in place first, then open the narrowest range that works.| What | Where |
|---|---|
| JENKINS_HOME | /var/lib/jenkins — jobs, builds, configuration, secrets and plugins |
| Unpacked WAR | /var/cache/jenkins/war |
| Service settings | /etc/jenkins/jenkins.env — JENKINS_LISTEN_ADDRESS, JENKINS_PORT, JAVA_OPTS, JENKINS_OPTS |
| Logs | the systemd journal — journalctl -u jenkins -f; also Manage Jenkins → System Log |
| Disk | The deployment package creates one boot disk (default 50 GB, balanced persistent disk) and no separate data disk, so the data above lives on the boot disk — size it for your data, or mount a persistent disk at the data path. |
/opt/jenkins/jenkins.war is owned by root and is not an apt package, so neither Jenkins' own updater (Jenkins runs as jenkins) nor unattended-upgrades (enabled, for Ubuntu's updates including OpenJDK 21) replaces it. Back up JENKINS_HOME, download the newer LTS jenkins.war with its .sha256 and .asc from get.jenkins.io, verify them, then:sudo install -m 0644 jenkins.war /opt/jenkins/jenkins.war
echo NEW_VERSION | sudo tee /opt/jenkins/version.txt
sudo systemctl restart jenkinsJENKINS_HOME across: stop jenkins on both VMs, copy /var/lib/jenkins (it carries secrets/master.key, without which stored credentials cannot be decrypted), sudo chown -R jenkins:jenkins /var/lib/jenkins, and start. Your plugins come with it, so update them afterwards.Stop jenkins and copy /var/lib/jenkins — keep secrets/ with it — or snapshot the boot disk. Restore by putting the directory back, owned by jenkins, before starting the service.
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/login → 200 — wire this into an uptime check or your monitoring agent.google-logging-enable=0, google-monitoring-enable=0), and the image pre-installs no monitoring agent. Install the Google Cloud Ops Agent if you want logs and metrics in Cloud Logging and Cloud Monitoring; nothing phones home by default.More: install · troubleshooting · security notes · support card. Questions: support@dcassociatesgroup.com — first response within 1 business day.
Jenkins® is a registered trademark of LF Charities Inc.