---
title: "Ruby on Rails 容器化最佳指南（一）"
date: 2021-10-09T00:00:00+08:00
publishDate: 2021-10-09T19:49:13+08:00
lastmod: 2022-01-17T14:20:52+08:00
tags: ["Docker","容器","Ruby","Rails","經驗","DevOps"]
toc: true
permalink: "https://blog.aotoki.me/posts/2021/10/09/the-best-practice-of-containerize-ruby-on-rails-part-1/"
language: "zh-tw"
---


今年 COSCUP 的時候前同事 Cindy 分享了 [Rails 容器化最佳實踐](https://coscup.org/2021/zh-TW/session/VHSKGW) 這場演講，裡面提到我們在五倍紅寶石在將 Ruby on Rails 專案轉換為容器的一些技巧。

這系列文章會分享一下這個容器化的過程是怎麼判斷、處理以及在過程中需要注意哪些事情。

<!--more-->

## 目的{#target}

五倍紅寶石在多年的接案經驗中大致上經過了完全沒有測試環境、使用單一伺服器把所有測試環境放到裡面、使用 KVM 虛擬化技術搭建測試環境到這幾年利用 [Proxmox VE](https://www.proxmox.com/en/proxmox-ve) 管理虛擬機和目前最新的使用容器化技術來搭建測試環境。

這個過程中主要就是從沒有測試到有測試，從人工管理環境到自動化管理環境的一個過程，也因此我們進行容器化是為了要能在將專案轉交給客戶之前，確實的驗證能夠正常運作、部署。

## 用途區分{#usage}

我自己是在 Docker 剛推出時就接觸容器化技術，不過當時的疑惑是「能拿來做什麼？」

不過這幾年容器化技術成熟後，我們大致上可以將用途區分為「開發」跟「部署」兩種情境，前者是為了解決許多開發環境搭建的問題，因為相對虛擬機輕巧跟容易配置，某方面來說是一個很不錯的選項。

至於後者的部署最有名的應該就是 [Kuberentes](https://kubernetes.io/) 這套調度系統，以及像是 Microservice 這類應用，大多都跟容器化技術的成熟有所關聯。

在製作容器的時候，會隨著目的、用途有著很大的差異，像是將開發用途的容器化處理直接套在部署的情境上，雖然不會出太大的問題，但是像是資安、部署速度等等都會受到影響。

## 最佳實踐{#best-practice}

既然五倍紅寶石的目的是要用在測試環境，因此我們希望打造的容器必然是要接近正式環境，或者說可以直接被應用在正式環境的設計更符合我們的預期。

在我們開始之前，先談談有哪些東西會影響到部署用的容器。

### 大小{#size}

部署用的容器大小基本上應該要盡可能的越小越好，首先我們會進入到這一個階段表示 CI/CD 已經接近成熟，可以自動的產生可以部署的容器，也因此部署的頻率會越來越高。

如果大小過大的話，部署的速度會變慢也會造成大量的流量費用，不論是從測試環境的效益或者正式環境影響服務拓展的角度來看，容器過大都是問題。

> Ruby 專案的容器大小根據製作者的技巧，可以從 200MB 左右到 2GB 都有可能，處理做得好是能節省十倍以上的大小。

### 套件{#package}

在正式環境會有很多套件不需要使用到，像是用來編譯 Ruby C Extension 的套件，因此需要利用像是 Multi Stage 這類技巧去清除掉多餘的套件。

除此之外，在套件上也會需要更精細的安裝。如果直接安裝某些套件，會把像是 C 的 Header 和一些輔助的工具安裝進去，這些都會嚴重影響到最後產生的容器大小。

除此之外，Ruby 專案本身的套件也要稍微注意。像是我們原本在虛擬機上會使用 [Passenger](https://www.phusionpassenger.com/) 來作為 Rails 的 Web Server，不過光是要運行 Passenger 就會產生約 1G 的空間消耗，因此目前大多會以 Puma 為主，雖然功能沒有 Passenger 豐富但是能夠透過其他容器的特性補足。

### 安全性{#security}

最後一塊是比較難處理的部分，大致上分為兩大部分。第一塊是專案本身跟 Linux 可以處理的安全性問題，在處理容器時需要注意檔案權限、執行權限等等問題來避免容器被攻擊時讓攻擊者很容易能取得更高的權限。

另一塊主要是容器的掃描，目前存在的掃描大多整合在雲端或者 SaaS（Ex. AWS ECR、Synk）上，想要自己運行掃描服務架設上並不容易，不過如果已經有 Kubernetes 環境倒是會容易些。

這三塊處理完畢後，大致上就能讓 Ruby on Rails 容器化調整到一個相當不錯的狀態。

## 小結{#conclusion}

這篇文章大致上介紹了我們在製作 Ruby 容器關注的一些重點，如果是開發用的容器就會相對的寬鬆一些，畢竟是以快速搭建環境為前提所規劃。

下一篇會開始說明我們目前所使用的方式以及 Dockerfile 撰寫會怎樣處理。

