2025/12/18

網站 / 莊生趣味 tricohobby 重新建置

原本的網站是在GCP部署Bitnami package for WordPress

由於這算是一種套裝軟體(?)的概念,優點是部署快速

缺點是PHP、Apache、MySQL都是無法自行更新

隨著時間的推進,終會有無法配合wordpress最低要求的時候

之前已經發生過一次,那時候是重新部署VM

現在,Gemini 3 pro經過幾次試用之後,發現回答問題的架構很完整(當然還是要多次修飾提示詞)

於是嘗試請Gemini回答"如何在GCP建置WordPress"

Gemini給了2種方式

方法一:使用 GCP Marketplace (最推薦、最快速)

方法二:進階手動安裝

我的目標不是要用預裝軟體(方法一)的方式來部署,不就跟原本的一樣

所以請Gemini更詳細說明如何"從頭建置網路伺服器"(方法二)

根據多次的調整與問題處理,目前應該是完善了整個流程

最後請Grmini將整個過程整理如下


第一階段:基礎建設 (GCP Console)

1. 建立 VM 執行個體

  • 名稱: 自訂 (如 wp-server)
  • 區域: asia-east1 (台灣)
  • 機器類型: e2-small (建議)/我是選e2-micro (1GB RAM),更便宜
  • 開機磁碟: Ubuntu 22.04 LTS (建議 20GB 標準永久磁碟)
  • 防火牆: 勾選 「允許 HTTP」「允許 HTTPS」
  • 2. 固定 IP 與 DNS

  • GCP Console: VPC 網路 > IP 位址 > 將該 VM 的 IP 升級為 「靜態」
  • 網域商 (DNS): 設定 A Record (@www) 指向該靜態 IP
  • 3. 設定 GCP 防火牆 (安全性關鍵)

    這個其實就是GCP預設的情況,所以不用特別設定

  • 前往 VPC 網路 > 防火牆
  • 確認: 允許 tcp:80, tcp:443, tcp:22
  • 確認: 絕對不要 允許 tcp:3306 (資料庫埠口)

  • 第二階段:環境架設 (SSH 指令)

    使用 GCP SSH 視窗或 PuTTY 連線後執行

    1. 系統更新與安裝 PHP 8.2

    我後來安裝php8.4,以下指令只要把php8.2改成php8.4即可 Bash

    sudo apt update && sudo apt upgrade -y
    sudo apt install software-properties-common nano -y
    # 加入 PHP 8.2 專用儲存庫
    sudo add-apt-repository ppa:ondrej/php -y
    sudo apt update

    2. 安裝 LAMP 堆疊

    Bash

    # 安裝 Apache 與 MariaDB
    sudo apt install apache2 mariadb-server mariadb-client -y

    # 安裝 PHP 8.2 及 WordPress 必要模組
    sudo apt install php8.2 php8.2-mysql php8.2-curl php8.2-gd php8.2-mbstring php8.2-xml php8.2-xmlrpc php8.2-soap php8.2-intl php8.2-zip libapache2-mod-php8.2 -y

    3. 資料庫初始安全設定

    Bash

    sudo apt install mariadb-server mariadb-client -y

    建議執行安全性設定 (設定資料庫 root 密碼):

    Bash

    sudo mysql_secure_installation

    (問是否切換 unix_socket 按 n,設定 root 密碼按 y 並輸入密碼,其餘一路按 y 即可)

    4. 申請 SSL 憑證 (HTTPS)

    Bash

    sudo apt install certbot python3-certbot-apache -y
    sudo certbot --apache

    執行上述指令後,系統會問幾個問題:

  • Enter email address: 輸入您的 Email (用於緊急續約通知)
  • Terms of Service: 輸入 Y 同意服務條款
  • Share email: 是否分享 Email 給基金會?輸入 Y 或 N 皆可
  • Which names would you like to activate HTTPS for?

  • 會列出它偵測到的網域 (如果您尚未在 Apache 設定檔指定 ServerName,它可能會要您手動輸入)
  • 直接輸入要申請的網域,例如:example.com www.example.com (用空白鍵隔開)
  • 重要提示:  DNS 設定必須已經生效,Certbot 才能驗證成功。如果失敗,請稍等 DNS 擴散後再試一次
  • 驗證成功 如果一切順利,會看到 "Congratulations!" 的訊息。Certbot 會自動幫您設定好「每三個月自動續約」,不需要手動去更新憑證


    第三階段:核心部署

    1. 建立資料庫與使用者

    Bash

    sudo mysql -u root -p

    進入 資料庫 後執行 SQL 指令:

    SQL

    CREATE DATABASE wordpress_db;
    /* 請將 your_password 換成您的強密碼 */
    CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'your_password';
    GRANT ALL PRIVILEGES ON wordpress_db.* TO 'wp_user'@'localhost';
    FLUSH PRIVILEGES;
    EXIT;

    2. 下載 WordPress 並設定權限

    Bash

    cd /tmp
    wget https://wordpress.org/latest.tar.gz
    tar -xvzf latest.tar.gz
    sudo mv wordpress/* /var/www/html/

    # 設定正確權限 (www-data)
    sudo chown -R www-data:www-data /var/www/html/
    sudo chmod -R 755 /var/www/html/

    # 移除預設首頁
    sudo rm /var/www/html/index.html


    第四階段:系統優化與修正

    1. 修改 PHP 設定 (php.ini)

    路徑:/etc/php/8.2/apache2/php.ini 指令:sudo nano /etc/php/8.2/apache2/php.ini 搜尋並修改以下數值:

    Ini, TOML

    upload_max_filesize = 64M
    post_max_size = 128M
    memory_limit = 256M
    max_execution_time = 300
    max_input_time = 300

    2. 修改 MariaDB 設定

    路徑:/etc/mysql/mariadb.conf.d/50-server.cnf 指令:sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf [mysqld] 下方加入:

    Ini, TOML

    max_allowed_packet = 64M
    wait_timeout = 28800
    interactive_timeout = 28800

    3. 重啟服務使設定生效

    Bash

    sudo systemctl restart apache2
    sudo systemctl restart mariadb

    4. 修正內頁 404 錯誤 (啟用 Rewrite)

  • 啟用模組:sudo a2enmod rewrite
  • 修改設定:sudo nano /etc/apache2/apache2.conf
  • 找到 <Directory /var/www/>,將 AllowOverride None 改為 AllowOverride All
  • 重啟:sudo systemctl restart apache2
  • 後台動作: 進 WordPress 設定 > 永久連結 > 點擊「儲存」

  • 第五階段:極致安全設定 (隱藏後台)

    1. 安裝 phpMyAdmin

    Bash

    sudo apt install phpmyadmin -y

    下面的步驟1.跟實際情況不太一樣,是直接輸入選項

    【重要】安裝過程中的互動畫面設定: 執行後,畫面會變成藍底灰字的選單,請依照以下指示操作(這步錯了會很麻煩,請慢點按):

  • Web server selection (選擇網頁伺服器):

  • 畫面會列出 apache2lighttpd
  • 請先按鍵盤的「空白鍵 (Space)」 選取 apache2 (這時前面會出現一個 * 星號)
  • 確認有星號後,再按 Enter
  • (許多人直接按 Enter 沒選到,導致安裝後網頁打不開)
  • Configure database for phpmyadmin with dbconfig-common? (是否自動設定資料庫)

  • 選擇 「Yes」 (是)
  • MySQL application password for phpmyadmin:

  • 系統會要求您設定一個 phpMyAdmin 程式本身連線資料庫用的密碼
  • 您可以輸入一個新密碼,或是直接按 Enter 讓它隨機產生(通常按 Enter 即可)
  • 啟用必要的 PHP 擴充功能

    雖然安裝時已經包含了,但為了保險起見,我們明確告知 PHP 啟用 mbstring (處理中文必備):

    (如果您安裝的是 php 8.2,請執行)

    Bash

    sudo phpenmod mbstring
    sudo systemctl restart apache2

    2. 設定「僅限本機 (Localhost) 存取」

    修改 Apache 設定檔:sudo nano /etc/phpmyadmin/apache.conf

    修改內容如下 (包含改網址與 IP 限制):

    Apache

    # 1. 修改存取路徑 (隱藏入口)
    Alias /phpmyadmin_db /usr/share/phpmyadmin

    <Directory /usr/share/phpmyadmin>
    Options SymLinksIfOwnerMatch
    DirectoryIndex index.php

    # 2. 加入 IP 限制 (只允許 SSH 通道)
    Require all denied
    Require ip 127.0.0.1

    # ... (下方保持原樣) ...

    3. 重啟服務

    Bash

    sudo systemctl restart apache2

    設定完成後,直接用網址連線會出現 403 Forbidden,必須使用 SSH 通道才看得到


    第六階段:備份策略 (GCS 異地備份)

    1. 建立 GCS Bucket

  • GCP Console > Cloud Storage > 建立 Bucket (例如 backup-tricohobby-manual) > 位置選 asia-east1
  • 設定生命週期 (省錢): 新增規則 > Age 30 天 > 動作:刪除物件
  • 2. 設定寫入權限 (關鍵)

    為了避免 VM 權限不足,直接在 Bucket 授權

  • GCP Console > Cloud Storage > 點擊該 Bucket > 權限 (Permissions)
  • 點擊 授予存取權 (Grant Access)
  • 主體: 輸入您的 VM 服務帳號 (錯誤訊息中出現的那串 email,如 xxxx-compute@developer...)
  • 角色: 選擇 Storage Object Admin
  • 3. 建立備份腳本

    在 SSH 建立檔案:nano manual_backup.sh

    Bash

    #!/bin/bash
    # 設定區
    BUCKET_NAME="backup-tricohobby-manual" # 您的 Bucket 名稱
    DB_USER="root"
    DB_PASS="您的資料庫Root密碼"
    DB_NAME="wordpress_db"

    DATE=$(date +%Y%m%d_%H%M)
    echo "--- 開始備份 [$DATE] ---"

    # 匯出資料庫
    echo "1. 匯出 SQL..."
    mysqldump -u $DB_USER -p$DB_PASS $DB_NAME > /tmp/db_$DATE.sql

    # 打包檔案
    echo "2. 打包網站..."
    tar -czf /tmp/files_$DATE.tar.gz /var/www/html/

    # 上傳 (失敗會報錯並停止)
    echo "3. 上傳至 GCS..."
    gsutil cp /tmp/db_$DATE.sql gs://$BUCKET_NAME/sql/ || { echo "❌ SQL 上傳失敗"; exit 1; }
    gsutil cp /tmp/files_$DATE.tar.gz gs://$BUCKET_NAME/files/ || { echo "❌ 檔案上傳失敗"; exit 1; }

    # 清理
    rm /tmp/db_$DATE.sql
    rm /tmp/files_$DATE.tar.gz
    echo "✅ 備份完成!"

    賦予執行權限:chmod +x manual_backup.sh 執行備份: ./manual_backup.sh


    第七階段:用戶端連線教學 (日常維護)

    因為我們鎖住了 3306 和 phpMyAdmin,必須使用特殊方式連線

    SSH沿用之前的VM設定,這樣相關程式只要改IP位址就可以了

    1. 連線 phpMyAdmin (管理資料庫內容)

  • 工具: PuTTY + Chrome/Edge 瀏覽器
  • PuTTY 設定:

  • Connection > SSH > Tunnels
  • Source port: 8888
  • Destination: 127.0.0.1:443
  • 點擊 Add,然後 Open 連線。
  • 瀏覽器開啟:

  • 網址:https://127.0.0.1:8888/phpmyadmin_db/
  • 遇到「不安全」警告:點擊「進階」->「繼續前往」。
  • 2. 連線 MySQL Workbench (管理資料庫結構)

  • 工具: MySQL Workbench
  • 新增連線:

  • Method: Standard TCP/IP over SSH
  • SSH Host: GCP外部IP
  • SSH Key:  .pem 金鑰檔/用private key轉換的open_ssh_key
  • MySQL Host: 127.0.0.1 (指伺服器自己)
  • MySQL Port: 3306
  • Username: wp_user
  • 3. 連線 SFTP (管理檔案)

  • 工具: FileZilla
  • 設定:

  • 協定: SFTP
  • 主機: GCP外部IP
  • 登入型式: 金鑰檔案 (.ppk)
  • 使用者:  SSH 帳號
  • 其他

    1.建立 Swap (虛擬記憶體)

    因為網站常常在更新之後就卡住了,必須重新啟動伺服器 Gemini對於這個問題的回答

    這是一個典型的系統高負載或記憶體耗盡的連鎖反應(Symptom),而非根本原因

    當您的 e2-micro (1GB RAM) 因為 WordPress 更新而記憶體不足時,會發生以下情況:

  • 資源搶奪: CPU 和 RAM 被佔滿,系統變得極度緩慢
  • 程序崩潰: 不只是 MySQL 資料庫會崩潰,連 GCP 的背景服務(如您看到的 Guest Agent)也會因為拿不到資源而運作異常、超時或被強制終止
  • 產生錯誤日誌: 系統試圖恢復這些服務失敗,就會留下您貼出的這些紀錄
  • 結論: 這些日誌證實了您的伺服器在 12-1012-13 這幾天曾經歷過嚴重的資源不穩,這與您「更新導致當機」的描述完全吻合


    1.建立 2GB 的 Swap 檔案

    這會告訴系統:「當 1GB 真實記憶體不夠用時,請使用硬碟上的這 2GB 空間來幫忙」,這樣網站就不會當機了

    Bash

    sudo fallocate -l 2G /swapfile

    2.設定權限(安全考量)

    Bash

    sudo chmod 600 /swapfile

    3.啟用 Swap

    Bash

    sudo mkswap /swapfile
    sudo swapon /swapfile

    4.檢查是否成功

    執行後,您應該會看到 Swap 欄位不再是 0:

    Bash

    sudo swapon --show

    5.確保重開機後設定還在 (重要)

    將設定寫入系統檔案,這樣下次您重啟伺服器時,Swap 依然有效:

    Bash

    echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

    2.


    2.限制 Apache 的最大連線數

    偶爾網站還是會在更新外掛、發文之後掛掉

    Gemini建議限制 Apache 的最大連線數

    以下是針對(Apache + 1GB RAM)的調整步驟:

    第一步:確認Apache 運作模式 (MPM)
    Apache 有兩種主要的運作模式,設定檔位置不同。請先輸入這行指令確認:

    Bash

    apachectl -V | grep -i mpm

    如果出現 mpm_prefork:(最常見,配合 mod_php)

    代表每個連線都是一個獨立進程,非常吃記憶體。

    如果出現 mpm_event 或 mpm_worker:

    代表使用執行緒模式,記憶體較省,但設定方式略有不同。

    (以下假設大多數 WordPress 使用的 prefork 模式)

    第二步:計算合理的數值 (數學時間)

    讓我們簡單算一下您的主機極限:

    總記憶體: 1024 MB
    系統 + 資料庫保留: 約需 400 MB (給作業系統和 MySQL)
    剩餘給 Apache: 約 600 MB
    一個 Apache 進程耗費: WordPress 通常一個進程吃掉 40MB ~ 60MB
    計算公式: 600MB / 50MB ≈ 12 個連線

    結論: 您應該將最大連線數設定在 10 到 15 之間。預設的 150 絕對會讓伺服器當機

    請依照以下步驟,將 Apache 的胃口「縮小」到適合您主機的大小:

    1. 編輯設定檔
    請執行以下指令開啟設定檔:

    Bash

    sudo nano /etc/apache2/mods-enabled/mpm_prefork.conf

    2. 修改數值 (請直接複製貼上覆蓋)

    請刪除原本的內容(或修改數值),並貼上以下針對 1GB RAM 主機優化 的設定

    這裡將最大連線數限制在 12,保留足夠的記憶體給資料庫和系統運作。

    Apache
    
    <IfModule mpm_prefork_module>
    StartServers 2
    MinSpareServers 2
    MaxSpareServers 5
    
    # 這是最關鍵的設定:最多只允許 12 個同時連線
    # 算法:(總記憶體 1024MB - 系統保留 400MB) / 每個PHP程序約 50MB = ~12
    MaxRequestWorkers 12
    
    # 避免請求過多導致排隊過久,超過此數值會拒絕連線 (保護機制)
    ServerLimit 12
    
    # 每個子程序處理 1000 個請求後就自動重生,防止記憶體洩漏
    MaxConnectionsPerChild 1000
    </IfModule>

    按 Ctrl + O (寫入檔案)

    按 Enter (確認檔名)

    按 Ctrl + X (離開)。

    4. 檢查語法是否正確 (重要)

    在重啟之前,先確認我們沒有打錯字:

    Bash

    sudo apache2ctl -t

    如果看到 Syntax OK:代表沒問題,可以繼續。

    如果看到錯誤訊息,請重新進去檢查。

    5. 重啟 Apache 讓設定生效

    Bash

    sudo service apache2 restart

    3.還原網站

    一如既往,先安裝修改版的All-in-One WP Migration

    還是一如既往在回復資料的時候,卡在資料庫(不知道是不是All-in-One WP Migration的版本問題)

    所以還是直接連入資料庫,匯入之前的備份檔

    這時候要留意,前面在設定wordpress所用的資料庫名稱跟原先的不同

    可以修改wordpress的config,也可以用新的名稱來建立資料庫,再將檔案匯入

    0 comments:

    張貼留言