Setup SQL Server and Docker on a MacBook

Problem

Docker is a great way to play with SQL Server without the administrative overhead of managing an instance. I wanted to get started using my new MacBook Pro M1 for local development and testing, but quickly discovered there are no Docker images for SQL Server that support ARM64 just yet. Can I test SQL Server locally on this new hardware?

Solution

To get around the lack of ARM64 Docker images, I decided to use the Azure SQL Edge flavor of SQL Server. When I got it working, I thought I would share how I set this up (though note that this tip is equally relevant if you have an Intel Mac or, barring a few minor syntax differences, a Windows PC).

Using Azure SQL Edge probably sounds risky, and may imply I am building solutions only for sensors or IoT devices or that can only run in Microsoft’s cloud. In truth, it can run wherever I like, and supports all of the SQL Server features I actually use. The list of limitations is significant, but only slightly longer than the list of features not supported on Linux. Some of the notable missing features:

  • Active Directory (read: SQL authentication only)
  • Replication, mirroring, snapshots, Availability Groups, Failover Clustering
  • Filestream, Filetable, StretchDB, Service Broker, and Full-Text Search
  • In-Memory OLTP, Polybase, and language extensibility (e.g. Spark)
  • Distributed query, Distributed Transaction Coordinator, and linked servers
  • CLR (including HierarchyId, Geography/Geometry methods, and functions like TRY_PARSE and FORMAT)
  • Resource Governor, Buffer Pool Extension, persistent memory, and Hot-add CPU / memory

A more exhaustive list is available here: Supported features of Azure SQL Edge. If none of those features are deal-breakers and you’re still with me, let’s see how easy it is to set up.

Docker

We’ll need Docker first to get started – easiest is to install Docker Desktop. If we go there with a Mac, we’ll be offered these options; choose wisely, as they indicate the platform we’re using, not anything related to the containers we want to run:

Docker Desktop platform choices for Mac

There is a great guide to getting started here: Install Docker Desktop on Mac – guides are also available for Windows and Linux (e.g. Ubuntu). But for our purposes, we can jump right in by double-clicking docker.app (or docker.exe).

Next, we can open up a terminal/cmd window, and check that the service is running:

docker run hello-world

Part of the output should include:

Hello from Docker!
This message shows that your installation appears to be working correctly.

Azure SQL Edge

With Docker up and running, next we need to pull the most recent Azure SQL Edge container image:

docker pull mcr.microsoft.com/azure-sql-edge:latest

We can create the appropriate container with the following command (it is quite annoying that some of these parameter names are just slightly different from the ones for “regular” SQL Server):

docker run -d 
--name SQLEdge
-p 6666:1433
-e ACCEPT_EULA=1
-e MSSQL_SA_PASSWORD=3dg3Y0urB3ts
-e MSSQL_PID=Developer
mcr.microsoft.com/azure-sql-edge

A brief breakdown of the parameters:

We can run the following to make sure the container is up and running, and we should see SQLEdge in the list (and also how much space it is using):

Though we need to wait long enough (~10 seconds) to be sure (a) the container has had enough time to fully initialize and (b) it’s also had enough time to shut down due to a runtime or configuration error. If the container isn’t running after 10 seconds, it’s quite likely that it crashed. We can read the SQL Server errorlog directly, even if SQL Server isn’t running, using the following command (another reason it’s a good idea to give containers an intuitive name):

If the container crashed, the output should give us some hints about what happened, and hopefully they are easy to resolve.

We can validate SQL Server is running by using Azure Data Studio to connect and then running SELECT @@VERSION;

Restoring a real database

I like to use Stack Overflow and AdventureWorks databases for consistency. In this case, let’s use the “lightweight” AdventureWorks database to steer clear of any advanced functionality that might not be supported (and also to help keep the size within the magic 40GB threshold, which I talk about in this blog post). You can download the sample databases here: AdventureWorks sample databases (2019 direct link).

We can get this backup file into the container using Docker commands to create the folder and copy the .bak file (note that your source location may be different):

docker exec -it SQLEdge mkdir "/var/opt/mssql/backup"
docker cp ~/Downloads/AdventureWorksLT2019.bak SQLEdge:/var/opt/mssql/backup/

Then we can restore:

RESTORE DATABASE AdventureWorksLT2019 
FROM DISK = '/var/opt/mssql/backup/AdventureWorksLT2019.bak'
WITH REPLACE, RECOVERY,
MOVE 'AdventureWorksLT2012_Data' TO '/var/opt/mssql/data/aw2019.mdf',
MOVE 'AdventureWorksLT2012_Log' TO '/var/opt/mssql/data/aw2019.ldf';

Output should be something like this:

Processed 840 pages for database 'AdventureWorksLT2019', file 'AdventureWorksLT2012_Data' on file 1.
Processed 2 pages for database 'AdventureWorksLT2019', file 'AdventureWorksLT2012_Log' on file 1.
Converting database 'AdventureWorksLT2019' from version 904 to the current version 921.
Database 'AdventureWorksLT2019' running the upgrade step from version 904 to version 905. … Database 'AdventureWorksLT2019' running the upgrade step from version 920 to version 921.
RESTORE DATABASE successfully processed 842 pages in 0.029 seconds (226.697 MB/sec).

Now we can run queries against that database, e.g.:

SELECT COUNT(*) FROM SalesLT.vProductAndDescription;
----
1764

Removing the container

If we are done testing or wish to wipe it clean and start over, we can issue stop and rm commands:

docker stop SQLEdge
docker rm SQLEdge

Conclusion

Azure SQL Edge is a way to test and develop using SQL Server locally, and have a consistent experience between machines, whether they’re PCs running Windows, Intel-based Macs, or the new Apple silicon (M1). In a future tip, I’ll take a closer look at any performance or functional differences I observe as I start to compare.

Next Steps

5 Comments

  1. Thanks, this was really useful. I also wasn’t sure at first where to run the RESTORE command but made the assumption it had to be in the Azure Data Studio tool (which I just downloaded and found easy to use). Thanks for posting this!

  2. Thanks Aaron,
    I have the latest DOCKER on my M1 and Azure Data Studio but I haven’t been able to run a Command Line RESTORE. I didn’t think the tools were there in the ARM image?
    John

  3. Thank you Aaron, I reposted your post here: https://dba.stackexchange.com/questions/307157/is-there-a-way-to-use-standard-clr-functions-on-sql-server-for-ubuntu-docker-on/307159#307159

Leave a Reply

Your email address will not be published. Required fields are marked *