Update: as pointed out to me on Reddit, it turns out this just got even easier for those with Docker Desktop installed. The latest release (4.16.0) includes an option to use Rosetta as the emulator similar to what Lima is doing below. Once enabled SQL Server should just work if you set the platform flag to
linux/amd64
After countless hours entering different terms into various search engines, only to have them all return the same "Run SQL Server on an M1 Mac" results that actually run Azure SQL Edge instead, I have uncovered a simple enough way to run a full version of SQL Server Linux on an M1 Mac.
For some, running Azure SQL Edge for local development is enough and if it is, go for it (it is likely still the top Google result if you want to go looking)!
If however you require some of the features missing from the cutdown edge version, or a tool you use for schema versioning requires it (e.g. Flyway) then hopefully this simple how-to will get you going.
Lima to the rescue
[🌎Web site]
[📖Documentation]
[👤Slack (#lima
)]
Lima: Linux Machines
Lima launches Linux virtual machines with automatic file sharing and port forwarding (similar to WSL2).
The original goal of Lima was to promote containerd including nerdctl (contaiNERD ctl) to Mac users, but Lima can be used for non-container applications as well.
Lima also supports other container engines (Docker, Podman, Kubernetes, etc.) and non-macOS hosts (Linux, NetBSD, etc.).
Getting started
Set up (on macOS):
brew install lima
limactl start
To run Linux commands:
lima sudo apt-get install -y neofetch
lima neofetch
To run containers with containerd:
lima nerdctl run --rm hello-world
To run containers with Docker:
limactl start template://docker
export DOCKER_HOST=$(limactl list docker --format 'unix://{{.Dir}}/sock/docker.sock')
docker run --rm hello-world
To run containers with Kubernetes:
limactl start template://k8s
export KUBECONFIG=$(limactl list k8s --format 'unix://{{.Dir}}/copied-from-guest/kubeconfig.yaml')
kubectl apply
…Or at least Lima and all of the tools it pulls together like Rosetta, QEMU, containerd, nerdctl, etc. Lima is virtual machine from which you can launch containers using the containerd runtime (or the docker runtime if you so choose).
Virtual machines can be launched on the battle-hardened QEMU emulator, or more importantly for our use case, using native virtualisation, aka VZ (to Lima) or Rosetta 2. While still experimental the VZ virtual machine type offers better performance and is the only VM I could get SQL Server to work on.
SQL Server on Apple Silicon
Get it going
To get SQL Server running, first download and install Lima using Homebrew (other installation options can be found on GitHub):
brew install lima
Once installed, start a new virtual machine using the experimental VZ VM:
limactl start --name=default --tty=false template://experimental/vz
The above command will create a new VM config under $HOME/.lima/default
. By using default we get the convenience of not having to name our VM for shell commands. --tty=false
is not necessary, it is just a convenient way to skip Lima asking if you want to review your config.
You should see an output for the starting VM concluding with the following lines:
INFO[0040] [hostagent] Waiting for the final requirement 1 of 1: "boot scripts must have finished"
INFO[0049] [hostagent] The final requirement 1 of 1 is satisfied
INFO[0049] READY. Run `lima` to open the shell.
If you happen to see the error r.CreateEndpoint() = connection was refused
along the way this can safely be ignored.
Now that the VM is running, all that is left to do is start a SQL Server container. This can be done using nerdCtl, a CLI tool for containerd that mimics the commands available in the Docker CLI.
nerdctl.lima run --platform linux/amd64 -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=ThisIsMyP@ssw0rdThereAreManyLikeItButThisOneIsMine" -p 1433:1433 -d --restart always mcr.microsoft.com/mssql/server:2022-latest
This will launch SQL Server on the necessary amd64 runtime, accepting the EULA and setting the sa
password in the process. It exposes the SQL Server default port 1433 and is configured to run in the background and restart if stopped.
If SQL Server 2022 isn't your jam then just replace the container tag with the SQL Server version of your choosing:
nerdctl.lima run --platform linux/amd64 -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=ThisIsMyP@ssw0rdThereAreManyLikeItButThisOneIsMine" -p 1433:1433 -d --restart always mcr.microsoft.com/mssql/server:2019-latest
Finally, obtain the IP address of the running VM using:
lima ip -f inet addr
The IP address you are after will be listed under the lima0
adaptor.
Test it works
One simple way to test if SQL Server is running and accessible is to use Microsoft's sqlcmd
tool. This can also be installed with Homebrew:
brew tap microsoft/mssql-release https://github.com/Microsoft/homebrew-mssql-release
brew update
brew install mssql-tools
Then attempt to connect:
sqlcmd -S 192.168.105.3 -U sa -P "ThisIsMyP@ssw0rdThereAreManyLikeItButThisOneIsMine" -Q "select name,database_id,create_date from sys.databases"
-S
refers to the server address. This is the IP address of the VM that you obtained earlier.
If all has gone to plan you should see the databases that currently belong to SQL Server along with their ID and create date.
Cleaning up
If you need to clean up your Lima VM for any reason, first stop the VM:
limactl stop default
Then delete it:
limactl delete default
Final disclaimer
Lima is still quite new and I am even newer to it so bear in mind that there may be better ways to wield this weapon. There is also a lot of development in this space with the likes of Finch, Multipass and others offering potential alternatives or simplifications to this approach so watch this space!
Top comments (2)
Great article! You can ease all the Lima configuration by using Colima, a wrapper on top of Lima specifically for running docker containers in Lima.
Oh nice, I wasn't aware of Colima thanks @superfola! Looks like it supports Rosetta too (
colima start --arch aarch64 --vm-type=vz --vz-rosetta
), something that wasn't available when I was testing Finch.