Deploy Rails with Docker Swarm (2) - 流程介紹與設定 Traefik & Rails
讓我們進到實際操作的部分!這篇主要會先介紹一下後續的文章架構,主要是分成以下三個部分:
- 設定 Rails & Traefik
- 設定 AWS
- 設定 Gitlab runner 自動化部署
因為篇幅的關係,這篇文會先介紹第一部分,後面兩部分也會再另外發新的文章(不知不覺就變成連載系列了)
部署流程
實作流程
- 本地端進行部署
- 開啟 rails production server
- 確認本地端 Docker compose build/up 皆可順利執行
- 手動 ssh 進入 EC2 部署
- 將 Traefik 與 Docker Swarm 直接部署在 EC2 裡,詳細的流程會在下一部分的圖裡說明
- 利用 Gitlab runner 自動部署
- 將前一步的所有設定、部署指令自動化
實際部署流程
這邊要講的是完整的部署流程上執行了哪些設定,後續的介紹也會將以下四點的順序作為主要架構進行介紹:
-
設定 Traefik Service:依照上一篇提到的 Traefik 特性,先設定 reverse proxy(再把 app 掛上去)
-
設定 Rails App Service:基本上等於在本地端部署的步驟,也就是確認 Docker compose build/up 可以順利開啟服務
-
設定 EC2 與 Route53:在確認設定檔大致完成後,設定並開啟 EC2,將剛剛設定的服務部署上去
-
自動化部署 with Gitlab Runner:註冊並撰寫 runner 的腳本(
.gitlab-ci.yml
),而腳本的內容則是實際在部署時需要對機器本身下的設定,內容如下:- 開啟 Docker Swarm
- 創建
traefik-public
的公開 Network,讓 App service 可以使用 traefik 來做 reverse proxy - 指定每次 Traefik 更新時固定使用同個節點
- 使用 docker stack 部署 Traefik
- 部署 Rails App
實際部署 Docker Swarm 的流程
Rails & Traefik Service
Traefik Service Settings
Traefik 與 Rails App 其實是兩個獨立的服務,因此這邊會將 Traefik 與 Rails App 的設定檔分開,也就是 Traefik 會有一個 traefik.yml
用於部署 traefik stack,而 Rails App 則是使用原始的 docker-compose.yml
去部署 task stack(這邊的 Rails App 叫做 Task-Manager,因此 stack name 取為task
)
首先在 traefik.yml 中的設定會與一般的 docker compose file 架構相同,這邊我是參考 dockerswarm.rocks 裡提供的 Traefik 設定範例進行設定,不過我們會需要特別設定以下幾點(這部分也可以直接參考我寫好的設定檔 traefik.yml / Task-Manager-Ruby · GitLab):
- Network:需要新增一個叫
traefik-public
的網路,並且設定為 external,好讓 Rails App 可以透過這個網路與 Traefik 溝通 - Volumes:新增一個
traefik-public-certificate
的 volume,用於存放已經申請過的憑證 - Service:分為兩部分需要注意,Command 與 Deploy Label
- Command:Traefik 的基本設定,需要指定 Docker provider、開啟 Swarm mode,憑證的申請、儲存位置,以及 DNS Challenge 等等
- Deploy Label:為了要開啟 Traefik Dashboard 而設定的 reverse proxy routing,主要有下列幾點要設定:
- 開啟 Traefik 並加入 traefik-public Network
- Dashboard 登入帳密
- Http/Https host
- Redirect middleware:當用戶使用 Http 發送請求,自動轉為 Https
- Load balancer port:當有目的地是 host 的請求,Traefik 需要將其導向的 port
- 設定 wildcard 驗證過的 domain
到這一步基本上 Traefik 本身已經設定完畢,可以先進 EC2 裡開好 Traefik stack 來檢查是否能正確開啟。
Rails App(Application) Service
接下來要說明的是 Rails App 要怎麼設定,當然這個部署架構不只限定於 Rails App,不過這個步驟可能要依照使用的語言或框架而改動。
首先必須生成一組 RAILS_MASTER_KEY
,因為 Rails 在 Production 環境中需要有 RAILS_MASTER_KEY
才能啟動,確定 production server 可正常開啟後,可以來準備我們的 Dockerfile 與 Docker-compose file 來進行 task stack 的設定。
Dockerfile
這部分我使用的是 這個 gem 來幫我自動生成,他會依據專案中的 Gemfile 以及 boxing 本身的設定檔(config/boxing.rb
)來自動生成 Dockerfile。另外這個 Gem 的作者(也就是蒼時大大)有特別研究如何生成最小化的 Docker image,因此自動生成的映像檔大約只會有(據他本人所說) 100 MB,下面列出可以另外設定的選項(粗體為我這次有採用的設定):
- Source Code Root
- Ignore File
- Extra Packages: Node.js & Python
- Revision Information
- Sentry Support
- Asset Precompile: True
- Health Check
補充: OpenBox - Auto generate entrypoint settings,如果將 Boxing 與 OpenBox 同時採用的話,Boxing 生成的 Dockerfile 會將 Entrypoint 自動指定為 OpenBox 生成的 Entrypoint
Docker-compose file
與在本地端設定的 docker-compose.yml
基本上一樣,我在這邊是只有設定三個 service(app/redis/postgres),Network 只有 net 讓三個 service 共享,並加上下面兩項設定:
-
RAILS_MASTER_KEY
:剛剛生成的RAILS_MASTER_KEY
可以先放到 Gitlab 中設定為 CI variable(如果要跑本地測試的話可以將RAILS_MASTER_KEY
放在 .env、或者設定為 app service 的 environment var,可以參考本地端的 docker-compose Line 55) -
DATABSE_URL
:在 app service 的 environment variable 要特別指定資料庫的路徑,才能正確連線到 postgres service,並且要注意格式為postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...]
做完基本的設定後,在把 Traefik 相關的 routing rules 加到 deploy label 上。這部分和在設定 Traefik 的 deploy labels 一樣,設定完畢後會像這個檔案類似。
補充
Load Balancer Port 設定
假設今天我們的 domain 是
abc.dev
有用戶請求了traefik.abc.dev(aka 我們的 host name)
,而我們的 Traefik Dashboard 開在 8080 port,則 Traefik 會將這個 request 導向 8080Wildcard 相關知識
相關設定的補充知識,需要參考我已經寫好的設定檔
- Wildcard:ACME 驗證方式 - Let’s Encrypt - 免費的 SSL/TLS 憑證 (letsencrypt.org)
- 可以直接申請某個 domain 的憑證,讓整個 domain 下的所有 host 都可以使用同一張憑證(domain.sans 部分),不需特地為所有 host 個別申請憑證
- 屬於 Let’s Encrypt 發放的其中一種憑證格式
- 給予 route53 權限的原因
- 因為設定 DNS challenge 與 DNS Challenge Provider 為 route53
- DNS challenge:需要有 route53 的權限才能動態驗證 *.domain 下的所有 host
- Route53 提供自動更新憑證的 API
第一部分就到這邊結束,其實做到這個步驟應該就能在本地端進行部署(僅限 Rails 部分)。希望大家與 Docker 可以好好相處,他真的是個好用ㄉ酷東西(
想要閱讀更多來自五倍紅寶石軟體開發的技術分享?歡迎訂閱我們的月報,每月將自動幫你送上最新文章。