Ss
Databases Azure

SQL Server 2022 Express on Ubuntu 22.04 LTS — Azure

| Product: SQL Server 2022 Express

SQL Server 2022 Express on Ubuntu 22.04 LTS

Microsoft SQL Server 2022 Express is the free entry-level edition of SQL Server — the full T-SQL engine, capped at 1 CPU socket (4 cores), 1.4 GB RAM, and 10 GB per database. Use it for development, learning, small production workloads, and evaluating SQL Server features before upgrading to a paid edition.

Edition limits: 1 socket / 4 cores · 1.4 GB RAM · 10 GB max database size
License: Free for commercial use — no product key or SPLA agreement required
SQL Server version: 2022 (RTM-CU24-GDR) 16.0.4250.1


1. Deploy the VM

In the Azure portal, launch the SQL Server 2022 Express on Ubuntu 22.04 LTS by cloudimg image from Azure Marketplace.

Recommended VM size: Standard_D2s_v3 (2 vCPU / 8 GB RAM). Express caps memory at 1.4 GB regardless of VM size — D2s_v3 gives comfortable headroom for the OS and any co-located services.

Networking: Open inbound port 1433 (SQL Server TDS) in your NSG. Restrict the source to trusted IP ranges — avoid opening 1433 to the public internet.

After the VM starts, connect via SSH:

ssh azureuser@<your-vm-public-ip>

2. Retrieve the credentials

On first boot, a systemd service generates a unique SA password and a secondary cloudimg login, then writes them to a credentials file:

sudo cat /stage/scripts/mssql-credentials.log

Example output:

# SQL Server 2022 Express Edition — Per-VM Credentials
# Generated: Fri Apr 24 22:35:01 UTC 2026
#
# Express Edition is free for commercial use within the edition limits:
#   1 CPU socket / 4 cores  |  1.4 GB RAM  |  10 GB max database size
# No license key required.
#
SA_USER=sa
SA_PASSWORD=Az<generated>
CLOUDIMG_USER=cloudimg
CLOUDIMG_PASSWORD=Cl<generated>
CLOUDIMG_DATABASE=cloudimg

Save the SA_PASSWORD value — you will use it for the initial connection.


3. Verify the service

sudo systemctl status mssql-server --no-pager

The service should show active (running). If it is not yet running (first-boot may still be completing), wait 30 seconds and retry.

Check that port 1433 is listening:

ss -tlnp | grep 1433

mssql-server.service active (running) with TCP 1433 bound on all interfaces


4. Connect with sqlcmd from the VM

sqlcmd (version 18) is pre-installed. Read your SA password and verify the SQL Server version:

SA_PASS=$(sudo grep '^SA_PASSWORD=' /stage/scripts/mssql-credentials.log | cut -d= -f2-)
/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "${SA_PASS}" -C -Q "SELECT @@VERSION" -h -1 -W

Output:

Microsoft SQL Server 2022 (RTM-CU24-GDR) (KB5083252) - 16.0.4250.1 (X64)
    Mar 13 2026 00:15:17
    Copyright (C) 2022 Microsoft Corporation
    Express Edition (64-bit) on Linux (Ubuntu 22.04.5 LTS) <X64>

Confirm the edition:

SA_PASS=$(sudo grep '^SA_PASSWORD=' /stage/scripts/mssql-credentials.log | cut -d= -f2-)
/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "${SA_PASS}" -C -Q "SELECT SERVERPROPERTY('Edition')" -h -1 -W

Per-VM SA + cloudimg credentials at /stage/scripts/mssql-credentials.log; SERVERPROPERTY('Edition') confirms Express Edition (64-bit)

@@VERSION reports Microsoft SQL Server 2022 Express Edition on Linux (Ubuntu 22.04); cloudimg user CREATE/INSERT/SELECT round-trip on cloudimg database returns cloudimg-ok


5. Connect from your workstation

sqlcmd on Linux/macOS (install from aka.ms/get-sqlcmd):

sqlcmd -S <your-vm-public-ip>,1433 -U sa -P '<SA_PASSWORD>' -C

Azure Data Studio — download from aka.ms/azuredatastudio. Create a new connection with:

  • Server: <your-vm-public-ip>,1433
  • Authentication: SQL Login
  • Username: sa
  • Password: <SA_PASSWORD>
  • Trust server certificate: enabled

SSMS on Windows — use the same connection string. Express supports all SQL Server Management Studio features for a database of this size.


6. Create a database and table

Connect to the instance and run:

-- Create a database
CREATE DATABASE myapp;
GO

-- Use it
USE myapp;
GO

-- Create a table
CREATE TABLE customers (
    id          INT IDENTITY(1,1) PRIMARY KEY,
    name        NVARCHAR(100) NOT NULL,
    email       NVARCHAR(255) UNIQUE,
    created_at  DATETIME2 DEFAULT SYSDATETIME()
);
GO

-- Insert a row
INSERT INTO customers (name, email) VALUES (N'Alice', N'alice@example.com');
GO

-- Query
SELECT * FROM customers;
GO

Express limit reminder: Each database is capped at 10 GB. When a database approaches the limit, SQL Server logs error 1105 and rejects inserts that would exceed it.

Express Edition limits: 1 socket / 4 cores, 1.4 GB buffer pool, 10 GB max database; sys.dm_os_sys_info confirms the engine sees the build VM's 4 GB but caps at 1410 MB. Apply Standard or Enterprise key with mssql-conf setpid for more capacity.


7. Create an application login

Avoid using sa for day-to-day application access. Create a least-privilege login:

-- Create login
CREATE LOGIN appuser WITH PASSWORD = 'StrongP@ssw0rd!';
GO

-- Grant access to your database
USE myapp;
CREATE USER appuser FOR LOGIN appuser;
ALTER ROLE db_datareader ADD MEMBER appuser;
ALTER ROLE db_datawriter ADD MEMBER appuser;
GO

8. Configure TLS encryption

By default the server accepts unencrypted connections. Enable forced encryption:

1. Generate a self-signed certificate (or use a CA-signed cert):

sudo openssl req -x509 -nodes -newkey rsa:2048 -days 3650 \
  -keyout /etc/ssl/private/mssql.key \
  -out /etc/ssl/certs/mssql.pem \
  -subj "/CN=$(hostname -f)"
sudo chown mssql:mssql /etc/ssl/private/mssql.key /etc/ssl/certs/mssql.pem
sudo chmod 600 /etc/ssl/private/mssql.key

2. Configure SQL Server to use the certificate:

sudo /opt/mssql/bin/mssql-conf set network.tlscert /etc/ssl/certs/mssql.pem
sudo /opt/mssql/bin/mssql-conf set network.tlskey /etc/ssl/private/mssql.key
sudo /opt/mssql/bin/mssql-conf set network.forceencryption 1
sudo systemctl restart mssql-server

After restart, clients must connect with TLS. Remove -C (trust self-signed) and add -N (encrypt) once you have a CA-signed cert.


9. Back up a database

SQL Server Express supports the full BACKUP DATABASE syntax. Create the backup directory and run a backup:

sudo mkdir -p /var/opt/mssql/backups
sudo chown mssql:mssql /var/opt/mssql/backups

From sqlcmd:

BACKUP DATABASE myapp
TO DISK = '/var/opt/mssql/backups/myapp.bak'
WITH FORMAT, COMPRESSION, STATS = 10;
GO

Schedule regular backups with a cron job or Azure Backup.


10. Security hardening

Rotate the SA password:

ALTER LOGIN [sa] WITH PASSWORD = 'NewStr0ng!Pass';
GO

Disable the SA login once you have app logins:

ALTER LOGIN [sa] DISABLE;
GO

NSG rules: Restrict port 1433 to specific source IP ranges. Never expose it to 0.0.0.0/0.

Check current logins:

SA_PASS=$(sudo grep '^SA_PASSWORD=' /stage/scripts/mssql-credentials.log | cut -d= -f2-)
/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "${SA_PASS}" -C \
  -Q "SELECT name, is_disabled FROM sys.server_principals WHERE type='S'" -h -1 -W

Useful commands

Check service status:

sudo systemctl status mssql-server --no-pager

View the SQL Server error log:

sudo tail -50 /var/opt/mssql/log/errorlog

Check the memory configuration:

sudo /opt/mssql/bin/mssql-conf get memory memorylimitmb 2>/dev/null; echo "memory check done"

Restart SQL Server:

sudo systemctl restart mssql-server

Credentials file reference

File Contents
/stage/scripts/mssql-credentials.log SA password and cloudimg login credentials (mode 600)

The cloudimg database and login are created by firstboot and can be used for initial application testing. Create application-specific logins as described in section 7.