Databases Azure

SQLite 3.53 on Ubuntu 24.04 on Azure User Guide

| Product: SQLite 3.53 on Ubuntu 24.04 LTS on Azure

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/local with sha256 verification at install time

  • sqlite3 command line shell at /usr/local/bin/sqlite3 with readline support for interactive querying and dot commands

  • Shared library /usr/local/lib/libsqlite3.so and static library /usr/local/lib/libsqlite3.a for application linking

  • Header files /usr/local/include/sqlite3.h and sqlite3ext.h for C and C++ development

  • pkg-config metadata at /usr/local/lib/pkgconfig/sqlite3.pc for build system integration

  • FTS5 full-text search, JSON1 functions, RTREE / GEOPOLY spatial, math functions, and loadable extensions all compiled in

  • sqlite-firstboot.service systemd oneshot that writes a per-VM build-info banner to /stage/scripts/sqlite-credentials.log on 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:

sqlite-firstboot.service is-active=active with the build-info banner showing SQLITE_VERSION=3.53.0 and library paths

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:

sqlite3 -version reports 3.53.0, pkg-config matches, library and header files listed under /usr/local

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.

sqlite3 interactive shell against ~/notes.sqlite showing .tables, .schema, and a SELECT with .headers on / .mode column

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.