---
title: "Rails 部署實踐 - 伺服器搭建"
date: 2022-03-11T00:00:00+08:00
publishDate: 2022-03-11T00:00:00+08:00
lastmod: 2025-10-19T10:51:10+08:00
tags: ["Rails","教學","部署","實作","Rails 部署實踐","VPS","Docker"]
series: "rails-deployment-in-practice"
toc: true
permalink: "https://blog.aotoki.me/posts/2022/03/11/rails-deployment-in-practice-setup-server/"
language: "zh-tw"
---


要將網站使用容器技術部署，就需要有可以運行容器的伺服器。要滿足可以提供其他人連上使用、隨時提供服務以及能夠運行容器，選擇雲端服務上的 Linux 伺服器會是最適合的選項。

<!--more-->

## 建立虛擬機器{#create-virtual-machine}

雲端服務得以實現原因之一是因為虛擬化技術，我們現在可以很輕鬆的在雲端服務上建立一個虛擬機器來使用，跟容器技術不同的地方在於虛擬機器有更好的隔離性，並且會完整的模擬一台真實的電腦環境。

這次我們會使用 [DigitalOcean](https://m.do.co/c/55a8b594beba) 來做為範例，如果你想使用其他雲端服務也完全沒有問題，在文章中所有關鍵字都會提供對應的說明來協助大家找到正確的設定。

在 DigitalOcena 中，一台虛擬機器的單位叫做 Droplet（AWS 則叫做 EC2）在大多數的狀況下我們都可以一個月 5 美元的方案來架設伺服器並且足夠一些簡單的服務使用。

下圖是 DigitalOcean 的建立畫面：

![New Droplet](images/2022-03-11-rails-deployment-in-practice-setup-server/digitalocean-new-droplet.png)

在這張圖片中，我們需要注意這些項目。

| 項目           | 說明                                                                                            |
| -------------- | ----------------------------------------------------------------------------------------------- |
| Image          | 伺服器的基礎鏡像，推薦使用 Ubuntu，在這次範例中也可以用 Marketplace 的 Docker 鏡像              |
| DataCenter     | 在台灣通常推薦使用 Signapore（新加坡）會比較順暢，沒有日本選項是 DigitalOcean 比較可惜的地方    |
| VPC            | 在標準的網路規劃中是需要設定虛擬私人網路（Virtual Private Cloud）因為篇幅關係我們可以使用預設值 |
| Authentication | 建議使用 SSH Key 的方式登入，比較不容易被暴力破解嘗試密碼，同時也建議使用比較新的 ED25519 格式  |
| Hostname       | 這台伺服器的名稱，我自己習慣用部署後會使用的網域名稱來設定，方便辨識                            |
| Tags           | 在 DigitalOcean 或者 AWS 都有特殊用途，像是 DigitalOcean 可以透過 Tag 統一設定防火牆            |

每個雲端服務廠商都提供了不同的設定，最重要的是我們要確定鏡像、資料中心、認證方式這三個項目都在正確的設定上，才能夠順利地進入伺服器。

> Ubuntu 應該已經成為主流部署的 Linux 發行版本，在過去還是會有選用像是 CentOS 這類發行版本的狀況，然而目前有著容易入門、開源社群穩定等等特性的發行版本是 Ubuntu 如果有偏好的發行版本也可以自己調整選用。

## 安裝 Docker {#setup-docker}

伺服器建立完成後，可以看到像是下圖這樣的畫面。

![Dashboard](images/2022-03-11-rails-deployment-in-practice-setup-server/digitalocean-droplet-dashboard.png)

在這個畫面中 `139.59.106.82` 就是分配給我們的 Public IP（公開位址）我們可以透過這個位址連上伺服器，開啟你習慣的命令工具來操作，如果是 Windows 的話可能需要透過 [MobaXterm](https://mobaxterm.mobatek.net/) 這類軟體協助連線。

```bash
ssh root@139.59.106.82
```

在正常的狀況下，雲端服務的設定不會加入任何「防火牆」的設定因此我們可以直接連上這台伺服器，在正式環境中會推薦透過雲端服務的防火牆直接將連線限制在我們平常工作的環境中，或者採用堡壘主機（Bastion）的方式，礙於篇幅的關係我們暫時不會詳細討論這些技巧。

![SSH Login](images/2022-03-11-rails-deployment-in-practice-setup-server/ssh-login-screen.png)

連上之後會看到這樣的畫面，同時會提示有套件可以進行升級，因此我們使用 Ubuntu 預設的套件管理命令 `apt`（或是 `apt-get`）來進行升級（`upgrade`）除此之外定期升級套件可以確保伺服器在安全的狀況下運行。

接下來我們依照 Docker 的 [Ubuntu 安裝指南](https://docs.docker.com/engine/install/ubuntu/進)行 Docker 的安裝，目前主流的 Linux 發行版本都有對應的支援，因此我們在安裝上基本上只需要依序將命令貼上即可。

```bash
sudo apt-get update # 更新套件資訊

# 安裝必要套件，目前 Ubuntu 20.04+ 通常已經都有安裝
sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

# 匯入 GPG Key 用於驗證下載的來源是來自 Docker 官方
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# 加入 Docker 套件來源
# 如果更新的發行版本可能會需要手動修改
    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update # 更新套件資訊，這次是用來抓取 Docker 套件資訊
sudo apt-get install docker-ce docker-ce-cli containerd.io # 安裝 Docker
```

執行完畢後我們基本上就安裝好了 Docker 並且可以使用，我們可以簡單的安裝 NGINX 鏡像來測試。

## 測試安裝{#test-setup}

如果你已經非常熟悉容器環境的使用，或者是透過 DigitalOcean 的 Marketplace 的 Docker 鏡像安裝環境，這個步驟可以跳過，如果是第一次使用，那麼非常建議用這種方式體驗一下。

下達下面的命令來執行一個提供 80 Port 連線的 NGINX 伺服器。

```bash
docker run --rm -it -p 80:80 nginx
```

當你看到畫面之後，可以直接打開剛剛雲端服務分派給我們的 IP 位址，就能夠看到 NGINX 執行成功的畫面。

![NGINX Demo](images/2022-03-11-rails-deployment-in-practice-setup-server/nginx-demo.png)

這也是容器技術的好處，我們只需要有可以運行的環境就可以省略掉複雜的伺服器安裝步驟，如果直接使用 Docker 鏡像來啟動虛擬伺服器，我們只需要簡單的下達啟動命令就可以將服務運作起來。

---

如果想在第一時間收到更新，歡迎[訂閱弦而時習之](https://mailchi.mp/aotoki/rails-deployment-in-practice)在這系列文章更新時收到通知，如果有希望了解的知識，可以利用[Rails 部署實踐回饋表單](https://us4.list-manage.com/survey?u=dd3d68032c0510041f1302539&id=f25e0dc43e&attribution=false)告訴我。


