Infinispan on Ubuntu 24.04 on Azure User Guide
Overview
Infinispan is an open source in-memory data grid: a key/value store that keeps your data in memory so it can be read at memory speed, with the option to write it through to disk so it survives a restart. It is used as a cache in front of a slower database, as a session store for a fleet of application servers, and as the system of record for data that has to be fast.
Applications talk to it over Hot Rod, Infinispan's own binary protocol, for which official clients are published for Java, Go, JavaScript, C++, .NET and Python. Anything that prefers HTTP can use the REST API instead, on the same port. A web console is included for creating caches, browsing entries and watching statistics without writing any code.
The cloudimg image delivers Infinispan Server 16.2.3 on Ubuntu 24.04 as a single node, served over TLS, with an administrator account generated on the first boot of your VM. Backed by 24/7 cloudimg support.
What is included:
- Infinispan Server 16.2.3, the unmodified upstream distribution at
/opt/infinispan-server-16.2.3, run by systemd as the unprivilegedinfinispanuser - The single port 11222, serving TLS with a certificate generated for your VM, carrying the REST API, the web console and the binary Hot Rod protocol together
- The web console at
/console/, for creating caches and browsing entries in a browser - A durable cache template named
persistent: caches you create from it write through to disk and reload their contents when the server restarts - OpenJDK 25, the runtime Infinispan 16.2's server modules require, installed from the Ubuntu archive so it receives security updates like any other package
- No user is baked into the image. The Infinispan distribution ships no account at all, and every data and configuration path answers
401until one exists. Your administrator, your TLS certificate and your keystore password are all generated on your VM's first boot and written to a root-only file - A JVM heap sized for the instance rather than for a laptop, and no swap
- The
infinispansystemd service, enabled and active
Infinispan is a trademark of the Commonhaus Foundation. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them. This image packages the unmodified open source software, which is distributed under the Apache License 2.0.

Prerequisites
An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2ms (2 vCPU, 8 GiB RAM) is the recommended size: the JVM heap in this image is set to 2 GiB, which does not fit honestly alongside the operating system on a 4 GiB instance. Choose a larger size if you intend to hold a large working set in memory. Network security group inbound rules: 22/tcp from your management network, and 11222/tcp from wherever your applications and administrators connect.
Step 1: Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Infinispan Data Grid 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). Then select Review + create and Create. Open 11222 afterwards, as shown in the next step.
Step 2: Deploy from the Azure CLI
Accept the image terms once per subscription, then deploy:
az vm image terms accept --urn cloudimg:infinispan-ubuntu-24-04:default:latest
az group create --name infinispan-rg --location eastus
az vm create \
--resource-group infinispan-rg \
--name infinispan-vm \
--image cloudimg:infinispan-ubuntu-24-04:default:latest \
--size Standard_B2ms \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
az vm open-port --resource-group infinispan-rg --name infinispan-vm --port 11222 --priority 1010
Step 3: Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4: Confirm Infinispan is running
The service is infinispan. It is started by systemd only after first boot has finished provisioning your VM, so on a brand new instance it may take a few seconds longer than the other services to become active.
systemctl is-active infinispan
Expected output:
active
The liveness probe is deliberately open — it is what an Azure load balancer or a monitoring agent would call, and it returns nothing but a health word:
curl -sk https://localhost:11222/rest/v2/container/health/status
Expected output:
HEALTHY
The runtime is OpenJDK 25, which is what Infinispan 16.2's server modules are compiled for:
java -version 2>&1 | head -1
Expected output:
openjdk version "25.0.4" 2026-07-21
Step 5: Check what the network can reach
Infinispan multiplexes several protocols onto one port. The REST API, the web console and the binary Hot Rod protocol all arrive on 11222, and the server picks the protocol per connection.
sudo ss -Hltn | awk '{print $4}' | sort -u
Expected output:
0.0.0.0:11222
0.0.0.0:22
127.0.0.53%lo:53
127.0.0.54:53
[::]:22
Only 22 and 11222 are reachable from outside the VM; the two 127.0.0.x:53 entries are the local DNS stub resolver.
There are no cluster ports here, and that is deliberate. Infinispan's stock configuration starts a JGroups cluster transport, which binds TCP 7800, TCP 57800 and a UDP multicast discovery socket. This image is a single node, so its configuration declares no transport at all — those sockets are never created, rather than being created and then firewalled off. The image ships a check that proves it:
sudo /usr/local/sbin/infinispan-port-check.sh
Expected output:
off-box TCP exactly [22 11222]
JGroups 7800/57800/udp-46655 not bound on any interface — no cluster transport exists
INFINISPAN_PORTS_OK
Step 6: Retrieve the first-boot administrator
The Infinispan distribution ships no user at all — this is not a cloudimg choice, it is how upstream ships it, and it means there is no vendor default in this image for anyone to guess. Your VM created its own administrator on first boot and wrote it to a file only root can read.
sudo ls -l /root/infinispan-credentials.txt
Expected output:
-rw------- 1 root root 764 Sep 21 01:07 /root/infinispan-credentials.txt
The exact byte count differs between instances — the file embeds your VM's own address — but the mode is always 0600 root:root.
Read it, with the password masked:
sudo sed 's/^\(INFINISPAN_ADMIN_PASSWORD=\).*/\1<hidden>/' /root/infinispan-credentials.txt
Expected output:
# Infinispan Data Grid on Ubuntu 24.04 LTS by cloudimg
# Generated on this VM's first boot — unique to this VM. Keep this file secret.
...
INFINISPAN_ADMIN_USER=ispnadmin
INFINISPAN_ADMIN_PASSWORD=<hidden>
INFINISPAN_HOST=<INFINISPAN_HOST>
INFINISPAN_URL=https://<INFINISPAN_HOST>:11222
INFINISPAN_CONSOLE_URL=https://<INFINISPAN_HOST>:11222/console/
INFINISPAN_TLS_CERT=/var/lib/infinispan/conf/server.crt
The realm file the server reads holds only salted hashes, never the password itself:
sudo head -3 /var/lib/infinispan/conf/users.properties
Expected output:
#$REALM_NAME=default$
#$ALGORITHM=encrypted$

To use the credential in the commands below without typing it, read it into shell variables. Do this in each new shell — the variables do not survive a logout:
U=$(sudo grep '^INFINISPAN_ADMIN_USER=' /root/infinispan-credentials.txt | cut -d= -f2-)
P=$(sudo grep '^INFINISPAN_ADMIN_PASSWORD=' /root/infinispan-credentials.txt | cut -d= -f2-)
echo "administrator: $U"
Expected output:
administrator: ispnadmin
Step 7: Confirm the door refuses everything but your credential
Every path that touches data or configuration is closed without your credential. Check the whole set at once:
sudo /usr/local/sbin/infinispan-verify-auth.sh
Expected output:
door: no credential 401 with a Digest challenge; wrong password 401; unknown user 401
door: this VM's credential accepted over DIGEST-SHA-256 and BASIC (200)
TLS: a plaintext request to 11222 is REJECTED
anonymous surface is exactly the two health probes, the version banner and the console bundle
every data and configuration path is 401
INFINISPAN_AUTH_OK
Each of those checks is itself tested against a known-bad input, so a check that could never fail cannot quietly pass:
sudo /usr/local/sbin/infinispan-gate-selftest.sh
Expected output:
INFINISPAN_GATE_SELFTEST_OK
You can see the refusal yourself. Without a credential:
curl -sk -o /dev/null -w '%{http_code}\n' -X GET https://localhost:11222/rest/v2/caches
Expected output:
401
And with it:
U=$(sudo grep '^INFINISPAN_ADMIN_USER=' /root/infinispan-credentials.txt | cut -d= -f2-)
P=$(sudo grep '^INFINISPAN_ADMIN_PASSWORD=' /root/infinispan-credentials.txt | cut -d= -f2-)
curl -sk --digest -u "$U:$P" https://localhost:11222/rest/v2/caches
Expected output:
["___protobuf_metadata","___script_cache"]
Those two entries are Infinispan's own internal caches. Your own caches will appear alongside them.

Step 8: Open the web console
Browse to your VM's console:
https://<INFINISPAN_HOST>:11222/console/
Your browser will warn about the certificate, because first boot generated a self-signed one for your VM's address. Accept it for now — Step 13 replaces it with your own. Sign in with the administrator from Step 6.
The console opens on Data container, which lists every cache on the node with its type, health and features.

Step 9: Create a durable cache
A cache that loses everything on restart is fine for a pure read-through cache and useless for a session store. This image ships a cache template called persistent: every cache you create from it writes through to disk and reloads on start.
Create one and put three entries in it:
U=$(sudo grep '^INFINISPAN_ADMIN_USER=' /root/infinispan-credentials.txt | cut -d= -f2-)
P=$(sudo grep '^INFINISPAN_ADMIN_PASSWORD=' /root/infinispan-credentials.txt | cut -d= -f2-)
curl -sk --digest -u "$U:$P" -X POST 'https://localhost:11222/rest/v2/caches/sessions?template=persistent'
for k in alice bob carol; do
curl -sk --digest -u "$U:$P" -X PUT -H 'Content-Type: text/plain' \
--data-binary "session-for-$k" "https://localhost:11222/rest/v2/caches/sessions/$k"
done
curl -sk --digest -u "$U:$P" 'https://localhost:11222/rest/v2/caches/sessions?action=size'
Expected output:
3
Read one back:
U=$(sudo grep '^INFINISPAN_ADMIN_USER=' /root/infinispan-credentials.txt | cut -d= -f2-)
P=$(sudo grep '^INFINISPAN_ADMIN_PASSWORD=' /root/infinispan-credentials.txt | cut -d= -f2-)
curl -sk --digest -u "$U:$P" https://localhost:11222/rest/v2/caches/sessions/alice
Expected output:
{"_type":"string","_value":"session-for-alice"}
The entries are on disk as well as in memory:
ls /var/lib/infinispan/data/sessions/
Expected output:
data
index
sessions.lck
You can do all of this in the console instead — Create a cache, choose the persistent template, then use the cache's Entries tab to add and browse entries.

Step 10: Prove the data survives a restart
This is the difference the persistent template makes. Restart the server and read the same key back:
sudo systemctl restart infinispan </dev/null
sleep 20
U=$(sudo grep '^INFINISPAN_ADMIN_USER=' /root/infinispan-credentials.txt | cut -d= -f2-)
P=$(sudo grep '^INFINISPAN_ADMIN_PASSWORD=' /root/infinispan-credentials.txt | cut -d= -f2-)
curl -sk --digest -u "$U:$P" https://localhost:11222/rest/v2/caches/sessions/alice
Expected output:
{"_type":"string","_value":"session-for-alice"}
A cache created without the template is memory-only and comes back empty — which is the correct behaviour for a read-through cache, and the reason the template exists for everything else.
The cache's Configuration tab in the console shows exactly what it inherited:


Step 11: Watch the grid
The console's Global Statistics view shows cluster-wide figures for every cache — entries held, memory used, hit and miss rates — and Cluster Membership shows the nodes. This image is a single node, so membership shows one member.

Metrics are also exposed in Prometheus format on the same port, behind the same credential:
U=$(sudo grep '^INFINISPAN_ADMIN_USER=' /root/infinispan-credentials.txt | cut -d= -f2-)
P=$(sudo grep '^INFINISPAN_ADMIN_PASSWORD=' /root/infinispan-credentials.txt | cut -d= -f2-)
curl -sk --digest -u "$U:$P" https://localhost:11222/metrics | head -3
Expected output (the exact metric names vary by release):
# HELP base_classloader_loadedClasses_count Displays the number of classes that are currently loaded in the Java virtual machine.
# TYPE base_classloader_loadedClasses_count gauge
base_classloader_loadedClasses_count 12345.0
Step 12: Connect from your application
Applications should use Hot Rod, Infinispan's binary protocol. It reaches the same port 11222 and the same credential. A Java client is configured like this:
ConfigurationBuilder cfg = new ConfigurationBuilder();
cfg.addServer().host("<INFINISPAN_HOST>").port(11222)
.security().authentication()
.username("<INFINISPAN_ADMIN_USER>")
.password("<INFINISPAN_ADMIN_PASSWORD>")
.realm("default")
.saslMechanism("SCRAM-SHA-512")
.ssl()
.sniHostName("<INFINISPAN_HOST>")
.trustStorePath("/path/to/server.crt");
RemoteCacheManager cacheManager = new RemoteCacheManager(cfg.build());
RemoteCache<String, String> cache = cacheManager.getCache("sessions");
cache.put("dave", "session-for-dave");
Copy your VM's certificate to the client machine so it can verify the connection:
sudo cp /var/lib/infinispan/conf/server.crt /tmp/infinispan.crt && sudo chmod 0644 /tmp/infinispan.crt && ls -l /tmp/infinispan.crt
Then fetch it with scp azureuser@<INFINISPAN_HOST>:/tmp/infinispan.crt . from your workstation. Clients for Go, JavaScript, C++, .NET and Python are documented on the Infinispan clients page.
Anything that cannot speak Hot Rod can use the REST API shown in Step 9 — it is a first-class interface, not a fallback.
Step 13: Use your own certificate and domain
First boot generated a self-signed certificate naming your VM's address. To use a certificate from your own authority, replace the keystore the server reads. Point a DNS record at your VM, obtain a certificate for that name, then build a PKCS12 keystore from it and restart:
# On a VM whose DNS name is grid.your-domain.com, with fullchain.pem and privkey.pem
# obtained from your CA (certbot, your internal PKI, or a commercial issuer):
sudo openssl pkcs12 -export -inkey privkey.pem -in fullchain.pem -name server \
-out /var/lib/infinispan/conf/server.p12 -passout env:KSP
sudo systemctl restart infinispan </dev/null
The keystore password lives in /var/lib/infinispan/conf/infinispan.xml, which is readable only by root and the infinispan user. Set KSP to that value before running the command above, and keep it out of your shell history.
Step 14: Back up your caches
The cache stores and the persisted cache definitions both live under the server's data directory, so a consistent backup is a stopped-server copy of that directory:
sudo systemctl stop infinispan </dev/null && sudo tar -czf /var/backups/infinispan-data.tar.gz -C /var/lib/infinispan data && sudo systemctl start infinispan </dev/null && ls -l /var/backups/infinispan-data.tar.gz
For a running backup, or to move data between environments, use the server's own backup endpoint, which produces a single archive containing caches, templates and counters:
U=$(sudo grep '^INFINISPAN_ADMIN_USER=' /root/infinispan-credentials.txt | cut -d= -f2-)
P=$(sudo grep '^INFINISPAN_ADMIN_PASSWORD=' /root/infinispan-credentials.txt | cut -d= -f2-)
curl -sk --digest -u "$U:$P" -o /dev/null -w 'backup request: %{http_code}\n' \
-X POST -H 'Content-Type: application/json' -d '{}' \
https://localhost:11222/rest/v2/container/backups/nightly
Expected output:
backup request: 202
Step 15: Keep the image patched
The operating system and the JVM receive security updates through Ubuntu's unattended-upgrades, which is enabled in this image. To apply updates immediately:
sudo apt-get update && sudo apt-get install --only-upgrade openjdk-25-jre-headless
Upgrading Infinispan itself means unpacking a newer distribution alongside the current one and repointing the service. The configuration and data live outside the distribution directory, under /var/lib/infinispan, so they are not disturbed by the swap. Contact cloudimg support before a major version change.
Step 16: Rotate the administrator password
The account is an ordinary properties-realm user, so the server's own CLI changes it. The realm files are re-read while the server runs, so no restart is needed:
sudo ISPN_PASSWORD='<new-password>' /opt/infinispan/bin/cli.sh user password ispnadmin \
-f /var/lib/infinispan/conf/users.properties -w /var/lib/infinispan/conf/groups.properties
Use user password, not user create — create refuses an account that already exists rather than replacing it. Update /root/infinispan-credentials.txt afterwards so the file and the live account agree. Never pass the password as a normal argument: ISPN_PASSWORD exists precisely so it does not land in your shell history or in the process table.
Troubleshooting
The service will not start. Look at the journal first: sudo journalctl -u infinispan -n 80 --no-pager. A configuration error is reported as a parse exception naming the line and column. The service also refuses to start until first boot has finished, so on a brand new VM check sudo systemctl status infinispan-firstboot as well.
Every request returns 401. The credential in /root/infinispan-credentials.txt is the one the server accepts. If you have rotated the password, make sure you updated both the realm file and the credentials file — they are separate. sudo /usr/local/sbin/infinispan-verify-auth.sh tells you which half disagrees.
A browser or client reports a certificate error. First boot issues a self-signed certificate naming your VM's address. Either trust /var/lib/infinispan/conf/server.crt on the client, or follow Step 13 to install your own.
A cache is empty after a restart. It was created without the persistent template and is therefore memory-only. Check its features in the console: a durable cache shows Persistent.
Connections time out from outside the VM. Confirm the network security group allows 11222/tcp from your source, and remember that plain HTTP is refused on that port — the endpoint is HTTPS only.
The server runs out of memory. The JVM is configured to exit rather than thrash, because this image carries no swap by design. Either reduce what you are holding in memory, add an eviction policy to the cache, or move to a larger instance and raise the heap in /etc/systemd/system/infinispan.service.
Support
cloudimg provides 24/7 support for this image: deployment, upgrades, TLS certificates and custom domains, client integration, cache design and capacity planning. Contact us through the cloudimg website.