RisingWave on Ubuntu 24.04 on Azure User Guide
Overview
RisingWave is a Postgres-compatible streaming database. It speaks the PostgreSQL wire protocol on port 4566, so any psql client or PostgreSQL driver can run streaming SQL against it: sources, materialized views over streams, and continuous queries whose results are kept incrementally up to date. The cloudimg image installs RisingWave 3.0.0 (the official self-contained risingwave binary from RisingWave Labs) and runs it in standalone single-node mode, where one process hosts the meta, compute, frontend and compactor components. State and metadata are stored on a dedicated Azure data disk, and a unique password is rotated into the image on first boot.
What is included:
- RisingWave 3.0.0 (the single all-in-one
risingwavebinary) from the official GitHub release - Standalone single-node mode (
risingwave single-node): meta, compute, frontend and compactor in one process - A unique per-VM password generated on first boot (no shared default credential)
- Standalone state and metadata on a dedicated 40 GiB Azure data disk at
/var/lib/risingwave - The PostgreSQL wire protocol bound to loopback (
127.0.0.1:4566) with password authentication - 24/7 cloudimg support
This is a streaming-database product: the PostgreSQL wire protocol listens on 127.0.0.1:4566 only. The port is not opened to the internet - connect locally on the VM or over an SSH tunnel.
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B4ms (4 vCPU / 16 GiB RAM) is a good starting point. NSG inbound: allow 22/tcp from your management network. No inbound application ports are needed because RisingWave is reached over the SSH tunnel.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for RisingWave 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) only. Then Review + create -> Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name risingwave \
--image <marketplace-image-urn> \
--size Standard_B4ms \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4 - Confirm RisingWave is installed and running
risingwave --version
systemctl is-active risingwave.service risingwave-firstboot.service
ss -tln | grep -E ":4566|:5691"
You should see RisingWave 3.0.0, both services active, and the Postgres wire bound to loopback on 4566:
risingwave 3.0.0 (ef12f3adbc)
active
active
LISTEN 0 1024 0.0.0.0:5691 0.0.0.0:*
LISTEN 0 1024 127.0.0.1:4566 0.0.0.0:*
127.0.0.1:4566 is the PostgreSQL wire protocol - the data plane and authentication - and is bound to loopback only. 5691 is the read-only meta dashboard; it carries no data and is not opened on the Azure NSG by default.

Step 5 - Retrieve your per-VM password
Each VM generates its own unique RisingWave password on first boot and writes it to a root-only credentials file:
sudo cat /root/risingwave-credentials.txt
The file contains RISINGWAVE_PASSWORD, the connection details and the SSH-tunnel instructions. Store the password in your secrets manager. In the commands below, <RISINGWAVE_PASSWORD> stands for the value of RISINGWAVE_PASSWORD.
Step 6 - Run streaming SQL with psql
RisingWave is Postgres-compatible, so you connect with the standard psql client. The example below creates a table, defines a materialized view that aggregates over it, inserts rows, and reads the incrementally-maintained result. The default database is dev and the default user is root.
PGPASSWORD=<RISINGWAVE_PASSWORD> psql -h 127.0.0.1 -p 4566 -U root -d dev <<'SQL'
CREATE TABLE sales (region varchar, amount int);
CREATE MATERIALIZED VIEW sales_by_region AS
SELECT region, sum(amount) AS total FROM sales GROUP BY region;
INSERT INTO sales VALUES ('emea', 100), ('emea', 250), ('amer', 400);
FLUSH;
SELECT * FROM sales_by_region ORDER BY region;
SQL
CREATE_TABLE
CREATE_MATERIALIZED_VIEW
INSERT 0 3
FLUSH
region | total
--------+-------
amer | 400
emea | 350
(2 rows)
The sales_by_region materialized view is kept up to date automatically as new rows arrive in sales - this is the core of streaming SQL.

Step 7 - Confirm persistence on the dedicated data disk
RisingWave's standalone state and metadata live on the dedicated Azure data disk at /var/lib/risingwave, so streams, tables and materialized views survive restarts and the volume is independently resizable. Confirm the materialized view, the mount, and the meta dashboard health:
PGPASSWORD=<RISINGWAVE_PASSWORD> psql -h 127.0.0.1 -p 4566 -U root -d dev \
-c "SELECT name FROM rw_catalog.rw_materialized_views;"
findmnt /var/lib/risingwave
du -sh /var/lib/risingwave/state
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:5691/
name
-----------------
sales_by_region
(1 row)
TARGET SOURCE FSTYPE OPTIONS
/var/lib/risingwave /dev/sdc ext4 rw,relatime
672K /var/lib/risingwave/state
200
The mount on /dev/sdc confirms state is on the dedicated data disk, and the 200 confirms the meta dashboard is serving locally.

Step 8 - Verify the authentication wall
The per-VM password is enforced on the root user: the correct password is accepted, and a wrong password is rejected. Confirm the correct password authenticates:
PGPASSWORD=<RISINGWAVE_PASSWORD> psql -h 127.0.0.1 -p 4566 -U root -d dev \
-c "SELECT current_user, version();"
current_user | version
--------------+----------------------------------------------------------
root | PostgreSQL 13.14.0-RisingWave-3.0.0 (ef12f3adbcb6...)
(1 row)
To see the rejection for yourself, try connecting with a wrong password - for example PGPASSWORD=wrongpw psql -h 127.0.0.1 -p 4566 -U root -d dev -c 'SELECT 1'. RisingWave responds with FATAL: Invalid password, proving the datastore is never open without the credential.

Step 9 - Connect remotely over an SSH tunnel
RisingWave's PostgreSQL wire protocol listens on 127.0.0.1:4566 only and is not exposed publicly - this is the secure default. To reach it from your workstation, open an SSH tunnel and point a local psql client at localhost:4566:
# On your workstation:
ssh -L 4566:127.0.0.1:4566 azureuser@<vm-public-ip>
# In another terminal, with a local psql:
PGPASSWORD=<RISINGWAVE_PASSWORD> psql -h 127.0.0.1 -p 4566 -U root -d dev -c "SELECT 1;"
For production remote access without a tunnel, bind RisingWave to a private NIC and front it with TLS, or open 4566 in your own NSG restricted to known source ranges. Never expose 4566 to the internet without transport encryption and source restrictions.
Maintenance
- Persistence: standalone state and metadata live on the dedicated data disk at
/var/lib/risingwave, so your streams and materialized views survive reboots and the volume is independently resizable. - Password: the per-VM password is rotated into the
rootuser on first boot. To change it, runALTER USER root WITH PASSWORD '<new>';over psql and update your secrets manager. - Service: RisingWave runs as
risingwave.serviceunder a dedicatedrisingwavesystem user. Restart withsudo systemctl restart risingwave.service. - Security patches: unattended-upgrades remains enabled so the OS continues to receive security updates automatically.
- Compatibility: RisingWave speaks the PostgreSQL wire protocol - existing Postgres clients, drivers and tooling connect to
4566unchanged.
Support
cloudimg provides 24/7 expert support for this image. Contact support@cloudimg.co.uk.
RisingWave is a trademark of RisingWave Labs. This image is provided by cloudimg and is not affiliated with or endorsed by RisingWave Labs. RisingWave is licensed under the Apache License 2.0.