記得在第十五天的時候我有提過,目前 NOJ 有其中一個問題是我們會把一些機敏資料,像是 JWT 使用的 secret、沙盒的 token 等等放在 docker compose 的設定檔裡面,導致了我們沒辦法將這些 config 公開,因此導致管理困難,雖然還有一部分是根本沒有寫這些設定的文件啦...那又是另外要處理的問題了。
接下來就稍微介紹一下有關在 docker 裡面如何管理這些機敏資料吧。
首先第一個做法是環境變數,不管是不是使用容器部署服務,這其實都是一個常見的設定手法。以 docker compose 來說,有兩種方式可以設定容器的環境變數。
environment
(文件):docker-compose.yml
裡面,但若是透過 docker compose 的變數替換,則可以不需在裡面直接明文寫入這些設定,不過問題會變成 host 上面的環境變數要怎麼設定。env_file
(文件):docker-compose.yml
裡面,相對於 environment
應該算是更適合儲存這些機敏資訊的選項,不過需要注意不要不小心提交這些檔案進版控。docker 還提供了另一種管理設定的方式,稱之為 secret,也是可以透過基於檔案的方式,把設定注入到容器裡面。那麼他跟 env_file
這個 docker compose 裡面的 section 有什麼差別呢,就我目前查到的主要有兩點。
docker secret create
這個命令去創建的 secret,之後使用 docker secret inspect
檢視 secret 資訊的時候,並不會將當初設定的值顯示給使用者。不過需要注意的是,透過這種方式創建 secret 只有在 docker swarm mode 支援。綜上所述,secret 應該是比起環境變數更加安全的選項,不過若是選擇透環境變數設定容器的話,也是可以設計成支援透過 secret 去設定服務(從指定路徑讀取檔案內容,因為 docker 的 secret 會被掛載到 /run/secrets
這個資料夾底下),我想在需要擴展的時候會更好。像是有些 image(例如 MySQL)可能會有像是 PASSWORD
與 PASSWORD__FILE
這樣兩個環境變數都可以去設定 PASSWORD
的,只是帶 FILE
後綴的是從檔案讀。
還有一種常見的做法是透過 volume 掛檔案進去容器,例如說服務可能需要一個叫做 config.json
的檔案去設定,那就可以把這個檔案透過 volume 掛進去。
今天統整了幾種管理機敏資料的方式,除了上述幾種之外,也有像是 Vault 這種專門的服務,不過以我的例子來說應該是不需要用到這種複雜的東西,先使用 env file 把那些設定從 docker-compose.yml
裡面分出來就好。
另外,我覺得 docker 官方文件有關安全性的部分(這裡)值得一讀,至少在我當初不熟悉 docker 時從裡面了解到不少設計上需要注意的部分。