docker放浪記2・dockerでSQLServer

第二回dockerでSQLServer
DBならMySQLをやると思っただろ。違うんだな、これが
さて前回、基本アプリのDockerDesktopとVsCodeをインストールしたのですがVsCodeにはdocker拡張機能やSQL-Server拡張機能もあるので、是非使ってみましょう。
RDBMSとは?
SQLServerもMySQLもリレーショナル データベース(RDBMS)と呼ばれます。
詳しくはこちらを参照して見てください。
第二回はdocker-composeを使ってこのDB環境を作り上げて初期データを投入、そしてVsCodeから接続して見ましょう。
VsCodeでフォルダーを開く
今回も例によって適当なフォルダー(mssqlなど)を作成し、VsCodeのエクスプローラーで開いて見ましょう。
ここを参照にしてプロジェクトを作って見ました。
ただわたしの環境ではうまく動作しなかったので、いくつか手を加えてあります。
- 親ディレクトリ(mssqlなど)
- init.db.d(DBを初期化するシェルなどを配置するフォルダです)
- entrypoint.sh(DB初期化シェル)
- init.sql(DB初期データSQL)
- docker-compose.yml
- init.db.d(DBを初期化するシェルなどを配置するフォルダです)
今回はインストール等必要ないみたいですのでDockerFileは使いません。
docker-compose.yml
以下docker-compose.ymlの例です。
version: '3'
services:
mssql:
image: mcr.microsoft.com/mssql/server:2022-latest # イメージを直接指定
cap_add:
- SYS_PTRACE # 追加 システムアタッチ
security_opt:
- seccomp:unconfined # 追加 システムアタッチ
user: root # ルートユーザーで実行
container_name: mssql # コンテナ名を指定
environment: # 環境変数を設定
- ACCEPT_EULA=Y # エンドユーザーライセンス契約に同意
- SA_PASSWORD=Passw0rd # パスワードを設定
- MSSQL_PID=Express # エディションを設定
- MSSQL_TCP_PORT=1433 # 使用するポートを設定
- MSSQL_LCID=1041 # 日本語に設定
- TZ="Asia/Tokyo" # タイムゾーン設定
- Japanese_CI_AS=Japanese_CI_AS # 照合順序を指定
ports: # ポート番号を指定(ホスト:コンテナ)
- 1433:1433
volumes: # マッピングを指定
- ./init.db.d:/docker-initdb.d # 初期化用SQLとSQL Server起動スクリプト
- mssql_data:/var/opt/mssql/data # dataの永続化
- mssql_log:/var/opt/mssql/log # logの永続化
- mssql_secrets:/var/opt/mssql/secrets # secretsの永続化
command: ["/bin/bash", "-c", "chmod +x /docker-initdb.d/entrypoint.sh && /docker-initdb.d/entrypoint.sh"] # SQL Server起動スクリプトを実行
volumes:
mssql_data:
mssql_log:
mssql_secrets:
ほぼ参照元のままなのですが、いくつか動作しなかったところ(システムアタッチなど)を修正しました。
元になるイメージはM1だと動作しないらしいのですが、前回のようにDockerDesktopでUseVirtualization frameworkをオンにしたら動いたのでそのまま使用しています。
dockerでDB環境を動作させる場合、永続化(dockerコンテナを停止させた時にDBのデータが消えないようにする)という作業が必要なのですがそれをvolumesでローカルに関連づけています
entrypoint.sh
実行シェルです。そのためdocker-compose.ymlのcommandで実行権限を与えてから実行しています。
#!/bin/bash
# SQL Serverをフォアグラウンドで実行
echo "Waiting for SQL Server to start..."
/opt/mssql/bin/sqlservr & MSSQL_PID=$!
# SQL Serverの起動を待機
#while ! /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Passw0rd -Q "SELECT 1" > /dev/null 2>&1; do
while ! /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P Passw0rd -C -Q "SELECT 1" > /dev/null 2>&1; do
sleep 1
done
echo "SQL Server started."
# 初期化用SQLを実行
echo "Initializing database..."
#/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Passw0rd -i /docker-initdb.d/init.sql
/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P Passw0rd -i /docker-initdb.d/init.sql -C
echo "Database initialized."
# バックグラウンドで実行中のSQL Serverのプロセスを待機
wait $MSSQL_PID
# SQL Serverをフォアグラウンドで実行
echo "Waiting for SQL Server to start..."
/opt/mssql/bin/sqlservr & MSSQL_PID=$!
# SQL Serverの起動を待機
while ! /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P Passw0rd -C -Q "SELECT 1" > /dev/null 2>&1; do
sleep 1
done
echo "SQL Server started."
# 初期化用SQLを実行
echo "Initializing database..."
/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P Passw0rd -i /docker-initdb.d/init.sql -C
echo "Database initialized."
# バックグラウンドで実行中のSQL Serverのプロセスを待機
wait $MSSQL_PID
これもいくつかdockerデバッグをしながら修正しました。コンテナが起動中であればVsCodeやターミナルなどから
docker exec -it mssql /bin/bash
のようにしてdockerコンテナに入り
cat /var/opt/mssql/log/errorlog.loc
のようにしてログを見てデバッグしました。
init.sql
-- データベースが存在しない場合のみ作成
IF NOT EXISTS(SELECT * FROM sys.databases WHERE name = 'test_db')
BEGIN
CREATE DATABASE test_db;
END
GO
USE test_db;
GO
-- テーブルが存在しない場合のみ作成
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'UserInfo' AND type = 'U')
BEGIN
CREATE TABLE UserInfo (
[id] INT NOT NULL IDENTITY(1,1)
, [name] VARCHAR(MAX)
, PRIMARY KEY (ID)
);
INSERT INTO UserInfo (name) VALUES('taro');
INSERT INTO UserInfo (name) VALUES('jiro');
INSERT INTO UserInfo (name) VALUES('saburo');
END
GO
テーブル名でSQLエラーが出たのでUserInfoにかえました。
実行してみるっ
起動方法は前回と同じでVsCodeでターミナルを開き
docker-compose -p <コンテナ名> up -d
とやってみましょう
うまく行けばMAC上でSQLServerが起動します。
RecoveryUnit::Shutdown. IsOnline: 02024-12-06 00:20:28.39 spid28s Attribute synchronization initialized
2024-12-06 00:20:28.39 spid28s Attribute synchronization initialized
2024-12-06 00:20:28.39 spid28s Attribute synchronization manager initialized
2024-12-06 00:20:28.40 spid28s Attribute synchronization manager initialized
DockerDesktopでこんなログが出ればOKです。
VsCodeで接続してみるっ
といっても同じマシン内なので簡単だろう、と思うのですが、意外と苦労しました。
まずVsCodeに拡張機能のsql serverをインストールしましょう
接続先ホストはlocalhost,1433になります。
ユーザーはsa、パスワードはdocker-compose.ymlのSA_PASSWORDで指定しているものになります。
これでテーブルUserInfoの内容が見れればOKです。