Running SQL Server on Apple Silicon - Updated
Last week I purchased a shiny new MacBook Air with an M2 processor. After I got all the standard stuff up and running, I set out to learn how to run SQL Server containers on this new hardware. This post shows you how to run SQL Server on Apple Silicon using colima.
Colima is a container runtime that runs a Linux VM on your Mac. This Linux VM runs using the Virtualization framework hypervisor native in MacOS. Your containers will run inside this virtual machine.
Install Required Software
Docker Desktop for Mac
First, you’ll need Docker Desktop. Well, technically, you don’t need Docker Desktop. Docker Desktop provides both the command line tooling and the container runtime. I’m installing Docker because it will provide the command line interface that I’m used to when working with containers, the docker
command. We’re not going to use Docker as the container runtime. As I write this post, Docker Desktop for Mac recently added MacOS Virtualization framework support, but SQL Server doesn’t run in this environment. I plan to watch this space to see if Docker provides similar functionality in upcoming releases.
Update 22 Jan 23: As predicted, Docker Desktop now supports the Use of Rosetta for x86/amd64 emulation on Apple Silion. Open up your Docker Desktop Settings, click Features in Development and check Use of Rosetta for x86/amd64 emulation on Apple Silion. Once enabled and docker restarts, you can jump right to the section Starting a SQL Server Container. You may be thinking, why would I still go the Colima route? Well, Docker has changed their licensing model and the Colima solution may be a good alternative for you.
Rosetta 2
Next, you’ll need Rosetta 2, which provides emulation for x86 CPU architectures. In other words, software built for x86 can run on Apple Silicon.
softwareupdate --install-rosetta
Installing Colima
You can install Colima with brew MacOS package manager. If you need help installing brew, check out this link.
You can then brew
to install Colima.
brew install colima
Configuring Colima
Setting the Colima virtual machine template configuration
Now, you need to configure Colima’s virtual machine template. Like Docker for Mac, Colima uses a virtual machine to provide a Linux kernel for containers running on MacOS. This virtual machine needs some configuration to run x86 containers.
To configure the VM, you use the command colima template
. This will open Colima’s yaml configuration file in your default text editor.
First, let’s configure the VM to use the MacOS’s Virtualization framework (vz
) rather than the default, which is qemu
.
Around line 121, change vmType: qemu
to vmType: vz
.
Next, around line 133, change mountType: sshfs
to mountType: virtiofs
Next, not required, but reccomended you need to update the CPU and memory allocated to the VM.
Around line 9, change cpu: 2
to cpu 4
and around line 18 change memory: 2
to memory: 4
.
Starting up Colima
Now, you’ll create a virtual machine from the template file configured in the previous section. You execute the command colima start
. This creates and boots up a VM. And it changes the context of your docker command to point to the Colima container runtime rather than Docker Desktop’s. So when you use docker
commands, they are executed against this VM rather than the Docker Desktop installation. As a note, the settings you set in the template file above can be passed as runtime parameters for the colima start
command. But my preference is to have them persistent in a file.
bash-3.2$ colima start
INFO[0000] starting colima
INFO[0000] runtime: docker
INFO[0000] creating and starting ... context=vm
INFO[0014] provisioning ... context=docker
INFO[0014] starting ... context=docker
INFO[0019] done
Working with Contexts
A second ago, I used the term context. A context is a configuration for your docker CLI tools telling the tools which container runtime endpoint to execute the commands against. When you install Docker Desktop, your default context is the Docker container runtime endpoint. When you start up Colima, it adds a new context and configures your default docker context to point to this new endpoint. You can easily switch between these to launch containers in either container runtimes using the command docker context use [context name]
. To get a listing of which contexts are available on your system, you can use docker context list
and you will get this output.
docker context list
NAME TYPE DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR
colima * moby colima unix:///Users/aen/.colima/default/docker.sock
default moby Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm
desktop-linux moby unix:///Users/aen/.docker/run/docker.sock
Notice the *
next to colima
, this means it is the default. So docker
commands will execute and start containers in this container runtime. Note you can also define which context you want your commands to run against for each execution with the parameter --context
rather than relying on the default context configuration.
At this point, you no longer need the docker container runtime. To conserve your systems resources, you can quit docker and set it to not restart when your computer starts up.
Starting a SQL Server Container
OK, so now that everything is up and running, let’s start a SQL Server container. Most of these parameters are familiar to you if you’ve been working with SQL Server in containers. There is one new one, --platform linux/amd64
. This gives docker
a hint on which container image to pull.
docker run \
--env 'ACCEPT_EULA=Y' \
--env 'MSSQL_SA_PASSWORD=S0methingS@Str0ng!' \
--name 'sqldemo1' \
--hostname 'sqldemo1' \
--publish 31433:1433 \
--volume sqldemo1:/var/opt/mssql \
--detach \
--platform linux/amd64 mcr.microsoft.com/mssql/server:2022-RTM-ubuntu-20.04
If you don’t specify --platform linux/amd64
, everything works fine, but you’ll get this warning at startup.
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
Checking out what SQL Server thinks about all of this
What I like most about this is all the code I’ve written using the docker
command just work, even though this container isn’t running in the docker container runtime but rather Colima.
With that up and running, we can use docker logs sqldemo1
to get some information about this container.
SQL Server thinks it’s running on an x64 CPU.
2023-01-02 15:59:32.97 Server Microsoft SQL Server 2022 (RTM) - 16.0.1000.6 (X64)
Oct 8 2022 05:58:25
Copyright (C) 2022 Microsoft Corporation
Developer Edition (64-bit) on Linux (Ubuntu 20.04.5 LTS) <X64>
Based on our Colima virtual machine configuration, you can see SQL Server had access to four CPUs. The MacBook Air I have has eight cores. But this CPU topology is coming from the Colima VM.
2023-01-02 15:59:32.98 Server SQL Server detected 1 sockets with 4 cores per socket and 4 logical processors per socket, 4 total logical processors; using 4 logical processors based on SQL Server licensing. This is an informational message; no user action is required.
Next, we configured Colima to use 4GB of RAM. The VM has 4GB of RAM, but due to the architecture of SQL Server on Linux with SQLPAL, the default is the SQL Server process sees about 80% of that. So here we see 3142MB of memory.
2023-01-02 15:59:32.98 Server Detected 3142 MB of RAM. This is an informational message; no user action is required.
SQL Server throwing some shade at my configuration:
2023-01-02 15:59:33.67 Server In-Memory OLTP initialized on lowend machine.
How’s Performance?
This whole experiment isn’t a performance play. I need the ability to run SQL Server containers on my laptop in a functional way. This configuration gives me just that. And it’s pretty decent on performance too. While, I still need to do a complete evaluation of performance, here’s a restore of a backup…getting roughly 785MB/sec. That’s good enough for what I need.
USE [master]
RESTORE DATABASE [tpcc100]
FROM DISK = N'/var/opt/mssql/data/tpcc100.bak'
WITH REPLACE
Database 'tpcc100' running the upgrade step from version 912 to version 913.
...
Database 'tpcc100' running the upgrade step from version 956 to version 957.
RESTORE DATABASE successfully processed 1032597 pages in 10.278 seconds (784.896 MB/sec).
Total execution time: 00:00:12.866