SQL Server 2022 Express on Ubuntu 22.04 LTS — Azure
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

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


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.

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.