uncategorized

開始建立SQL Server for Windows Containers

有了Docker這項技術後,想要把SQL Server也放入到Docker中,自從SSMS 2016開始,管理工具與DB可以分開安裝後,就沒有在自己電腦安裝DB,但是,有時候在開發專案,並不可能隨時與DB連線,如果手邊沒有SQL Server也很不方便,所以,可以用Docker建立SQL Server,如果中間被搞壞了,也不用太害怕。此外,或許可以透過這樣方式解決一些實務上遇到SQL測試的另一種問題

此外,這篇實作環境在Windows10搭配docker for windows,並啟用Windows Container

安裝SQL Server Containers


要安裝SQL Server,可以到Docker Store找到安裝指令,不過,如果在Docker Store開始找,可能只會找到mssql-server-windows-express這個Image,此時,不需要太緊張,因為,在這個image的文件中,有包含到SQL Server for Windows Containers的資訊,只要點擊它就可以找到mssql-server-windows,如果不想要找,也可以執行下面指令就可以開始安裝了

1
docker run -d -p 1433:1433 -e sa_password=<SA_PASSWORD> -e ACCEPT_EULA=Y microsoft/mssql-server-windows

如果是第一次,會需要一段時間下載相關性的image,這段時間會比較久一點,之後就不會了,如果下載完畢,就會開始解壓縮,並啟動Containers,之後每次要建立SQL Server Containers,只要重複執行這段指令就可以,另位,預設是透過SQL帳號進行登入,且帳號是用sa,所以,會透過sa_password設定sa密碼

SSMS連線SQL Server Containers


使用docker run指令後,可以透過docker ps確認這個Container是否有啟動,若是有啟動成功,就會出現如下圖的資訊

但是,這樣不代表就可以讓SSMS連入,我們還必須要知道這台在Containers內的SQL Server的IP位置才行,所以,必須使用下面指令查詢SQL Server IP

1
docker inspect --format "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" ff04d07c4b51

其中,ff04d07c4b51是代表你啟動這個Container的ID,用先前的docker ps就可以找到資訊,有了IP之後,就可以開心用SSMS連入了

如果,今天你忘記sa密碼,還可以用docker exec指令加入新的sa密碼

1
docker exec -it <DOCKER_CONTAINER_ID> sqlcmd -S. -Usa

網路問題?


如果在SSMS中紀錄這次建立的Container的IP,若是移除這個Container後,重新建立時候,就有可能下次就無法登入,要做這測試很簡單,只要你把剛剛建立的Container移除,移除指令如下

1
2
docker stop ff04d07c4b51
docker rm ff04d07c4b51

然後,再建立一個新的Container,會發現SQL Server網路位置變了,這主要是因為在Windows Container內的網路是透過NAT方式進行對外公開,所以,會導致每次重建後,IP位置會有所變更,想要指定IP給SQL Server,就必須給予這個Container固定IP

1
docker run --ip 172.20.1.10 -d -p 1433:1433 -e sa_password=<SA_PASSWORD> -e ACCEPT_EULA=Y microsoft/mssql-server-windows

這時候會很好奇,為什麼要給172.20.1.10,主要是Container內是透過NAT方式轉換IP,預設都會啟動NAT,又或是可以透過docker network ls查詢目前網路配置,就可以看到有啟動NAT了,不過,這樣依舊無法知道NAT配置IP範圍,所以, 要知道IP的分配範圍

1
docker network inspect nat

這樣就可以知道了IP範圍,就可以啟動Container時候去指定IP,指定的IP必須在NAT範圍內,不然會發生錯誤

匯入資料


到這一步,還不能高興太早,因為,我們還沒有把資料匯入進去,因此,就必須讓Container能讀取外部資料夾或是檔案,才可以把DB還原到Container的SQL Server裡面。把資料匯入SQL Server有兩種方式,一種就是用掛載mdf檔案,另一種就是直接匯入備份檔,我比較習慣用匯入備份檔方式進行,所以,必須把正式區DB備份下來,這裡假設是放到E:\DB下面,然後,我們需要透過資料夾mapping方式,將Container內的資料夾與外部資料夾連結起來,如果有用過VM人大概可以了解這意思。

1
docker run -it --ip 172.20.1.10 -d -p 1433:1433 -e sa_password=<SA_PASSWORD> -e ACCEPT_EULA=Y -v e:/DB/:c:/DB/ microsoft/mssql-server-windows

我們把Container內的c:\DB對應到E:\DB,就可以在SQL Server還原DB時候找到這個備份的DB檔案

以上就可以把SQL Server Container建立起來,並匯入我們想要的DB,如果想要一氣呵成的話,也是可以,不用每次要建立Container都花這樣多工,整個指令如下,其中有一點不同的是,在這邊我們指定了Container Name,讓後續操作可以直接使用Container Name而不是用Container ID

1
2
3
docker run -it --name SQLTest --ip XXX.XXX.XXX.XXX -d -p 1433:1433 -e sa_password=<SA_PASSWORD> -e ACCEPT_EULA=Y -v e:/DB/:c:/DB/ microsoft/mssql-server-windows
docker exec SQLTest SqlCmd -E -S XXX.XXX.XXX.XXX -Q "RESTORE DATABASE [DEV_EAS] FROM DISK = N'C:\db\XXX.bak' WITH FILE = 1, MOVE N'XXX' TO N'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA\XXX.mdf', MOVE N'XXX_log' TO N'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA\XXX_log.ldf', MOVE N'XXX_mod1' TO N'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA\XXX_mod1', NOUNLOAD, STATS = 5"

第二個步驟主要是透過SqlCmd做還原DB的動作,從"Restore XXXXX"這一段就是SQL中還原DB指令,這樣我們就可以很快啟動一個具有資料的SQL Server Container了