在 Dokcer 的世界裡,他們有自己的虛擬網路 Software-Defined Networks (SDN)。 而 Container 在執行的時候預設會加入 bridge 的虛擬網路。 這個虛擬網路就能夠讓我們 Container 之間互相溝通。

下圖為 Dokcer 預設建立好的虛擬網路。

network-lsnetwork-ls

今天的範例是基於的 ASP.NET Core MVC 專案,透過 EF Core 與資料庫連接的方式來展示。展示的重點主要會是,當把 MVC 專案放到 Container 裡面去後,如何修改 EF Core 的連線字串,讓連線字串指向同樣是 SQL Server 的 虛擬網路 IP。

在後面步驟開始前,我已經先執行下方指令,把 SQL Server 執行起來了。 (如果讀者要執行,請記得修改密碼,要符合 預設密碼強度)

sql server
  • bash
1
docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=xxxxx" -p 1433:1433 --name sql1 -d mcr.microsoft.com/mssql/server

如何查詢 SQL Server 的虛擬IP?

因為如上述所說,當 Container 執行後,會自動加入 bridge 的虛擬網路,所以請執行下方指令,就可以看到加入這個虛擬網路的 Container IP。

inspect bridge
  • bash
1
docker network inspect bridge

執行後,會看到 SQL Server 的 IP,我這邊的 IP 是 172.17.0.2,如下圖。

sql-server-ipsql-server-ip

有 SQL Server IP 後,我們就可以來想辦法更改 ASP.NET Core MVC Container 裡面的連線字串啦。

修改連接字串的方法

要改變連線字串有兩種方法,一種是使用多個 appsettings.Production.json,一個是把連線字串設定成環境變數。

使用多個 appsettings.json

我們先在 ASP.NET Core MVC 專案新增一個 appsettings.Production.json,且把連線字串設定好指向 172.17.0.2 這個 IP。

appsettings-productionappsettings-production

接下來只要在啟動 Container 的時候設定環境變數 ASPNETCORE_ENVIRONMENT=Production,他就會去讀 appsettings.Production.json 的,這樣就成功切換 appsettings 啦。 而執行指令如下範例。

appsettings production
  • bash
1
docker run -e "ASPNETCORE_ENVIRONMENT=Production" -d -p 8000:80 myapp --name=prod

-e "ASPNETCORE_ENVIRONMENT=Production" 建議放 run 後面,我在練習的時放在指令的最後面,都會無效。

連線字串設定成環境變數

另一種方法是設定環境變數,要注意環境變數的優先權會比 appsettings 高,所以如果 appsettings 跟環境變數都有同樣的變數的話,會以環境變數為為主。
那要怎麼設定下方範例這種路徑的環境變數呢?

connection string
  • json
1
2
3
"ConnectionStrings": {
"Sample": "xxxx"
}

只要在設定環境變數的時候使用兩個底線 __ 就可以代表下一個階層,所以我只要設定這樣的環境變數 ConnectionStrings__Sample=Server=10.0.75.1;Database=Sample;User ID=sa;Password=xx;Trusted_Connection=True;Integrated Security=False; 就可以將連線字串整個換掉。 完整指令如下範例。

run with env
  • bash
1
docker run -e "ConnectionStrings__Sample=Server=172.17.0.2;Database=Sample;User ID=sa;Password=xxxx;Trusted_Connection=True;Integrated Security=False;" -d -p 8000:80 myapp --name=prod

搞定收工!!

延伸閱讀

[Use multiple environments in ASP.NET Core]