Published on

Getting SQL Server to Work with Docker and Mac

Authors

TLDR

  • Do not use volumes on SQL Server containers (at least on Mac, your mileage may vary on Linux/Windows)
  • Bump up Docker for Mac's RAM to 5GB
    • Apparently, SQL Server (empty DB) needs minimum 4GB to start ¯\(ツ)
  • Start the container with 4096M RAM

The Detailed Version

As part of the current project I am on, I have a bunch of docker-compose files I use to replicate the DEV, UAT and PROD environments as closely as possible. From a DB perspective, this means I need to run SQL Server. Luckily there is an official SQL Server Docker container that can be used exactly for this.

Unfortunately simply using the container is not the end of it. I found trying to use this container the way I use other DB containers is not stable at all. My usual approach when dealing with DB containers is:

  • Create a volume for the container
  • Use the volume to store the DB container so that it survives container crashes

In a perfect world, my compose file would look something like this:

version: "3.7"

services:
...
  db:
    image: mcr.microsoft.com/mssql/server:2017-CU18-ubuntu-16.04
    restart: unless-stopped
    container_name: my-apps-db
    deploy:
      resources:
        limits:
          memory: 4096M
    ports:
      - "1433:1433"
    volumes:
      - "dbData:/var/opt/mssql/data"
    environment:
      - ACCEPT_EULA=Y
      - SA_PASSWORD=uber_secure_password_here

volumes:
  dbData:

But when trying to run this setup I find the DB takes ages to start. But even once it has started it regularly crashes causing any containers/applications connecting to it to become unstable.

After a bit of Googling, I came across various issues logged against the mssql-docker Github repo. Here is one for example. 2 main problems need to be addressed:

  • SQL Server needs a minimum of 4GB to run
  • Volume mounts (where writes happen) do not work on Mac
    • Mounts where only reads happen work fine

Based on this I updated the previous docker-compose file to look as below:

version: '3.7'
---
db:
  image: mcr.microsoft.com/mssql/server:2017-CU18-ubuntu-16.04
  restart: unless-stopped
  container_name: my-apps-db
  deploy:
    resources:
      limits:
        memory: 4096M
  ports:
    - '1433:1433'
  environment:
    - ACCEPT_EULA=Y
    - SA_PASSWORD=uber_secure_password_here

To run this with Docker-compose without swarm do so as follows:

docker-compose --compatibility up -d
  • The --compatibility flag is needed here to get compose 3.x to convert 3.x swarm blocks to 2.x's resource fields.

This can be done directly with docker as follows:

docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=uber_secure_password_here' --memory=4096M -p 1433:1433 -d mcr.microsoft.com/mssql/server:2017-CU18-ubuntu-16.04