iT邦幫忙

2025 iThome 鐵人賽

DAY 7
0
Modern Web

Golang x Echo 30 天:零基礎GO , 後端入門系列 第 7

Go 應用程式設定管理:12-Factor 原則的簡單版

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20250921/20178818gcmvmmx4Sl.png

大家好!前幾篇我們已經把路由、中介層、API 都玩過一輪,程式碼開始有點專業的味道了。
但是專案越長越大,新的問題來了:我的程式要怎麼知道自己現在跑在「家裡測試」還是「正式上線」?

這就是今天的主角──程式的設定管理。

為什麼要分環境?

想像你開了一間珍珠奶茶店:

開發環境(Dev):在家亂調配,糖跟冰都隨便抓。

測試環境(Stage):請朋友來喝,開始用量杯量糖,但偶爾還是亂加。

正式環境(Prod):真的開始賣錢,每一杯都要精確計算,還要記錄供應商。

如果「糖量」=資料庫密碼,「冰塊」=快取設定,「供應商」=API Key,你把這些東西寫死在程式碼裡,那切換環境時就超麻煩,還可能一不小心把秘密配方洩漏出去。

12-Factor 原則:設定要獨立!

Heroku 提出了一套軟體開發準則,叫 12-Factor App。
其中一個重點就是:程式的設定不能跟程式碼綁死,要分開!

像是:

🔑 資料庫帳號密碼

🗝️ API Key

🌐 伺服器 IP 與 Port

🐞 除錯模式開關

這些都不能直接寫在程式碼裡,而是要從外部讀取。

最好用的方法:環境變數

12-Factor 推薦的做法就是:環境變數。

比喻一下:程式碼就像 SOP(流程表),永遠長一樣。
但真正的數據(糖、冰、供應商)要等老闆(環境變數)在開店前給。

程式碼只會問:「DB_HOST 在哪?」
而環境在啟動時給答案:

Dev:DB_HOST=127.0.0.1

Prod:DB_HOST=prod.db.com

程式碼本身完全不用改!

/images/emoticon/emoticon35.gif

Go 的好幫手:Viper 套件

雖然我們可以用 os.Getenv() 直接讀環境變數,但寫久了很亂。
這時候就需要一個「總管」── Viper!

它能:

✅ 讀環境變數 🌍
✅ 讀設定檔(json、yaml、toml、env 都行)📂
✅ 設定預設值 ⚙️

🚀 超方便。

  1. 安裝
go get github.com/spf13/viper
  1. 建立設定結構
package config

type Config struct {
    ServerPort string `mapstructure:"SERVER_PORT"`
    Database   DBConfig
}

type DBConfig struct {
    Host     string `mapstructure:"DB_HOST"`
    Port     string `mapstructure:"DB_PORT"`
    User     string `mapstructure:"DB_USER"`
    Password string `mapstructure:"DB_PASSWORD"`
    DBName   string `mapstructure:"DB_NAME"`
}

  1. 寫一個載入設定的函式
package config

import (
    "log"
    "github.com/spf13/viper"
)

func LoadConfig() (config Config, err error) {
    viper.AddConfigPath(".")
    viper.SetConfigName(".env")
    viper.SetConfigType("env")
    viper.AutomaticEnv()

    err = viper.ReadInConfig()
    if err != nil {
        log.Printf("找不到 .env,改用環境變數: %v", err)
    }

    err = viper.Unmarshal(&config)
    return
}

  1. 建立 .env 檔
SERVER_PORT=8080
DB_HOST=localhost
DB_PORT=5432
DB_USER=test_user
DB_PASSWORD=test_password
DB_NAME=todo_db_dev
  1. 在 main.go 使用
cfg, err := config.LoadConfig()
if err != nil {
    log.Fatalf("載入設定失敗: %v", err)
}

log.Printf("資料庫主機: %s", cfg.Database.Host)
log.Printf("伺服器埠號: %s", cfg.ServerPort)

部署到正式環境

上線時,不需要 .env 檔!
只要在伺服器輸入:

export DB_HOST=prod.db.super.com
export DB_USER=prod_user
./your_go_app

程式會自動讀這些設定,比較安全。

總結

❌ 不要把密碼寫死在程式碼裡。

🌍 用環境變數管理設定。

🛠️ 用 Viper 幫你統一管理。

這樣你的程式就能:

🔒 更安全(密碼不會外洩到 GitHub)

⚡ 更方便(切環境只要改變變數)

🏆 更專業(符合業界標準 12-Factor)


上一篇
統一 API 回應與錯誤處理:從概念到一步一步打造
下一篇
請求參數驗證:資料對不對,先打個分數!
系列文
Golang x Echo 30 天:零基礎GO , 後端入門8
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言