By: Aaron Bertrand | Updated: 2024-07-12 | Comments | Related: > Containers
Problem
I use Apple hardware almost exclusively and have done so for more than half of my career. These days, I do less and less local testing of SQL Server syntax and features, but when I do, I use Docker containers.
I've written about SQL Server and Docker on a Mac before, for example, Testing SQL Server Edge and Docker on the latest MacBooks. But things have changed. Most importantly, we can now run a real SQL Server edition on Apple M chips instead of the Azure SQL Edge flavor. I talked about this development last year: Regular SQL Server on Apple Silicon? Yes you can!
What else do I think you need to know?
Solution
In this tip, I want to share a consolidated list of things you can (or should) do when using Docker to run SQL Server on your own Mac. Some of this may only apply to M chips, but some apply in any scenario - even Windows.
Where to Get Docker
Docker Desktop has a download page. If you are using an M chip, make sure to choose the Apple chip option:
What Settings to Enable
To use a full-on version of SQL Server, you need to enable Rosetta emulation ("Use Rosetta for x86_64/amd64 emulation on Apple Silicon"). It should be enabled by default, but you can check under Settings (the screenshot is from version 4.30):
This has been supported since Ventura 13.3; I am on Sonoma 14.2 at the time of writing.
How to Get SQL Server
Once Docker is up and running, you can pull the latest container image per version, e.g., from whatever terminal you prefer (I use iTerm2 and Hyper):
docker pull mcr.microsoft.com/mssql/server:2022-latest
How to Start a Container
I'm not a huge fan of yaml or trying to understand docker-compose; if you grok those, great! If not, it's simplest to issue a docker run command to spin up a container on demand. Here is an example:
docker run -d --name SQL2022 --platform=linux/amd64 -e ACCEPT_EULA=1 -e MSSQL_SA_PASSWORD=Bak3D_B3anZ -p 6666:1433 mcr.microsoft.com/mssql/server:2022-latest
The -d
option tells the
container to run "detached"; if you leave it out, the container will
run in the context of your terminal window and spit out all the error log entries
there.
There are several other options to explore…
Name Your Container
Give your container a meaningful
--name
; without it, your
container will have a randomly generated name like this:
c1a39b8aedef60a97aaa96989107253383f7493da605b81bfa1ed9fcd198cfbd
Yuck. With a short and maybe even meaningful name, you will have a much easier
time interacting with the container and issuing commands. While you can use shorthand
(for example, docker start c1a39b
will work), even a few characters are too much for me to want to remember, starting
fresh every time.
Indicate the Platform
The --platform
argument
is only applicable if you are running on an Apple M chip, in which case it must
be set to linux/amd64
. If
you're on an Intel Mac or a Windows machine, just leave this line out.
Accept the EULA
I know it's a well-guarded secret, but nobody reads the license agreement.
Still, you need to pretend you did.
-e ACCEPT_EULA
will take
1
or
Y
, but your container won't
start otherwise.
How to Create a Password
You need to be careful about your
sa
password, because it
must satisfy
complexity requirements (they can't be bypassed like in
CREATE LOGIN
). If your password
has a special character (like $
),
it must be escaped in some contexts. In either case, SQL Server may not start or
be able to connect. I suggest something relatively long, with a healthy mix of alphanumeric
characters and "safe" symbols, like the one above or:
-e MSSQL_SA_PASSWORD = L00ney_T00ns_43va
What Port to Use
You specify the port SQL Server should run on (mapped internally to 1433) using
-p
. I like
using ports that mean something; for example, if I'm testing SQL Server
2019 and SQL Server 2022 (even if I don't intend to run both at the same time),
I'll set the former to port 2019 and the latter to port 2022. This approach
won't always make sense; just be sure to use a port that isn't already
used on the host (or that might potentially conflict in the future, including other
containers). If I don't have a specific one in mind, I tend to default to
something easy, like 6666 or 411.
Some Other Tidbits
How to Attach or Restore a Database
SQL Server's installed, so what? You can poke around in
master
if you like, but
what if you want to do something real? Like, with a real database?
An easy way to create small-ish databases inside a container is to copy your backup there and restore it from within.
Docker allows you to interact with the filesystem within the container, so you
can easily create folders and move files there from the host. Let's say you
have downloaded an
AdventureWorks sample database to
/Users/me/Downloads/aw/AdventureWorksLT.bak
.
You can make a backup directory inside the container using
docker exec
and then copy
the file there using docker cp
:
docker exec -it SQL2022 mkdir "/var/opt/mssql/backup" cd /Users/me/Downloads/aw/ docker cp . SQL2022:/var/opt/mssql/backup/
See where giving the container a logical name comes in handy?
Note: I recommend putting a downloaded file into its folder so you can use
cp .
(all files) instead
of typing out the filename. cp
doesn't support wildcards, and I'm sure you don't want to copy
your entire downloads folder!
With the file in place within the container, SQL Server can see it so that you
can issue a normal RESTORE DATABASE
command. But, if the backup was originally created on Windows, you'll definitely
need WITH MOVE
options.
For the 2022 version of AdventureWorksLT:
RESTORE DATABASE AdventureWorksLT FROM DISK = N'/var/opt/mssql/backup/AdventureWorksLT2022.bak' WITH REPLACE, RECOVERY, MOVE N'AdventureWorksLT2022_Data' TO N'/var/opt/mssql/data/awlt2022.mdf', MOVE N'AdventureWorksLT2022_Log' TO N'/var/opt/mssql/data/awlt2022.ldf';
Depending on what database you're trying to restore, you should confirm
the list of files (and that you don't have hints of unsupported features like
filestream or In-Memory OLTP) using
RESTORE FILELISTONLY
.
Be Aware of Size
So far, I've found that anything under 40 GB is okay. What happens if you
get into larger territory, like the backups are too large to move to the container
or the databases will be too big once restored or grow too large once you begin
using them? You can then override the default container size with an additional
option for docker run
. The
following will create the container with a base size of 256 GB:
--storage-opt dm.basesize=256G
See this post for some other possible workarounds.
How to Connect from Another Container
Probably the most common issue I've seen on Stack Overflow is when people
try to connect to a SQL Server container from another container using
localhost
or
127.0.0.1
. That's
the local machine, according to that container, so the container itself, not
the local machine, according to the host running that container. You
need to tell the container to connect to the right port on the host's
IP, which you can get from
ifconfig
(for me, it was in
ifconfig en10 inet
on one
machine and en7
on another;
yours may be elsewhere depending on your configuration):
In this case, where SQL Server is running on port 6666, then to connect from another container, I would tell the application inside that container to connect to:
192.168.1.79,6666
You can potentially do something with the hosts file or other mechanisms within
the container to give a name to the host's IP, but I don't do anything
like this enough to bother. Some answers, like
this one, suggest
it can be easily handled by docker
exec
.
Next Steps
- Grab Docker Desktop and start playing with containers for local development and testing!
- See these tips and other resources about SQL Server containers or SQL Server
on Linux:
- Performance Testing Azure SQL Edge on Intel and M1 MacBooks
- Testing SQL Server Edge and Docker on the latest MacBooks
- Run SQL Server vNext (CTP1) as a Docker Container on a Mac
- Build Docker Containers with External Storage on Your Desktop
- SQL Server 2017 installation on Ubuntu using Docker
- Edwin Sarmiento's series on Docker containers: Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6
- Run and Manage SQL Server 2019 CTP 2.0 RHEL Docker Container
- All SQL Server on Linux tips
About the author
This author pledges the content of this article is based on professional experience and not AI generated.
View all my tips
Article Last Updated: 2024-07-12