如何使用 Docker 建立 .NET Core + PostgreSQL 開發環境 ?
當使用 .NET Core 之後,server 就不見的要使用 Microsoft 技術,可自由選擇 Linux 受歡迎的 service,如 Nginx、Redis、PostgreSQL … 等。
以 PostgreSQL 而言,透過 Docker,我們可以很輕鬆的在 Windows 或 macOS 建立 .NET Core + PostgreSQL 開發環境,且重點是 Linux 版的 PostgreSQL 的。
Version
macOS High Sierra 10.13.4
Docker for Mac 18.03-ce-mac65 (24312)
.NET Core 2.1
PostgreSQL 10.3
DataGrip 2018.1.4
建立 Docker Compose
docker-compose.yml
1 | version: "3" services: netcore: image: microsoft/dotnet container_name: MyNETCore volumes: - ${NETCORE_HOST_DIR}:/code/ tty: true networks: - netcore-dev depends_on: - postgres postgres: image: postgres container_name: MyPostgres volumes: - ${POSTGRES_HOST_DIR}/data:/var/lib/postgresql/data expose: - "5432" ports: - "${POSTGRES_PORT}:5432" environment: - POSTGRES_DB=${POSTGRES_DB} - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} networks: - netcore-dev networks: netcore-dev: |
第 1 行
1 | version: "3" |
version
為 docker-compose.yml
的第一層 tag,用來設定 docker-compose.yml
格式的版本。
因為 docker-compose.yml
的格式版本與 Docker 版本息息相關,若你要使用新版的 Docker 所提供的功能,在 docker-compose.yml
的版本就必須下的更細,如 3.3
,在此只使用了 docker-compose.yml
基本功能而已,使用 3
即可。
第 3 行
1 | services: netcore: postgres: |
services
為 docker-compose.yml
的第一層 tag,用來設定有哪些 service 要一起跑。
以本文為例,要同時跑 .NET Core
與 PostgreSQL
兩個 service,因此在 docker-compose.yml
內建立 netcore
與 postgres
兩個 service。
31 行
1 | networks: netcore-dev: |
networks
為 docker-compose.yml
的第一層 tag,用來設定 container 間所共用的網路名稱。
以本文為例,我們希望 netcore
與 postgres
兩個 container 都跑在相同的網路下,彼此都能看到對方,因此特別宣告了 netcore-dev
網路,將來兩個 container 都將共用此網路。
第 4 行
1 | netcore: image: microsoft/dotnet |
設定 netcore
service,此名稱可自行建立。
使用 image
設定使用 microsoft/dotnet
image。
第 6 行
1 | container_name: MyNETCore |
使用 container_name
設定 netcore
service 的 container 名稱為 MyNETCore
。
第 7 行
1 | volumes: - ${NETCORE_HOST_DIR}:/code/ |
使用 volumns
設定 Host OS 與 container 所共享目錄,將來 Host OS 所分享的目錄,相當於 container 內部的 /code
目錄。
由於每個人 Host OS 要分享的目錄都不一樣,因此設定成 NETCORE_HOST_DIR
變數,稍後自行在 .env
設定。
第 9 行
1 | tty: true |
Docker 為了節省硬體資源,app 執行完就會釋放 container,但處於開發階段,我們需要的是類似 service 跑在背景,隨時可以進入 container 測試 Linux app。
tty: true
將令 Docker 分配一個 TTY (T
ele TY
pewriter),綁定到 container 的 stdin
與 stdout
上,將來我們才能透過 Bash 對 container 下指令,由於 tty
在背景持續執行,因此 container 就不會被釋放。
10 行
1 | networks: - netcore-dev |
使用 networks
設定 container 所要使用的網路名稱。
由於之前已經建立了 netcore-dev
網路,現在 netcore
container 將使用 netcore-dev
網路。
12 行
1 | depends_on: - postgres |
使用 depends_on
設定 container 的啟動順序。
我們希望 postgres
container 先啟動後,netcore
container 再啟動,如此 .NET Core 才能使用 PostgresSQL。
15 行
1 | postgres: image: postgres |
設定 postgres
service,此名稱可自行建立。
使用 image
設定使用 postgres
image。
17 行
1 | container_name: MyPostgres |
使用 container_name
設定 postgres
service 的 container 名稱為 MyPostgres
。
18 行
1 | volumes: - ${POSTGRES_HOST_DIR}/data:/var/lib/postgresql/data |
使用 volumns
設定 PostgreSQL 所儲存的資料到 Host OS。
我們不希望 PostreSQL 將資料存在 container 內部,如此 PostgreSQL 將來要更新版本時會很麻煩,無法簡單換掉 container 就更新版本,因此特別使用
volumns
指定 Host OS 目錄,如此 PostgreSQL 會將資料存在 Host OS,而不是 container 內
20 行
1 | expose: - "5432" |
PostgreSQL 將以 port 5432 對外溝通。
注意這只是對
netcore-dev
網路以 port 5432,若要讓 Host OS 存取,必須進一步靠ports
設定
22 行
1 | ports: - "${POSTGRES_PORT}:5432" |
使用 ports
設定 Host OS 與 container 的 port 對應。
由於每個人 Host OS 所希望的 port 不同,因此設定成 POSTGRES_PORT
變數,稍後自行在 .env
設定。
24 行
1 | environment: - POSTGRES_DB=${POSTGRES_DB} - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} |
使用 environment
設定 PostgreSQL 所需的環境變數。
- POSTGRES_DB: 要使用的 database,container 在建立時,會幫我們自動建立
- POSTGRES_USER:連進 PostgreSQL 的
user
- POSTGRES_PASSWORD:連進 PostgreSQL 的
password
由於這 3 個變數每個人的需求不同,因此統一使用變數在 .env
設定。
28 行
1 | networks: - netcore-dev |
使用 networks
設定 container 所要使用的網路名稱。
由於之前已經建立了 netcore-dev
網路,現在 postgres
container 將使用 netcore-dev
網路,如此 netcore
與 postgres
都在相同的 netcore-dev
網路下,可以彼此看到對方。
.env
1 | NETCORE_HOST_DIR=~/Code/CSharp |
所有 Host OS 自行設定的部分,全部放在 .env
。
- NETCORE_HOST_DIR : 設定 Host OS 的 .NET Core 專案所在目錄
- POSTGRES_HOST_DIR : 設定 PostgreSQL 將資料存到 Host OS 的目錄
- POSTGRES_DB : 設定 PostgreSQL 所使用的資料庫名稱
- POSTGRES_USER : 設定 PostgreSQL 連線的 user
- POSTGRES_PASSWORD : 設定 PostgreSQL 連線的 password
- POSTGRES_PORT : 設定 PostgreSQL 對應到 Host OS 的 port
執行 Docker Compose
1 | ~/PostgresCore $ docker-compose up -d |
進入 docker-compose.yml
所在的目錄,執行 docker-compose up
啟動所有 container。
- -d:
d
etatch,表示docker-compose
啟動後將離開 container 的 process,讓 container 在背景執行
連接 PostgreSQL
開啟 DataGrip:
- 右側選擇
Database
tab - 上放按
+
新增連線 - 選擇
Data Source -> ProgreSQL
- Name:設定 connection 連線名稱
- Database:設定剛剛所建立的 database
- User:設定剛剛所建立的 user
- Password : 設定剛剛所建立的 password
- 按
Test Connection
測試連線是否成功 - 顯示
Successful
確認連線成功 - 按
OK
建立連線
- 顯示剛剛所建立的 database
結束 Docker Compose
1 | ~/PostgresCore $ docker-compose down |
進入 docker-compose.yml
所在的目錄,執行 docker-compose down
結束所有 container。
Conclusion
- 透過 Docker,我們可以很輕易在本機建立 .NET Core + PostgreSQL 環境,重點是跑的是 Linux 版本的 PostgreSQL,與 production 的 Linux 版本一致。
Sample Code
完整的範例可以在我的 GitHub 上找到