--- tags: Docker & CI/CD & Server --- # 以 GCP 自架網站應用筆記 (含 Domain 與 SSL) ``` 本文僅作為網站架設筆記,關於GCP計費、雲端服務與第三方工具的相關細節,請自行爬文,本文章不多加敘述 ``` > 本文將使用以下工具 > 1. [Google Cloud Platform (GCP)](https://cloud.google.com/?hl=zh-tw) > 2. [No-Ip](https://www.noip.com/) > 3. [Let's Encrypt](https://letsencrypt.org/zh-tw/) ## 前言 這次筆者將操作筆記分為三個大綱 1. Google Cloud Platform 帳戶申請與創建 VM 2. 公有 IP 映射免費 Domain Name 3. SSL 憑證掛載與自動更新 --- ## 1. GCP 至 [GCP](https://cloud.google.com/?hl=zh-tw) 網站申請帳號,GCP目前提供90天的300美金免費額度,前提是需要綁定信用卡或簽帳金融卡(~~還不趕快去辦卡~~),且額度使用完畢後,Google不會自動向你收費,除非你升級為計費帳戶。 申請完畢並啟用免費額度後,會進入 GCP 的 Dashboard,點選側選單「Compute Engine」->「VM 執行個體」,進入 VM 列表後,可查看所有已建立的虛擬機以及私有IP、公有IP ![](https://i.imgur.com/96ypl9G.png) ### 創建虛擬機 點選上方的「建立執行個體」,創建並選擇虛擬機的規格,包含硬碟空間、RAM、開機磁碟與時區,並勾選防火牆允許 HTTP 與 HTTPS 流量,本篇文章使用 Ubuntu 16.04 LTS 作為安裝的系統,填選完畢後,點擊下方的建立按鈕,Google 就會幫我們產生新的虛擬機囉! ![](https://i.imgur.com/4FvXNoL.png) ### VM 列表 此時回到 VM 列表,若可看見公有 IP,即代表創建成功,接著進入 Domain 的部分囉! --- ## 2. No-IP [No-Ip](https://www.noip.com/) 是提供付費和免費服務的動態 DNS 提供商,而這次我們將透過 No-IP,為剛才在 GCP 建立的 VM 配給一組自訂的 Domain Name,然而 No-IP 的免費次級域名有效期限只有 30 天,但是在到期之前可以無限次申請延展。 廢話不多說,直接把 Domain Name 辦起來! ### 註冊 進入[註冊頁](https://www.noip.com/sign-up?hostname=&domain=hopto.org),填寫信箱、密碼與hostname,勾選隱私權條款後,點選「Get Enhanced」按鈕送出。送出後網頁會先導向到 No-IP 的購物車,此時清空購物車的內容即可忽略此情況 ![](https://i.imgur.com/B761JRc.png) ### 驗證與啟用 接著呢,到你剛才註冊填寫的信箱收取 No-IP 的驗證信,驗證完畢後再重新登入並進到管理頁面,點選下圖的綠色文字「Active」 ![](https://i.imgur.com/zazB4nx.png) ### 申請域名 來到 Hostname 的列表,點選「Create Hostname」的綠色按鈕,會跳出下圖的彈跳視窗,開始填寫你想註冊的 hostname、Domain 類型,以及最重要的公有 IP,公有 IP 就是你在 GCP VM 列表看到的那一組 (~~不要懷疑,用力填下去~~),最後點選右下角的「Create Hostname」即可完成免費 Domain 的註冊 (本篇以填寫custom.ddns.net作為範例) ![](https://i.imgur.com/srpIV4K.png) 你以為這樣就結束了嗎? 當然不是啊,這時回到 GCP 的 VM 執行個體列表,我們要使用 Terminal 進入虛擬機 ### GCP 終端機 ![](https://i.imgur.com/G6KbfNl.png) ### 安裝 Web Server (使用 Apache) ``` $ sudo -s $ apt update $ apt install -y apache2 ``` ### 安裝完畢後,用瀏覽器訪問剛才在 No-IP 註冊的那組網址,應該就會看到 Apache 的預設頁面了,若可正常顯示頁面,表示你的 Domain 是可以正常使用的,因為 Apache 預設占用 80 port,且防火牆允許 80 port 的外部訪問,所以開啟網址後才能正常顯示網頁 --- ## 3. SSL 有了 Apache 這 Web Server,並申請了免費域名後,終於進入本文的最後章節,SSL 憑證給他辦起來! 這次使用 Let's Encrypt 幫網站申請免費的 SSL 憑證,不過 Let's Encrypt 憑證有限期限也是 90 天,但章節最後會講解如何自動刷新憑證 > 以下的操作皆在 GCP 的終端機執行,對於下指令有恐懼、有陰影的,~~可以從側門離開XDD~~ ### 建立站台目錄 ``` $ mkdir -p /var/www/custom.ddns.net # chown -R $USER:$USER /var/www/custom.ddns.net ``` ### 撰寫簡易 HTML ``` $ vim /var/www/custom.ddns.net/index.html ``` html 內容 ```htmlmixed= <h1>Custom Website</h1> ``` ### VirtualHost 檔案名稱可設為自己的網址,如 xxx.xxx.conf ``` $ vim /etc/apache2/sites-available/custom.ddns.net.conf ``` custom.ddns.net.conf 內容 ``` <VirtualHost *:80> ServerName custom.ddns.net # ServerAlias www.custom.ddns.net ServerAdmin custom@service.com.tw DocumentRoot /var/www/custom.ddns.net ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> <IfModule mod_ssl.c> <VirtualHost *:443> ServerName custom.ddns.net # ServerAlias www.custom.ddns.net ServerAdmin custom@service.com.tw DocumentRoot /var/www/custom.ddns.net ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined SSLEngine on SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key <FilesMatch "\.(cgi|shtml|phtml|php)$"> SSLOptions +StdEnvVars </FilesMatch> <Directory /usr/lib/cgi-bin> SSLOptions +StdEnvVars </Directory> </VirtualHost> </IfModule> ``` ### 啟用 VirtualHost 設定檔 ``` $ a2ensite /etc/apache2/sites-available/custom.ddns.net.conf $ service apache2 reload ``` ### 禁用預設的設定檔 ``` $ a2dissite /etc/apache2/sites-available/000-default.conf $ service apache2 reload ``` ### 安裝 Let's Encrypt ``` $ add-apt-repository ppa:certbot/certbot $ apt-get update $ apt-get install python-certbot-apache ``` ### 建立 SSL 證書 1. 在設定過程中,可以選擇 No Redirect 或 Redirect 所有 HTTP 網頁至 HTTPS 2. 完成後,Terminal 將顯示 SSL 証書的檔案位置 e.g. /etc/letsencrypt/live/ ``` $ certbot --apache -d custom.ddns.net ``` ### 完成 開啟 https://custom.ddns.net 即可看見瀏覽器左上角呈現安全憑證的icon! ### 自動刷新憑證 設定系統排程 ``` $ vim /etc/crontab ``` 排程新增一行指令,每天早上 5:30 自動更新 ``` 30 5 * * * root /usr/bin/certbot renew --quiet ```