LoginSignup
0
1

Docker & Microsoft SQL Server(初期データ登録まで)

Posted at

はじめに

業務でDockerコンテナにMicrosoft SQL Server環境を構築する機会があり、ハマったポイントなどを残しておきます。
他にまとめている記事を拝見しましたが、上手く動かないものが多かったため、丁寧にまとめていきます。ホストはApple M2ですが、他のOSでも気にしないで大丈夫です。

ディレクトリ構成

リポジトリはこちらに作成しています。
docker-compose.yml以外のディレクトリ名やファイル名に決まりはないので、お好きなように変更していただいて問題ないです。
docker-compose.ymlはそのままの名前でないと動きませんので、ご注意ください。

┝ docker
    ┝ init.db.d
        ┝ entrypoint.sh
        ┝ init.sql
    ┝ docker-compose.yml

解説

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 = 'user' AND type = 'U')
BEGIN
    CREATE TABLE user (
        [id] INT NOT NULL IDENTITY(1,1)
        , [name] VARCHAR(MAX)
        , PRIMARY KEY (ID)
    );

    INSERT INTO user (name) VALUES('taro');
    INSERT INTO user (name) VALUES('jiro');
    INSERT INTO user (name) VALUES('saburo');
END
GO

こちらはシンプルで、test_dbというデータベースが存在しない場合のみtest_dbを作成し、userというテーブルが存在しない場合のみuserを作成し、初期データを登録します。
このファイルはコンテナ起動時に毎回流れるため、IF NOT EXISTSを使って存在チェックを行います。

entrypoint.sh

#!/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
    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
echo "Database initialized."

# バックグラウンドで実行中のSQL Serverのプロセスを待機
wait $MSSQL_PID

こちらはSQL Server起動 & 初期化用SQL実行のためのシェルスクリプトです。
シェルスクリプトにまとめる理由は2つです。

  1. docker-compose.ymlにコマンドを全て記述すると見づらくなるから
    docker-compose.ymlは同時に複数のコンテナを操作するためのファイルで、設計書のような役割を果たすことから、可読性を保つ必要があります。
  2. SQL Server起動後に初期化用SQLを実行する必要があるから
    SQL Serverは起動コマンドを実行してから実際に起動するまで遅延があるため、SQL Serverが起動したことを確認してから、初期化用SQLを流さないとエラーになります。

/opt/mssql/bin/sqlservrはSQL Serverを起動させるコマンドです。
MSSQL_PID=$!は直前にバックグラウンドで実行したSQL Server起動プロセスIDをMSSQL_PID変数に保存しています。
最後のwait $MSSQL_PIDでバックグラウンドで実行中のSQL Server起動プロセスを待機させ、終了させないようにすることができます。

! /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Passw0rd -Q "SELECT 1" > /dev/null 2>&1;SELECT 1を実行しています。
SQL Serverが起動前であれば失敗するので、1秒待機して再度SELECT 1を実行します。
ここでは、成功か失敗かを確認できればよいため、> /dev/null 2>&1;を使って出力結果を表示させないようにしています。

/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Passw0rd -i /docker-initdb.d/init.sqlはコメントの通り、/docker-initdb.d/init.sqlを実行しているだけのコマンドです。

echo "Waiting for SQL Server to start..."echo "SQL Server started."echo "Initializing database..."echo "Database initialized."はシェルスクリプトがどこまで進んだかをわかりやすくするためのものです。

docker-compose.yml

version: '3'

services:
  mssql:
    image: mcr.microsoft.com/mssql/server:2022-latest # イメージを直接指定
    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: # マッピングを指定
      - ./initdb.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:

こちらでSQL Serverコンテナの様々な設定をしています。
詳細はコメントの通りですが、ポイントはdocker-compose.ymlentrypoint.shを実行し、実行されたentrypoint.shinit.sqlを実行しているというところです。

docker-compose.yml

entrypoint.sh

init.sql

初期データ登録

実践

Appleシリコン搭載Macに必要な設定

※Appleシリコン以外のOSをお使いの方は、ここは飛ばしてください。

画面右上の歯車から設定を開く
image.png
Use Rosetta for x86/amd64 emulation on Apple Siliconのチェックを付ける
image.png
これだけでOKです!

コンテナ作成 & コンテナ起動

ここからはどのOSでも共通です!
下記を実行します。

# docker-compose.ymlが格納されているディレクトリに移動
cd docker-mssql/docker
# docker-compose.ymlを元にコンテナを作成 & 起動
docker-compose -p [お好きな名前] up -d

こうすることで、コンテナが作成され、起動されます。
赤枠が[お好きな名前]で指定した名前になります。
私はdocker-compose -p docker-mssql up -dで実行したため、docker-mssqlという名前になっています。
image.png

さいごに

個人的にはSQL Serverを使う機会は少ないのかなと思っていますが、使用するプロジェクトもまだ存在するため、参考になれば嬉しいです!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1