SQLite 3.53 on Ubuntu 24.04 on Azure User Guide
Overview
This guide covers the deployment and use of SQLite 3.53 on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. SQLite is the world's most widely deployed embedded SQL engine — a single file, no daemon, no admin password, just a library and a CLI shell.
The image ships SQLite 3.53.0 built from upstream source with all modern compile options enabled: FTS3/4/5 full-text search, JSON1 functions and JSON path syntax, RTREE and GEOPOLY spatial virtual tables, math functions, the loadable-extensions API, column metadata, DBSTAT, and STMT. The library, CLI, headers, and pkg-config metadata are installed under /usr/local. PATH ordering puts /usr/local/bin/sqlite3 ahead of any system sqlite3 so the latest 3.53.0 is what sqlite3 resolves to on the customer's shell.
What is included:
-
SQLite 3.53.0 source build from sqlite.org installed to
/usr/localwith sha256 verification at install time -
sqlite3command line shell at/usr/local/bin/sqlite3with readline support for interactive querying and dot commands -
Shared library
/usr/local/lib/libsqlite3.soand static library/usr/local/lib/libsqlite3.afor application linking -
Header files
/usr/local/include/sqlite3.handsqlite3ext.hfor C and C++ development -
pkg-config metadata at
/usr/local/lib/pkgconfig/sqlite3.pcfor build system integration -
FTS5 full-text search, JSON1 functions, RTREE / GEOPOLY spatial, math functions, and loadable extensions all compiled in
-
sqlite-firstboot.servicesystemd oneshot that writes a per-VM build-info banner to/stage/scripts/sqlite-credentials.logon first boot -
Ubuntu 24.04 LTS base with latest security patches applied at build time
-
Azure Linux Agent for seamless cloud integration and SSH key injection
-
24/7 cloudimg support with guaranteed 24 hour response SLA
Prerequisites
-
An active Azure subscription
-
A subscription to the SQLite 3.53 on Ubuntu 24.04 listing on Azure Marketplace
-
An SSH public key for VM authentication
-
A virtual network and subnet in the target region
Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) for typical embedded application backends, prototyping, and dev workflows. SQLite is extremely efficient — scale up only for workloads that operate on multi-gigabyte database files or need high concurrent reader throughput.
Step 1: Deploy from the Azure Portal
Navigate to Marketplace in the Azure Portal, search for SQLite 3.53, select the cloudimg publisher entry, and click Create.
On the Networking tab attach a network security group that allows inbound TCP 22 from your management IP range. SQLite has no daemon and no listening ports — TCP 22 (SSH) is the only port that needs to be reachable from the internet (or wherever you administer the VM from).
Click Review + create, wait for validation, then Create. Deployment takes around two minutes.
Step 2: Deploy from the Azure CLI
RG="sqlite-prod"
LOCATION="eastus"
VM_NAME="sqlite-01"
ADMIN_USER="azureuser"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/sqlite-3-53-ubuntu-24-04/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az network vnet create \
--resource-group "$RG" \
--name sqlite-vnet --address-prefix 10.96.0.0/16 \
--subnet-name sqlite-subnet --subnet-prefix 10.96.1.0/24
az network nsg create --resource-group "$RG" --name sqlite-nsg
az network nsg rule create \
--resource-group "$RG" --nsg-name sqlite-nsg \
--name allow-ssh --priority 100 \
--source-address-prefixes "<your-mgmt-cidr>" \
--destination-port-ranges 22 --access Allow --protocol Tcp
az vm create \
--resource-group "$RG" --name "$VM_NAME" \
--image "$GALLERY_IMAGE_ID" \
--size Standard_B2s --storage-sku StandardSSD_LRS \
--admin-username "$ADMIN_USER" --ssh-key-values "$SSH_KEY" \
--vnet-name sqlite-vnet --subnet sqlite-subnet --nsg sqlite-nsg \
--public-ip-sku Standard
Step 3: Connect via SSH
ssh azureuser@<vm-ip>
sqlite-firstboot.service will already have run on first boot, written the build-info banner, and disabled itself.
Step 4: Verify the Build-Info Banner and Sentinel
Confirm the firstboot sentinel exists:
sudo test -f /var/lib/cloudimg/sqlite-firstboot.done && echo FIRSTBOOT_DONE
Expected: FIRSTBOOT_DONE.
Read the build-info banner:
sudo cat /stage/scripts/sqlite-credentials.log
The banner includes SQLITE_VERSION=3.53.0, the binary, library, and header paths, plus a quickstart snippet:

Step 5: Verify SQLite 3.53.0 on PATH
sqlite3 -version
Expected: a single line beginning 3.53.0 followed by the build date and source ID.
which sqlite3
Expected: /usr/local/bin/sqlite3.
pkg-config --modversion sqlite3
Expected: 3.53.0.
ls -la /usr/local/lib/libsqlite3.* /usr/local/include/sqlite3*.h
Expected: libsqlite3.so (symlink), libsqlite3.so.0 (symlink), libsqlite3.so.0.8.6 (real file), libsqlite3.a (static), and the two header files:

Step 6: Open a Database and Run a Quick CREATE / INSERT / SELECT
sqlite3 ~/notes.sqlite <<'SQL'
CREATE TABLE notes(id INTEGER PRIMARY KEY, body TEXT NOT NULL, created TEXT DEFAULT CURRENT_TIMESTAMP);
INSERT INTO notes(body) VALUES ('first note from cloudimg'), ('second note'), ('third note');
SELECT id, body, created FROM notes ORDER BY id;
SQL
Expected: three rows printed with their auto-assigned ids and timestamps.
You can also enter the interactive shell:
sqlite3 ~/notes.sqlite
Inside the shell, useful dot commands include .tables, .schema notes, .headers on, .mode column, and .quit.

Step 7: Try FTS5 Full-Text Search
sqlite3 :memory: <<'SQL'
CREATE VIRTUAL TABLE doc USING fts5(body);
INSERT INTO doc VALUES ('the quick brown fox jumps over the lazy dog');
INSERT INTO doc VALUES ('a stitch in time saves nine');
INSERT INTO doc VALUES ('the early bird catches the worm');
SELECT body FROM doc WHERE body MATCH 'fox OR bird';
SQL
Expected: two rows — the fox sentence and the bird sentence.
Step 8: Try JSON1 Functions
sqlite3 :memory: <<'SQL'
SELECT json_extract('{"product":"sqlite","version":"3.53","modules":["fts5","rtree","json1"]}', '$.modules[1]');
SELECT json_object('a', 1, 'b', json_array(2, 3, 4));
SQL
Expected: rtree on the first row and a JSON object string on the second.
Step 9: Try Math Functions
sqlite3 :memory: <<'SQL'
SELECT round(pi(), 4);
SELECT round(pow(2, 10));
SELECT round(sqrt(2), 6);
SQL
Expected: 3.1416, 1024.0, and 1.414214.
Step 10: Compile a C Program Against libsqlite3
sudo apt-get install -y --no-install-recommends gcc
cat > /tmp/sqlite_demo.c <<'C'
#include <stdio.h>
#include <sqlite3.h>
int main(void) {
sqlite3 *db; sqlite3_stmt *stmt;
sqlite3_open(":memory:", &db);
sqlite3_prepare_v2(db, "SELECT sqlite_version();", -1, &stmt, NULL);
sqlite3_step(stmt);
printf("linked sqlite version: %s\n", sqlite3_column_text(stmt, 0));
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
C
gcc /tmp/sqlite_demo.c $(pkg-config --cflags --libs sqlite3) -o /tmp/sqlite_demo
LD_LIBRARY_PATH=/usr/local/lib /tmp/sqlite_demo
Expected: linked sqlite version: 3.53.0.
Notes on Concurrency and Backups
SQLite handles many concurrent readers but serialises writers via a per-database lock. For higher write throughput, enable WAL mode after creating a database:
sqlite3 ~/notes.sqlite "PRAGMA journal_mode = WAL;"
Expected output: wal. WAL mode allows readers and a single writer to operate concurrently without blocking each other for most workloads.
For backups, the safest approach is the online .backup command, which works while readers and writers are active:
sqlite3 ~/notes.sqlite ".backup ~/notes.sqlite.bak"
ls -la ~/notes.sqlite ~/notes.sqlite.bak
For point-in-time copies of static databases, plain cp is also safe.
Where Things Live
| Path | Purpose |
|---|---|
/usr/local/bin/sqlite3 |
SQLite 3.53.0 command line shell (in PATH ahead of any system sqlite3) |
/usr/local/lib/libsqlite3.so |
Shared library (symlink to libsqlite3.so.0.8.6) |
/usr/local/lib/libsqlite3.a |
Static library |
/usr/local/include/sqlite3.h |
Public C API header |
/usr/local/include/sqlite3ext.h |
Loadable extensions API header |
/usr/local/lib/pkgconfig/sqlite3.pc |
pkg-config metadata |
/stage/scripts/sqlite-credentials.log |
Build-info banner (mode 0600 root:root) |
/var/lib/cloudimg/sqlite-firstboot.done |
First-boot sentinel |
/var/log/sqlite-firstboot.log |
First-boot service log |
Stock Ubuntu sqlite3 Coexistence
Ubuntu 24.04 noble main ships an older sqlite3 package (3.45.x). It is not preinstalled on the cloudimg image. If a piece of system tooling needs the stock 3.45.x binary at /usr/bin/sqlite3, install it alongside the upstream build:
sudo apt-get install -y sqlite3
which -a sqlite3
PATH still resolves sqlite3 to /usr/local/bin/sqlite3 first, so the upstream 3.53.0 build remains the default. Reference the stock binary explicitly as /usr/bin/sqlite3 if you need it.
Support
For technical support, contact support@cloudimg.co.uk. We provide 24/7 expert support with a guaranteed 24 hour response for all requests and a one hour average for critical issues. Visit www.cloudimg.co.uk for documentation and additional resources.