SQL Server 2025 Express on AWS User Guide
Overview
This image runs Microsoft SQL Server 2025 Express Edition, the free, entry-level edition for small databases, prototypes and learning. SQL Server is the only workload on the image, so the platform stays lean, predictable and easy to reason about.
Express Edition is the free entry-level engine, ideal for small databases, prototypes, learning and lightweight applications.
This guide covers the Express delivery option. SQL Server 2025 is also offered in other editions on the same listing -- see the SQL Server 2025 on AWS hub to compare and choose.
SQL Server is installed from the official Microsoft APT repository for Ubuntu 24.04. The mssql-tools18 package and the sqlcmd command-line utility are preinstalled.
On the first boot of your instance a one-shot service generates a fresh SA password, sets it via mssql-conf, re-applies the Express edition, creates a dedicated cloudimg SQL login, removes the build-time memory cap and writes all credentials to /root/mssql-credentials.txt, a file that only the root user can read. No shared or default credentials ship in the image. SQL Server listens on port 1433 and starts on boot via systemd.
Express edition at a glance: A maximum database size of 10 GB, roughly 1.4 GB of buffer-pool memory, and 1 socket or 4 cores. Backup compression is not available on Express.
This is a headless image. SQL Server has no web interface; you administer it over SSH with the sqlcmd command-line tool and any compatible SQL Server client on port 1433, both covered below.
Prerequisites
Before you deploy this image you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network
- The AWS CLI (version 2) installed locally if you plan to deploy from the command line
Recommended instance type: t3.large or m5.large (Express is lightweight; larger types bring no benefit beyond its limits).
Step 1: Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for SQL Server 2025. Select the cloudimg listing and choose Select, then on the subscription summary pick the SQL Server 2025 Express on Ubuntu 24.04 delivery option and choose Continue.
Pick an instance type appropriate for your workload (see Prerequisites). Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that allows inbound port 22 from your management network. Add port 1433 to the security group if you want external clients to connect to SQL Server directly. Leave the root volume at the default size or larger.
Select Launch instance. First-boot initialisation, which generates the SA password and starts SQL Server, takes a minute or two after the instance state becomes Running and the status checks pass.
Step 2: Launch the Instance from the AWS CLI
The following block launches an instance from the cloudimg SQL Server 2025 Express Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing for the Express delivery option, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens inbound port 22 (and optionally 1433 for external SQL connections).
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.xlarge \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--metadata-options HttpTokens=required \
--block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":40,"VolumeType":"gp3"}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=mssql-01}]'
The command prints a JSON document on success. Note the instance ID, then retrieve its public address once it is running:
aws ec2 describe-instances \
--instance-ids <instance-id> \
--query "Reservations[].Instances[].PublicIpAddress" \
--output text
Step 3: Connect over SSH
Connect over SSH with the key pair you selected and the public IP address from step 2. This delivery option is built on Ubuntu 24.04, so the SSH login user is ubuntu:
ssh ubuntu@<your-instance-ip>
Wait until the instance has passed both EC2 status checks before connecting. The first-boot service runs before the SSH daemon is ready, so SQL Server is initialised by the time you can log in.
Step 4: Retrieve the Generated SA Password
The first-boot service generates a fresh SA password for this instance and writes it, with the connection details, to /root/mssql-credentials.txt. The file is readable only by the root user. Display it from your SSH session:
sudo cat /root/mssql-credentials.txt
The file looks like this, with unique passwords on your instance:
# SQL Server 2025 Express Edition -- Per-Instance Credentials
# Generated: Wed Jun 04 09:00:00 UTC 2026
# Instance IP: 3.86.159.217
#
SA_USER=SA
SA_PASSWORD=Az6b3036366161212d18!fec2e071
CLOUDIMG_USER=cloudimg
CLOUDIMG_PASSWORD=Cle3946a05c9368d3c62!3510bba3
CLOUDIMG_DATABASE=cloudimg
#
# Connect: sqlcmd -S 3.86.159.217 -U SA -P 'Az6b3036366161212d18!fec2e071' -C
Keep this file secure. It contains the SA password for the SQL Server instance. The cloudimg login has db_owner membership on the cloudimg database and is suitable for application connections.
Step 5: Connect to SQL Server with sqlcmd
The sqlcmd command-line utility is preinstalled at /opt/mssql-tools18/bin/sqlcmd. Connect to the local SQL Server instance using the SA password from the credentials file:
SA_PASS=$(sudo grep '^SA_PASSWORD=' /root/mssql-credentials.txt | cut -d= -f2-)
/opt/mssql-tools18/bin/sqlcmd -S 127.0.0.1 -U SA -P "${SA_PASS}" -C
The -C flag trusts the server certificate (the image uses a self-signed certificate). From the 1> prompt you can run T-SQL statements. Type GO to execute a batch and exit to quit.
To verify the SQL Server version and confirm the Express edition:
SA_PASS=$(sudo grep '^SA_PASSWORD=' /root/mssql-credentials.txt | cut -d= -f2-)
/opt/mssql-tools18/bin/sqlcmd -S 127.0.0.1 -U SA -P "${SA_PASS}" -C -Q "SELECT @@VERSION"
Output from this instance:
Microsoft SQL Server 2025 (RTM-CU5-GDR) (KB5095565) - 17.0.4050.1 (X64)
May 15 2026 12:06:45
Copyright (C) 2025 Microsoft Corporation
Express Edition (64-bit) on Linux (Ubuntu 24.04.4 LTS) <X64>
Licensing
SQL Server Express Edition is a free edition and requires no product key. It is fully licensed for production use within its edition limits (see Overview).
Step 6: Check the SQL Server Service
SQL Server runs as a systemd service. Check its status with:
sudo systemctl status mssql-server --no-pager
Expected output:
mssql-server.service - Microsoft SQL Server Database Engine
Loaded: loaded (/usr/lib/systemd/system/mssql-server.service; enabled; preset: enabled)
Active: active (running) since Wed 2026-06-04 09:00:35 UTC; 16s ago
Docs: https://docs.microsoft.com/en-us/sql/linux
Main PID: 6640 (sqlservr)
Tasks: 87
Memory: 503.9M (peak: 503.9M)
CPU: 8.057s
Manage the service with standard systemctl commands:
sudo systemctl stop mssql-server
sudo systemctl start mssql-server
sudo systemctl restart mssql-server
Step 7: Create a Database and Table
Connect to SQL Server and create a database with the following commands:
SA_PASS=$(sudo grep '^SA_PASSWORD=' /root/mssql-credentials.txt | cut -d= -f2-)
/opt/mssql-tools18/bin/sqlcmd -S 127.0.0.1 -U SA -P "${SA_PASS}" -C -Q "IF DB_ID('myapp') IS NULL CREATE DATABASE [myapp];"
/opt/mssql-tools18/bin/sqlcmd -S 127.0.0.1 -U SA -P "${SA_PASS}" -C -d myapp -Q "IF OBJECT_ID('customers') IS NULL CREATE TABLE customers (id INT IDENTITY PRIMARY KEY, name NVARCHAR(100), email NVARCHAR(200), created_at DATETIME2 DEFAULT GETDATE()); INSERT INTO customers (name, email) VALUES ('Alice Smith', 'alice@example.com'); INSERT INTO customers (name, email) VALUES ('Bob Jones', 'bob@example.com'); SELECT id, name, email, created_at FROM customers;"
Sample output:
id name email created_at
-- ----------- ------------------ --------------------------
1 Alice Smith alice@example.com 2026-06-04 09:05:00.0000000
2 Bob Jones bob@example.com 2026-06-04 09:05:00.1000000
(2 rows affected)
Express edition: backup compression is not supported. Omit
WITH ... COMPRESSIONfrom theBACKUPcommand (useWITH INITonly). Databases are also capped at 10 GB.
Step 8: Connect from a Remote Client
SQL Server listens on port 1433. To connect from a remote machine, add port 1433 to the instance security group inbound rules. Then connect using any SQL Server compatible client (SQL Server Management Studio, Azure Data Studio, DBeaver, or sqlcmd on another machine):
/opt/mssql-tools18/bin/sqlcmd -S <your-instance-ip>,1433 -U SA -P "<SA_PASSWORD>" -C
For production deployments, consider enabling SSL/TLS with a trusted certificate. See the Microsoft documentation on SQL Server on Linux encryption.
Step 9: Configuration with mssql-conf
The mssql-conf utility manages SQL Server configuration. View the current settings:
sudo /opt/mssql/bin/mssql-conf list
Set the maximum server memory (replace 8192 with your desired limit in MB):
sudo /opt/mssql/bin/mssql-conf set memory.memorylimitmb 8192
sudo systemctl restart mssql-server
The first-boot service removes the build-time memory cap automatically, so SQL Server starts with no explicit memory limit on your instance (within the edition's own buffer-pool ceiling). Set an explicit limit only if you need to share the host with other workloads.
Step 10: Backup and Restore
Create the backup directory and back up the cloudimg database to a local file:
sudo mkdir -p /var/opt/mssql/backup
sudo chown mssql:mssql /var/opt/mssql/backup
SA_PASS=$(sudo grep '^SA_PASSWORD=' /root/mssql-credentials.txt | cut -d= -f2-)
/opt/mssql-tools18/bin/sqlcmd -S 127.0.0.1 -U SA -P "${SA_PASS}" -C -Q \
"BACKUP DATABASE [cloudimg] TO DISK = N'/var/opt/mssql/backup/cloudimg.bak' WITH INIT;"
Restore from a backup file:
SA_PASS=$(sudo grep '^SA_PASSWORD=' /root/mssql-credentials.txt | cut -d= -f2-)
/opt/mssql-tools18/bin/sqlcmd -S 127.0.0.1 -U SA -P "${SA_PASS}" -C -Q \
"RESTORE DATABASE [cloudimg] FROM DISK = N'/var/opt/mssql/backup/cloudimg.bak' WITH REPLACE;"
Troubleshooting
SQL Server will not start. Check the SQL Server error log:
sudo cat /var/opt/mssql/log/errorlog | tail -50
Check the systemd journal:
sudo journalctl -u mssql-server -n 50 --no-pager
Port 1433 not reachable from the internet. Check the EC2 security group inbound rules for the instance. Port 1433 must be open from your client IP or CIDR range.
Permission denied reading credentials. The credentials file is owned by root with mode 600. Use sudo:
sudo cat /root/mssql-credentials.txt
First-boot did not run. Check the first-boot service log:
sudo journalctl -u mssql-firstboot -n 50 --no-pager
sudo cat /var/log/mssql-firstboot.log
cloudimg Support
This image is supported by cloudimg. For technical assistance with SQL Server deployment, configuration, performance tuning, high availability, query optimisation or database administration, contact support at support@cloudimg.co.uk.
Support is available 24 hours a day, 7 days a week.