POABOB

小小工程師的筆記分享

0%

使用 GCP 建置一個具有 SSL 和 DNS 的靜態網站(完全免費!!!)

前言

最近因為 CakeResume 作品集不能給非會員觀看,這時就想說來自己架一個站好了,那麼我主要是利用 GCP 建立免費的 VMNo-IP 使用免費的 DNSCertbot 自動申請免費的 SSL 憑證,在 OS 之中,主要都是以 Docker 作為主力容器服務。

建立免費 GCP VM

官方免費 VM 服務條件

  • 其實一般人除了初次90天內300美元的額度可以使用以外,GCP 還有提供一個條件可以讓你免費使用他的 VM 服務
    • 使用 e2-micro (2 個 vCPU,1 GB 記憶體) 的硬體
    • VM 位置在奧勒岡州:us-west1愛荷華州:us-central1南卡羅來納州:us-east1
    • 硬碟空間最多使用30GB。(個人使用10GB而已,以前有用過30GB被收費過QQ)
    • 快照(Snapshot)空間就是 GCP 可以備份你的 VM,而限制就是 5GB(超容易達成,建議不要用)

P.S.

  1. 流量費用另外計算,但我的作法是 VM 只展示靜態檔案,這樣就可以避免如果架設後端 API 被亂 call。
  2. 每幾年基本上都會有些免費條件的調整,要請大家注意自己的帳單是否開始成長。

選擇/建立 Porject

  • 一開始進入後台的時候,GCP 會先要求你建立或是選擇一個 Project 來當作專案分類。
  • 我們可以點擊側邊欄的左上角的Dropdown 選擇或建立我們的Project


  • 如果沒有 Project 那麼直接輸入一個即可。

  • 選擇好 Project 後,請將 Compute Engine API 的服務順便啟用。

建立 VM

  • 進入 Compute Engine > VM執行個體的頁面之後,請點擊建立執行個體

  • 將你的 VM 名稱區域硬體條件(vCpu、Memory)硬碟(大小、OS)防火牆(HTTP、HTTPS)設定好,點擊建立


安裝 Docker

  • 使用瀏覽器的 SSH 進入 VM

  • 安裝指令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 先清空 VM 內的舊版本 Docker
sudo apt-get remove docker docker-engine docker.io containerd runc

# 系統上更新並安裝基本的依賴
sudo apt-get update
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release

# 添加 Dokcer 官方的 GPG 密鑰
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# 添加 Docker 到我們的 APT 倉庫之中
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
$(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-compose \
docker-compose-plugin

# 測試是否安裝成功,如果找得到指令就沒問題了
sudo docker --help
sudo docker-compose -h

刪除步驟:

1
2
3
4
5
# 刪除安裝包
sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-compose docker-compose-plugin

# 刪除鏡像、容器、配置相關文件
sudo rm -rf /var/lib/docker

撰寫 docker-compose.yml

  • 撰寫 /home/{user}/docker-compose.yml 是為了可以讓我們之後一鍵開啟容器服務,並且將 nginx 的相關配置也寫好

/home/{user}/docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
version: '3'

services:
webserver:
# 獲取最新鏡像
image: nginx:latest
# 端口映射 VM:CONTAINER
ports:
- 80:80
- 443:443
# 自動重啟
restart: always
# 文件映射
volumes:
# :ro代表在container之中的文件是read-only
- ./nginx/conf/:/etc/nginx/conf.d/:ro
- ./html:/etc/nginx/html/:ro
- ./certbot/www:/var/www/certbot/:ro

/home/{user}/nginx/conf/default.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
server {
# 開啟gzip 節省流量
gzip on;
gzip_vary on;

listen 80;
listen [::]:80;

# DNS配置
server_name example.org;
server_tokens off;

# 以下等我們下面段落會使用
# certbot 驗證所需路徑
# location /.well-known/acme-challenge/ {
# root /var/www/certbot;
# }

# http 301 redirect https
# location / {
# return 301 https://example.org$request_uri;
# }
}
  • 建立 /home/{user}/html/index.html,等等可以直接查看 Server 是否正常運行

/home/{user}/html/index.html

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World</title>
</head>
<body>
<h1>Hello I am NGINX SERVER!!!</h1>
</body>
</html>

Nginx DEMO

  • 配置好我們的文件之後,我們只要切換的家目錄下 docker-compose 指令,就可以開啟 http 服務
1
2
3
4
5
# 切換到USER 家目錄
cd

# docker-compose 開啟 nginx
sudo docker-compose up -d webserver
  • 然後開啟瀏覽器,輸入 IP 就可以看到我們的 HTML。

測試 GZIP 是否開啟成功

  • 進入測試網站
    • https://www.giftofspeed.com/gzip-test/
  • 輸入自己的IP,只要顯示Enabled即可

使用 No-IP 免費DNS服務

註冊會員

  • 點擊No-IP的註冊連結

    • https://www.noip.com/sign-up
  • 簡單註冊並輸入想使用的 DNS,記得點擊Free Sign Up,其他服務要收費


指定 VM 的 IP

  • 收取驗證信後,去到後台的My Services> Managed DNS,編輯自己 DNS 所指向的 IP

  • 編輯時,點選DNS Hostname(A),並輸入自己在 GCP 上的 IP 就可以了

DEMO

  • 瀏覽器輸入自己的 DNS

GCP SSL 配置

撰寫配置文件

  • SSL 加密之中,有一個免費的服務叫 Let's Encrypt,由於它派發的憑證每90天就要更新一次,所以我們必須使用自動化的方式來自動更新憑證,那麼 Certbot 就是我們所需要的。

/home/{user}/docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
version: '3'

services:
webserver:
# 獲取最新鏡像
image: nginx:latest
# 端口映射 VM:CONTAINER
ports:
- 80:80
- 443:443
# 自動重啟
restart: always
# 文件映射
volumes:
# :ro代表在container之中的文件是read-only
- ./nginx/conf/:/etc/nginx/conf.d/:ro
- ./html:/etc/nginx/html/:ro
- ./certbot/www:/var/www/certbot/:ro
- ./certbot/conf/:/etc/nginx/ssl/:ro
# SSL 驗證機器人
certbot:
image: certbot/certbot:latest
volumes:
- ./certbot/www/:/var/www/certbot/:rw
- ./certbot/conf/:/etc/letsencrypt/:rw
  • 把 Certbot 的註解還原

/home/{user}/nginx/conf/default.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
// ...

# 以下等我們下面段落會使用
# certbot 驗證所需路徑
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}

# http 301 redirect https
#location / {
# return 301 https://example.org$request_uri;
#}
}

Cerbot 服務

  • 下指令去讓 Certbot 安裝憑證
1
2
3
4
5
# 先開啟NGINX服務,讓Certbot驗證
sudo docker-compose up -d webserver

# 一次性將憑證安裝好,DNS請更改成自己的
docker-compose run --rm certbot certonly --webroot --webroot-path /var/www/certbot/ -d example.org

HTTP 301 跳轉 HTTPS

  • 由於我們已經申請好憑證了,但是如果我們訪問 http://{DNS} 仍然會可以看到頁面,這時我們就需要自動幫使用者做跳轉

/home/{user}/nginx/conf/default.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
server {
// ...

# http 301 redirect https
location / {
return 301 https://example.org$request_uri;
}
}
server {
listen 443 default_server ssl http2;
listen [::]:443 ssl http2;

server_name example.org;

# DNS 請自行修改
ssl_certificate /etc/nginx/ssl/live/example.org/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/example.org/privkey.pem;
}

SSL DEMO

Cronjob

  • 為了避免我們憑證過期,所以我們要在使用 Scheduler定期更新憑證
1
2
3
4
5
# 編輯 Scheduler
sudo crontab -e

# 加入以下指令,每周定期RENEW SSL 憑證
0 0 * * 0 root docker-compose run --rm certbot renew

參考資料

  • GCP建置、免費額度
    • https://hackmd.io/@JB-Lin/B1JEPsqIw
    • https://www.taskinghouse.com/posts/google-cloud-platform-free-plan-after-trial/
    • https://cloud.google.com/free/docs/free-cloud-features?hl=zh-tw#free-tier-usage-limits
  • Debian 上安裝 Docker
    • https://dockerdocs.cn/engine/install/debian/
    • https://www.runoob.com/docker/debian-docker-install.html
  • docker-compose.yml && SSL
    • https://mindsers.blog/post/https-using-nginx-certbot-docker/
    • https://ubiq.co/tech-blog/how-to-enable-nginx-gzip-compression/
    • https://hackmd.io/@JB-Lin/B1JEPsqIw
------ 本文結束 ------