🐋

Apple Silicon の Mac で SQL Server コンテナを動かす

2023/11/04に公開

以前 M1 Mac に変えた当初は SQL Server コンテナが ARM アーキテクチャ上で動かせなかった。
(--platform linux/x86_64 を指定しても駄目だった。)
そのため、代わりに ARM 版コンテナが提供されていた Azure SQL Edge を使用していた。

Azure SQL Edge by Microsoft | Docker Hub
https://hub.docker.com/_/microsoft-azure-sql-edge

今回一から環境構築をやり直す機会があったのだが、Docker Desktop for Mac 4.16 以降なら [Use Rosetta for x86/amd64 emulation on Apple Silicon] オプションを有効にすれば SQL Server のコンテナも動くらしいとの情報を見かけたので試してみた。

Docker Desktop for Mac のインストールと設定

Install Docker Desktop on Mac | Docker Docs
https://docs.docker.com/desktop/install/mac-install/

上記サイトの「Docker Desktop for Mac with Apple silicon」からインストーラをダウンロードしてインストール。
バージョンは v4.25.0 だった。

インストール完了したら [Settings...] - [General] - [Use Rosetta for x86/amd64 emulation on Apple Silicon] にチェックをいれて [Apply & restart] する。

SQL Server 2022 のインストール

公式は以下。

Microsoft SQL Server - Ubuntu based images by Microsoft | Docker Hub
https://hub.docker.com/_/microsoft-mssql-server

ここでは 2022-latest を使用した

# 起動
% docker run -e "ACCEPT_EULA=Y" \
             -e "MSSQL_SA_PASSWORD=1Strong#Pwd" \
             -e "TZ=Asia/Tokyo" \
             -p 1433:1433 \
             --name sqlserver2022 \
             -h sqlserver2022 \
             -v sqlserver2022_volume:/var/opt/mssql \
             -d \
             mcr.microsoft.com/mssql/server:2022-latest

# 実行すると以下のメッセージが出力されたが、起動には成功している模様
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
18048d6c14b12e26b507fd00e76207ae3e5ab279fc7640c681d0a6a22df0577c

# 起動してることを確認
% docker ps
CONTAINER ID   IMAGE                                        COMMAND                   CREATED              STATUS              PORTS                    NAMES
18048d6c14b1   mcr.microsoft.com/mssql/server:2022-latest   "/opt/mssql/bin/perm…"   About a minute ago   Up About a minute   0.0.0.0:1433->1433/tcp   sqlserver2022

# ログ確認
% docker logs sqlserver2022
# (略)

# 名前付きボリュームが作成されていることを確認
% docker volume ls
DRIVER    VOLUME NAME
local     sqlserver2022_volume

% docker inspect sqlserver2022_volume
[
    {
        "CreatedAt": "2023-11-04T08:22:20Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/sqlserver2022_volume/_data",
        "Name": "sqlserver2022_volume",
        "Options": null,
        "Scope": "local"
    }
]

接続確認

コンテナ入って確認、でもいいけど、せっかくホストのポートにバインドしたのでコンテナの外部から接続確認しておきたい。

確か以前は sqlcmd とか ODBC ドライバも ARM 対応してなかった気がしたので、公式を確認。

Microsoft ODBC Driver for SQL Server をインストールする (macOS) - ODBC Driver for SQL Server | Microsoft Learn
https://learn.microsoft.com/ja-jp/sql/connect/odbc/linux-mac/install-microsoft-odbc-driver-sql-server-macos?view=sql-server-ver15

注意

macOS 上の Microsoft ODBC Driver for SQL Server は、バージョン 17.7 を介して x64 アーキテクチャでのみサポートされています。
バージョン 17.8 から、Apple ARM64 がサポートされるようになりました。
アーキテクチャが検出され、Homebrew 式によって適切なパッケージが自動的にインストールされます。

とあったので、17.8 以降なら ARM 対応してる模様。
確かアプリケーション用コンテナの方もこれが原因で --platform linux/x86_64 指定して使ってた気がするけど、この指定はもう要らなくなったっぽい。

ただ、調べてみたら ODBC ドライバを 18 以降に上げると追加のオプション指定が必要になるようなので、既存アプリケーションのコンテナを変更する場合は注意が必要そう。

Connection encryption troubleshooting - ODBC Driver for SQL Server | Microsoft Learn
https://learn.microsoft.com/en-us/sql/connect/odbc/connection-troubleshooting?view=sql-server-ver16

Laravel SQLserver リモート接続のエラー 解決 #SQLServer - Qiita
https://qiita.com/tenriyu/items/e682a0d6c9dab28a02cc

対応しているのは分かったので homebrew で直接入れてもいいけど、以前 openssl@1.1 絡みとかでハマったりしたのでなんとなく気乗りしない。

調べるとどうやら mssql-tools 用のコンテナも提供されているようなので、ここではそれを使って接続してみることにした。

Mssql Tools by Microsoft | Docker Hub
https://hub.docker.com/_/microsoft-mssql-tools

ホストのローカルポートに接続するので --network host を指定して実行しないと接続できない。

% docker run -it --rm --network host mcr.microsoft.com/mssql-tools /opt/mssql-tools/bin/sqlcmd -S 127.0.0.1 -U sa -P "1Strong#Pwd"
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
1> EXEC sp_databases
2> GO
DATABASE_NAME                  DATABASE_SIZE REMARKS
------------------------------ ------------- --------------------------------------------------------------
master                                  6400 NULL
model                                  16384 NULL
msdb                                   16960 NULL
tempdb                                 73728 NULL
1>

問題なさそう。

ちなみに、 MSSQL_SA_PASSWORD で指定したパスワード文字列がパスワードポリシー違反(複雑性が足りない)の場合、特にサーバはエラーを吐かず、単に sa ユーザが無効になる、とのこと。

Why I can't login SA with docker · Issue #315 · microsoft/mssql-docker
https://github.com/microsoft/mssql-docker/issues/315

検証なので最初適当に指定したら、コンテナは起動するのに全然 sa ユーザで接続できなくってしばらくハマったので注意。

参考

Docker:SQL Server on Linux 用のコンテナーのインストール - SQL Server | Microsoft Learn
https://learn.microsoft.com/ja-jp/sql/linux/quickstart-install-connect-docker?view=sql-server-ver16&preserve-view=true&pivots=cs1-bash

SQL Server Linux コンテナーをデプロイして接続する - SQL Server | Microsoft Learn
https://learn.microsoft.com/ja-jp/sql/linux/sql-server-linux-docker-container-deployment?view=sql-server-2017&pivots=cs1-bash

SQL Server Docker コンテナーを構成およびカスタマイズする - SQL Server | Microsoft Learn
https://learn.microsoft.com/ja-jp/sql/linux/sql-server-linux-docker-container-configure?view=sql-server-ver16&pivots=cs1-bash

Discussion