以 Docker Compose 建立 Node.js 全端開發環境(三) — 資料庫與 Prisma 配置

Toki Lee
8 min readSep 1, 2022

--

在前兩個章節,我們建立了開發用的容器與基礎的配置,但目前兩個容器間還沒有實質互動,在實作一些功能之前,為了要能夠儲存資料,我們會需要加入資料庫的容器並建立與後端服務的連結。

這邊先附上上個章節與這個章節目標的樣子:

上個章節結尾

這個章節目標

資料庫

在這邊我選用 PostgreSQL 作為資料庫,我們可以先看看官方 Docker Image 的說明:

在文件中有提到 Environment Variables 的部分,而這邊我們會需要使用到其中三個環境變數:

  1. POSTGRES_USER:預設的 Super User 名稱。
  2. POSTGRES_PASSWORD: Super User 的密碼,另外可以看照文件中 Note.1 的說明:如果是在容器內連接時不會詢問密碼,也就是說之後進到容器內執行 psql 就不需用帶入密碼了(如果是在本機或其他機器連接時就會需要了,但在這邊我們並不會對外開啟 Port)
  3. POSTGRES_DB:預設的 DB 名稱。

將這幾個環境變數與容器加到配置檔:

docker-compose.yml

可以注意下 volumes 的部分,與之前將專案目錄 bind 到容器的方法不同,這邊的寫法會讓 docker 幫我們自動建立與管理這個 Volume,如果一開始沒有的話, docker 則會自動建立起來。

那們我一樣將容器重新跑起:

可以看到它自動幫忙建立了my-project_postgres-store 的 Volume,而新增的容器也順利啟動:

postgres 順利啟動

為了確認環境變數有順利設好,我們進到容器執行 psql 確認看看:

# 以容器執行 psql 指令
docker compose exec postgres psql -U backend
# 列出所有 db
\t
可以看到名為 backend 的 Table 確實建立好了

最後若我們想要把 Volume 刪掉的話,可以執行 docker compose down -v ,這樣的話 docker 就會在移除容器時將自動建立的 Volume 刪掉了:

到目前為止都還順利,然而這邊有個問題,資料庫的配置是屬於比較機敏的部分,一般來說是不該進入版本控管的,也就是說不該直接寫在 docker-compose.yml 之中。

千萬不要把資料庫的帳密資訊寫進 Repo 之中

不過幸好 Docker Compose 提供了一種配置方式,使用者可以在放置 docker-compose.yml 的目錄下加入 .env 檔案,再將這個檔案名稱寫入 .gitignore 之中,這樣的話專案 pull 下來後再配置好 .env 執行 docker compose up 時,這些 Secret 的環境變數就會自動帶入了。

那麼現在我們就加上 .env 並修改 docker-compose.yml

.env
docker-compose.yml

通常我會再加入一個 .example.env 做為範本,這樣下個使用者 pull 下來時就能很直覺的明白要複製一份並調整環境變數了。

Prisma 設置

後端的部分,我這邊會使用 Prisma 作為類似於 ORM 的工具來協助我們快速的建立 api,而關於 Prisma 是不是 ORM 這在官方有篇文章說明,這邊不會深究,主要來說 Prisma 提供了以下的功能:

  1. Prisma Client:自動生成 query builder 與 TypeScript 型別。
  2. Prisma Migrate:升級與更動資料庫架構的工具。
  3. Prisma Studio:可以查看並編輯資料庫的 GUI 介面。

那現在先讓我們加入要用到的依賴:

apps/backend/package.json

Prisma 有屬於自己 Schema 的語法,藉由編寫 Prisma Schema 的檔案,能夠讓 Prisma Client 為我們建立好 query builder 與相關的型別:

apps/backend/prisma/schema.prisma

這樣的內容將協助我們在資料庫中建立一個儲存 Todo 資料的 Table,現在我們先進到 backend 中執行 migrate 的指令:

# 進到容器中
docker compose exec backend bash
# 如果還沒有安裝依賴,記得要安裝下
yarn
# 執行 migration
yarn prisma migrate dev

執行後會看到:

這是因為我們還沒有為 backend 的容器設置 DATABASE_URL 的環境變數,而這個環境變數則是寫在 Prisma Schema 中datasource url 之中,現在我們就回過去 docker-compose.yml 中添加這個環境變數:

docker-compose.yml

這邊比較要注意的是 @postgres:5432 這邊,雖然 postgres 我們沒有 Mount 到本機的 Port ,但我們可以像這樣直接使用 service 的名稱在 url 中,因為預設上 Docker Compose 會自動建立一個 network ,讓容器間可以藉由 service 的名稱找到對應的容器。

現在我們再次重新跑起,重複剛剛的行為後我們會看到:

在這邊我們可以隨便輸入個戳記名稱並按下 Enter,這樣 Prisma 就會幫我們建立好新的表了:

我們可以進到 postgres 的容器中確認下 migration 之後的改變:

# 以容器執行 psql 指令
docker compose exec postgres psql -U backend
# 列出所有 Table
\dt
# 顯示 Table Schema
\d "Todo"
Todo 的 Table 順利建立

確認無誤後,最後我們再調整一次 docker-compose.yml 的配置:

這樣 Prisma 與資料庫的部分就配置完成了。

Prisma Studio

Prisma 還提供了個方便工具 — Prisma Studio,我們可以修改置加入這個功能:

apps/backend/package.json
docker-compose.yml
Prisma Studio 的 GUI 介面

這樣的話我們就不需要設置像是 pgAdmin 之類的 GUI 介面,可以直接使用 Prisma Studio 的 GUI 介面來協助我們的開發。

總結

在這個章節我們加入了資料庫的容器並配置了 Prisma 作為與資料庫溝通的中間層,而下一個章節我們將開始實做一個 Todo List 的功能。

--

--

Toki Lee

沒有技術上不可行,只是時間上做不到⋯