How to Upgrade Gerrit 3.12.2 to 3.13.1 on Ubuntu 24.04

Introduction

In a previous post,

I showed how to install Gerrit 3.11.2 on Ubuntu 24.04 with:

  • Java 21
  • A dedicated gerrit system user
  • Embedded Jetty + H2 database
  • A systemd service

After that, I upgraded my lab instance offline to Gerrit 3.12.2 (not documented).

This post starts from a working Gerrit 3.12.2 instance and shows how to upgrade it to Gerrit 3.13.1 on the same server, using the offline upgrade method.

Key points for 3.12 → 3.13:

  • No schema change
  • No reindex needed
  • Single-node upgrade is basically:
    stop Gerrit → replace gerrit.war → update plugins → start Gerrit

Offline vs Zero-Downtime Upgrade

Gerrit 3.13 supports two upgrade paths.

Offline upgrade (what this post uses)

Use this for single-node Gerrit or when you can afford a short outage:

  • Stop Gerrit.
  • Download the new gerrit.war and move it to $GERRIT_SITE/bin.
  • Extract plugins from the new WAR and copy the ones you need into $GERRIT_SITE/plugins.
  • Start Gerrit again.

This is what I do in this post.

Zero-downtime upgrade (HA only)

If you run multiple Gerrit nodes in a high-availability setup:

  • Start with Gerrit 3.12 on all nodes, healthy, behind a load balancer.
  • Mark one node unhealthy so it stops receiving traffic.
  • Stop that node, update gerrit.war, plugins, and libs to 3.13.x, then start it.
  • Run smoke tests, mark the node healthy again, and let it catch up with missed events.
  • Repeat for the remaining nodes, one by one.

My lab is single-node, so I only use the offline path.


Lab Overview

At the start of this post my environment is:

  • Gerrit version: 3.12.2
  • Target version: 3.13.1
  • OS: Ubuntu 24.04
  • Java: OpenJDK 21 (openjdk-21-jdk)
  • Gerrit site path ($GERRIT_SITE): /srv/gerrit
  • System user: gerrit
  • Database: Embedded H2
  • Public URL: https://gerrit.maksonlee.com/
  • Auth: auth.type = OAUTH via Keycloak (https://keycloak.maksonlee.com, realm maksonlee.com)
  • Reverse proxy: HAProxy with TLS termination, forwarding HTTPS :443 → Gerrit on 127.0.0.1:8080

systemd unit:

# /etc/systemd/system/gerrit.service
[Unit]
Description=Gerrit Code Review
After=network.target

[Service]
Type=simple
LimitNOFILE=65536
User=gerrit
ExecStart=/usr/bin/java -jar /srv/gerrit/bin/gerrit.war daemon -d /srv/gerrit
RemainAfterExit=yes
Restart=on-failure
OOMScoreAdjust=-1000

[Install]
WantedBy=multi-user.target

Key parts of gerrit.config:

# /srv/gerrit/etc/gerrit.config
[gerrit]
    basePath = git
    canonicalWebUrl = https://gerrit.maksonlee.com/

[container]
    user = gerrit
    javaHome = /usr/lib/jvm/java-21-openjdk-amd64

[index]
    type = lucene

[auth]
    type = OAUTH
    userNameCaseInsensitive = true
    gitBasicAuthPolicy = HTTP

[httpd]
    listenUrl = proxy-https://127.0.0.1:8080/

[sshd]
    listenAddress = *:29418

[cache]
    directory = cache

[plugins]
    allowRemoteAdmin = true

[plugin "gerrit-oauth-provider-keycloak-oauth"]
    client-id = gerrit
    root-url = https://keycloak.maksonlee.com
    realm = maksonlee.com

My plugins directory before upgrade looks like:

checks-jenkins.jar            # external (Jenkins Checks integration)
codemirror-editor.jar         # core
delete-project.jar            # core
download-commands.jar         # core
events-log.jar                # external (Gerrit-CI plugin)
gitiles.jar                   # core
oauth.jar                     # external (gerrit-oauth)
plugin-manager.jar            # core
reflog-recorder-1.0.0.jar     # external/custom
replication.jar               # core

If your 3.12.2 instance is similar, you can follow the same steps.


  1. Confirm You’re on 3.12.2

Check the current version:

sudo -u gerrit java -jar /srv/gerrit/bin/gerrit.war version

You should see:

gerrit version 3.12.2

Also check the service status:

sudo systemctl status gerrit

If it’s active (running) and logs look normal, you’re ready.


  1. Stop Gerrit

Before touching anything under /srv/gerrit, stop the daemon.

sudo systemctl stop gerrit
sudo systemctl status gerrit

Make sure it is actually stopped (not running or activating) before continuing.


  1. Back Up Site + Meta Repos (Skip Project Repos)

I keep large codebases (like AOSP) inside /srv/gerrit/git, so a single full-site tarball would be huge.
For this upgrade, I split the backup into two tarballs:

  • One for the Gerrit site without any Git repos
  • One for the meta projects (All-Projects and All-Users)

This assumes you already have a normal backup or snapshot strategy for your actual project repos.

Tarball 1 – Site backup without any Git repositories

This captures config, db, plugins, caches, logs, etc., but excludes the whole git directory:

sudo tar czf /root/gerrit-3.12.2-site-nogit-$(date +%F).tar.gz \
  -C /srv/gerrit \
  --exclude=./git \
  .

No project repos are included in this tarball.

Tarball 2 – Meta projects only (All-Projects, All-Users)

Gerrit stores important metadata in two special repos under /srv/gerrit/git:

  • All-Projects.git – global configuration, access rules, project defaults
  • All-Users.git – per-user settings, preferences, and some account data

Back them up separately:

sudo tar czf /root/gerrit-3.12.2-meta-projects-$(date +%F).tar.gz \
  -C /srv/gerrit/git All-Projects.git All-Users.git

These two tarballs together give you:

  • Complete site state (configs, db, plugins, caches, etc.)
  • All NoteDb metadata (All-Projects and All-Users)
  • While leaving large project repos (like AOSP) to your existing backup/snapshot mechanism.

  1. Download Gerrit 3.13.1 and Replace gerrit.war

Switch to the gerrit user:

sudo su - gerrit
cd /srv/gerrit/bin

Rename the existing WAR so you can easily roll back:

mv gerrit.war gerrit-3.12.2.war

Download 3.13.1:

wget https://gerrit-releases.storage.googleapis.com/gerrit-3.13.1.war

Point gerrit.war to the new file:

ln -sf gerrit-3.13.1.war gerrit.war

Your /srv/gerrit/bin should now look like:

gerrit-3.12.2.war
gerrit-3.13.1.war
gerrit.war -> gerrit-3.13.1.war
gerrit.sh

(If you keep extra helper files here, they’ll also show up.)

Exit back to your normal user:

exit

  1. Update Only Existing Core Plugins from the New WAR

For 3.12 → 3.13, schema and index don’t change, but you should update the core plugins you’re already using so they match the Gerrit version.

Switch to gerrit again:

sudo su - gerrit
cd /srv/gerrit

Create a temporary directory and unpack the new WAR:

mkdir -p /srv/gerrit/tmp-war
cd /srv/gerrit/tmp-war
jar xf /srv/gerrit/bin/gerrit-3.13.1.war

Core plugins live under WEB-INF/plugins/.

To overwrite only the core plugins you already use

for p in codemirror-editor delete-project download-commands \
         gitiles plugin-manager replication; do
  if [ -f "/srv/gerrit/plugins/$p.jar" ]; then
    echo "Updating $p.jar"
    cp "WEB-INF/plugins/$p.jar" "/srv/gerrit/plugins/$p.jar"
  else
    echo "Skipping $p.jar (not installed)"
  fi
done

External plugins (e.g. Keycloak OAuth)

If you use external plugins, make sure you have versions built against Gerrit 3.13. Replace those JARs in /srv/gerrit/plugins/ if needed.

Clean up:

cd /srv/gerrit
rm -rf tmp-war
exit

  1. Start Gerrit and Verify the Upgrade

Start Gerrit again:

sudo systemctl start gerrit
sudo systemctl status gerrit

Watch logs to confirm a clean startup:

sudo journalctl -u gerrit -f

Quick HTTP check from the server:

curl -I http://127.0.0.1:8080

Then verify the version:

sudo -u gerrit java -jar /srv/gerrit/bin/gerrit.war version

You should now see:

gerrit version 3.13.1

At this point, the offline upgrade is complete.

Did this guide save you time?

Support this site

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top