本教學部分畫面是 2020 ~ 2023 年的畫面,GCP UI 有些許不一致,但功能名稱基本上不會變,再斟酌一下,另外開設虛擬機的費用也會根據 GCP 的行銷策略會有些微調整。
軟體需求
MobaXTerm
1. 建立 GCP 專案


注意
專案名稱使用 django-server-xx 作為專案名稱,xx 請替換成自己的座號。方便後續我這邊進行維護或是解決問題。
第一種方式,於通知畫面點選【選取專案】
第二種方式,專案下拉式選單 ➡︎ 找到剛剛所建立的專案
2. 建立虛擬機










注意
按照上述設定後,虛擬機的預估價格為 3.83 USD/月,大約是 125 NTD/月,最後儲存建立虛擬前,請先檢查虛擬機預估發費是否過高。


3. 建立 SSH Key Pair




注意
GCP 虛擬機額外透過 key comment 識別這把金鑰的使用者身分,如果虛擬主機的使用者名稱打錯將會導致 SSH 通訊過程無法登入。









4. 建置伺服器
4.1 更新虛擬機作業系統
1 | sudo apt-get update && sudo apt-get upgrade -y |
如果出現以下畫面
假如出現上述畫面的話,按下 Tab ➡︎ 再 <ok> 選項反白時按下 Enter 即可。
4.2 安裝 Apache2
1 | sudo apt-get install apache2 libapache2-mod-wsgi-py3 -y |
4.3 安裝 python3.12
1 | sudo apt install -y software-properties-common build-essential libffi-dev libssl-dev zlib1g-dev libncurses5-dev libncursesw5-dev libreadline-dev libsqlite3-dev libgdbm-dev libdb5.3-dev libbz2-dev libexpat1-dev liblzma-dev libffi-dev libssl-dev |
1 | sudo add-apt-repository ppa:deadsnakes/ppa |
接著按下 Enter 確認套件庫使用訊息 ➡︎ 繼續使用該 PPA 。
1 | sudo apt update |
1 | sudo apt install -y python3.12 python3.12-venv |
1 | sudo apt install -y python3.12-distutils |
1 | wget https://bootstrap.pypa.io/get-pip.py |
1 | sudo python3.12 get-pip.py |
1 | sudo rm -rf get-pip.py |
1 | sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.12 1 |
1 | python -V |
1 | sudo apt autoremove |
1 | sudo add-apt-repository --remove ppa:deadsnakes/ppa |
5. 設定 Github Personal Access Token


展開 Personal Access Tokens ➡︎ 選擇 Fine-grained Personal Access Tokens
➡︎ 點選 Generate new token



注意
- 產生的 Token 等同於密碼妥善保管,萬一洩漏了等同於洩漏了整個專案,包括新增、修改、刪除的權限。
- 這個頁面關閉之後,無法再次顯示 Token 資訊,只能重新建立新的 Token。
語法為:
1 | git clone https://<您的Token>@github.com/<您的Github ID>/<專案名稱>.git <存放路徑與專案資料夾名稱> |
舉例: Clone 我的專案到個人資料夾並命名為 djangoBLOG
- PAT: github_pat_11ABWDRPY0JWEpm5B5vATm_WJM3oHBku2sDQElTrdvJkCA1RmkRiMZ0QbSwcVw1OtaONK
- 專案網址: https://github.com/keoinn/DjangoBLOG-AI.git
- 存放的路徑: /home/waynechang1226
- 於VM上的專案資料夾名稱: djangoBLOG
完整指令如下:
1 | git clone https://github_pat_11ABWDRPY0JWEpm5B5vATm_WJM3oHBku2sDQElTrdvJkCA1RmkRiMZ0QbSwcVw1OtaONK@github.com/keoinn/DjangoBLOG-AI.git ~/djangoBLOG |
而專案網址可以於 Github 的專案首頁上找到,如下圖。
使用指令查詢當前資料夾詳細資料
1 | ls -la |

6. 建立 Python 虛擬環境
1 | python -m venv ~/django_env |
1 | source ~/django_env/bin/activate |
1 | pip install -r ~/djangoBLOG/requirements.txt |
1 | asgiref==3.8.1 |
1 | django-admin version |
7. 撰寫 Apache2 設定檔案
進行此部分的內容時,請先完成網址申請與 DNS 設定。
1 | cd /etc/apache2/sites-available/ |
1 | sudo touch <你的網址>.conf |
1 | sudo nano <你的網址>.conf |
您可以選擇使用上傳方式
您可以先在本機端用常用的文字編輯器編輯設定檔 (第 4 步),完成後使用 MobaXTerm 內建的 FTP 介面上傳。或者使用 scp 指令將檔案從本地端上傳至遠端主機上,語法如下:
1 | scp -i <private key 路徑> <本地端檔案路徑> <GCP VM 使用者>@<主機位置>:/home/<GCP VM 使用者> |
之後記得把設定檔案移動到 apache2 的資料夾內
1 | sudo mv ~/<設定檔>.conf /etc/apache2/site-avaliable |
1 | <VirtualHost *:80> |
如果您是使用 nano 進行編輯,使用 Crtl + O 存檔。
注意
上面設定檔中,請將 <...> 按照自己的狀況替換字串。
ServerAdmin <您的信箱>替還換成您自己的信箱,即ServerAdmin example@gmail.com。ServerName <你申請的網址>使用您申請的網址,不包含 protocol,即ServerName example.learningweb.net。<VM主機使用者>則替換個人目錄資料夾名稱,通常為虛擬主機上的使用者名稱。<專案資料夾>專案存放的資料夾名稱,大小寫相異。<專案設定資料夾>根據自己專案存放settings.py的資料夾名稱。
上述內容替換後,設定檔案不存在中文與 < 及 > 符號。
1 | sudo a2dissite 000-default.conf |
1 | sudo systemctl reload apache2 |
8. 還原資料庫

1 | # 檔案連結 |
1 | wget --no-check-certificate 'https://docs.google.com/uc?export=download&id=<檔案的ID>' -O ~/<專案資料夾>/db.sqlite3 |
9. 調整專案資料夾權限
1 | sudo chmod +x /home/<VM主機使用者> |
1 | sudo chmod 664 ~/<專案資料夾>/db.sqlite3 |
1 | sudo chown :www-data ~/<專案資料夾>/db.sqlite3 |
1 | sudo chown :www-data <專案資料夾> |
1 | sudo chown :www-data <專案資料夾>/<專案設定資料夾> #專案資料夾/專案設定資料夾 |
10. 靜態檔案生成與集中
1 | source ~/django_env/bin/activate |
上述指令會將整個專案的靜態檔案,打包至指定資料夾,過程中會再次進行確認。
提示介面請輸入 yes 進行收集,而非輸入 y。
11. 專案部屬時需要調整程式碼
<專案資料夾>/<專案設定資料夾>/wsgi.pywsgi.py 1
2
3
4
5
6
7import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "DjangoBLOG.settings")
application = get_wsgi_application()<專案資料夾>/<專案設定資料夾>/settings.pysettings.py 1
2
3
4
5
6
7# ... (略) ...
# allowed host 需修改為 "*" 主機才會允許任何IP的連線
ALLOWED_HOSTS = ["*"]
# ... (略) ...
# 加入於檔案的結尾
SECURE_CROSS_ORIGIN_OPENER_POLICY = None
