Windows10のDocker上にSQLServer2022を構築する

# はじめに

仕事でDocker上にSQLServerを構築する機会がありました。（参考になるサイトがあり助かりました。）
バージョンは最新で構築したので、その際に出たエラー等で対応した内容や、SQLServerの接続にSQL Server Management Studio (SSMS) を使用しましたので、その手順をまとめてみました。

## 参考元

https://zenn.dev/megablacklabel/articles/d229408fffc5d35efaa0

# 動作環境

1. Windows10
2. Docker Desktop 4.19.0
    - mssql-server-linux 2022-latest（SQLServer2022 Linuxコンテナーイメージ）
3. SQL Server Management Studio (SSMS) 19.0.2 

# ファイル／フォルダ構成

```:ファイル／フォルダ構成
\---mssql-server-linux-sample
    |   .gitignore
    |   db-init.sh
    |   db-init.sql
    |   docker-compose.yml
    |   Dockerfile
    |   entrypoint.sh
    |
    \---backup
        NewEmployeeList.csv
```

# ファイル内容

docker-compose.ymlは以下の通りとします。
ホスト名はsql1とし、パスワードはBingさん（ChatGTP）に作成してもらいました。いい時代になりました。
またポート番号は1433のままとしています。

```ComposeFile:docker-compose.yml
version: "3"
services:
    db:
        build: ./
        environment:
            SA_PASSWORD: "B!ng_2023"
            ACCEPT_EULA: "Y"
            MSSQL_AGENT_ENABLED: "true"
        ports:
            - "1433:1433"
        container_name: sql1
        hostname: sql1
        volumes:
            - ms-sqlserver-linux-test-data:/var/opt/mssql
            - ./backup:/backup
volumes:
    ms-sqlserver-linux-test-data:
        driver: local
```


```Dockerfile:Dockerfile
FROM mcr.microsoft.com/mssql/server:2022-latest

COPY . /usr/src/docker

WORKDIR /usr/src/docker

# RUN chmod +x ./db-init.sh

CMD /bin/bash ./entrypoint.sh
```

この環境だと`RUN chmod +x ./db-init.sh`は、`docker-compose build`実行時にエラーとなるので、コメント化（していても問題なく動く）してます。理由がわかる方がいましたら教えてもらえると助かります。
`CMD /bin/bash ./entrypoint.sh`は、Docker起動（`docker-compose up -d`）時にentrypoint.shを実行します。

```entrypoint.sh
#start SQL Server, start the script to create/setup the DB
 ./db-init.sh & /opt/mssql/bin/sqlservr
```

Docker起動時にdb-init.shを実行します。

```sh:db-init.sh
#start SQL Server, start the script to create/setup the DB
#wait for the SQL Server to come up
sleep 10s

echo "running set up script"
#run the setup script to create the DB and the schema in the DB
/opt/mssql-tools/bin/sqlcmd -S sql1 -U SA -P "B!ng_2023" -d master -i db-init.sql
```

sqlcmdのサーバー名の指定を`localhost`としているサイトが多かったが、自分の環境では動作しませんでした。docker-compose.ymlで指定したホスト名`sql1`を指定すると正しく動作しました。

```SQL:title
CREATE DATABASE testdb;
go

use testdb;
go

DROP TABLE IF EXISTS NewEmployee;
GO

CREATE TABLE NewEmployee(
No CHAR (5),
氏名 NVARCHAR (8),
性別 NVARCHAR (1),
生年月日 DATE
PRIMARY KEY (No));
GO

BULK INSERT NewEmployee
FROM '/usr/src/docker/backup/NewEmployeeList.csv'
WITH
(
   FORMAT='CSV',
   FIRSTROW = 2, 
   ROWTERMINATOR = '\r\n'
);
GO
```

テーブルの項目名に、日本語を使えることがSQLServerを選んだ理由なので、サンプルの項目名は日本語名としています。

```csvs:NewEmployeeList.csv
"No","氏名","性別","生年月日"
0001,"伊藤〇也","男",1992-04-04
0002,"小林〇理","女",1997-07-07
0003,"中村〇子","女",2001-09-09
0004,"高橋〇一","男",2004-02-02
0005,"斉藤〇介","男",2007-08-08
0006,"山本〇穂","女",1993-06-06
0007,"松本〇太郎","男",1998-08-08
0008,"河野〇子","女",2002-10-10
0009,"清水〇司","男",2005-03-03
0010,"石川〇美子","女",2008-05-05
```

ここで注意点があり、BULK INSERT（bcpコマンドも）を使用してDocker上のSQLServer（Linux版）に取り込む場合、文字コードを`UTF-16,BOM付`保存してください。（そうでないと日本語が文字化けします。。。）

# docker-composeの操作について

以下に、簡単なDockerの操作方法を記載しました。

## Dockerイメージをビルドする

```powershell
docker-compose build
```

## コンテナを起動する

```powershell
docker-compose up -d
```

## コンテナを停止する

```powershell
docker-compose stop
```

## コンテナを停止→イメージを削除する
```powershell
docker-compose down
```
# SQL Server Management Studio (SSMS)について

SSMSのダウンロードから接続までの手順を、以下にまとめました。

## SSMSをダウンロードする

SQLServerへの接続方法はいろいろありますが、試行錯誤している間にSSMSに落ち着きましたので、その際の接続方法を記載します。
以下のサイトから、SSMSをダウンロードしてください。

https://learn.microsoft.com/ja-jp/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver16

ページを開くと下記のようなリンク（赤枠）があるので、クリックすればダウンロードできます。
![スクリーンショット 2023-05-04 094937.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3339977/50f88fd2-a76c-55f3-06d5-5b8d7aeb45ca.png)

## SSMSをインストールする

インストールは簡単で、以下の画面が表示されるので、「Install」ボタンをクリックするだけです。
![スクリーンショット 2023-05-07 165929.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3339977/cbe03642-95a0-8d0f-0f0d-e15ad437d990.png)

## DockerのIPアドレスを調べる

以下のコマンドを実行します。
```powershell
ipconfig
```

すると実行結果の中に「イーサネット アダプター vEthernet (WSL)・・・」と出力されている箇所があるかと思います。
```:実行結果
イーサネット アダプター vEthernet (WSL):

   接続固有の DNS サフィックス . . . . .:
   リンクローカル IPv6 アドレス. . . . .: fe80::7313:5580:5ca9:ab89%39
   IPv4 アドレス . . . . . . . . . . . .: 172.19.48.1
   サブネット マスク . . . . . . . . . .: 255.255.240.0
   デフォルト ゲートウェイ . . . . . . .:
```
この場合、DockerのIPアドレスは「172.19.48.1」となります。

## SSMSからSQLServerに接続する

SSMSを起動すると以下のポップアップが表示されます。
![スクリーンショット 2023-05-07 231608.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3339977/77cb8668-a7b0-8bb6-9d90-e92c07b9f282.png)

1. `Server name:`に先ほど調べたIPアドレス「172.19.48.1」、カンマ「,」、docker-compose.ymlで指定したポート番号「1433」を組み合わせて、`172.19.48.1,1433`と入力します。
2. `Authentication:`は、`SQL Server Authentication`を指定します。
3. `Login:`に、`sa`と入力します。
4. `Password:`に、`B!ng_2023`と入力します。
5. 最後にConnectボタンを押下します。

## テーブルを確認する

上手く接続できれば、Object Explorerに表示されます。
そうしたら、接続したDatabases>testdb>dbo.NewEmployeeを選択し、右クリックし`Select Top 1000 Rows`を選択してください。するとselect文が実行されて以下のように表示されます。
![スクリーンショット 2023-05-07 233523.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3339977/23078d71-4264-d1ea-964d-605dc826c2ec.png)
無事、SQLServerに入れたデータが確認できました。

# 最後に

自分がわかりにくいと思った部分を厚めに記載したら、思いのほか長くなってしまいました。。。なんとかまとめられて良かったです。
正直、本職ではないので（動作することは確認してますが）意味がわからず記載している部分があります。もしおかしい点があれば教えていただけると助かります。
皆さんのお役に立ちましたら光栄です。