網站 / 莊生趣味 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

  1. GCP Console: VPC 網路 > IP 位址 > 將該 VM 的 IP 升級為 「靜態」
  2. 網域商 (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. 資料庫初始安全設定

udo apt install mariadb-server mariadb-client -y

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

sudo mysql_secure_installation

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

4. 申請 SSL 憑證 (HTTPS)

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. 建立資料庫與使用者

>sudo mysql -u root -p

進入 資料庫 後執行 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 並設定權限

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] 下方加入:

max_allowed_packet = 64M
wait_timeout = 28800
interactive_timeout = 28800

3. 重啟服務使設定生效

sudo systemctl restart apache2
sudo systemctl restart mariadb

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

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

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

1. 安裝 phpMyAdmin

sudo apt install phpmyadmin -y

下面的步驟1.跟實際情況不太一樣,是直接輸入選項
【重要】安裝過程中的互動畫面設定: 執行後,畫面會變成藍底灰字的選單,請依照以下指示操作(這步錯了會很麻煩,請慢點按):

  1. Web server selection (選擇網頁伺服器):
    • 畫面會列出 apache2lighttpd
    • 請先按鍵盤的「空白鍵 (Space)」 選取 apache2 (這時前面會出現一個 * 星號)
    • 確認有星號後,再按 Enter
    • (許多人直接按 Enter 沒選到,導致安裝後網頁打不開)
  2. Configure database for phpmyadmin with dbconfig-common? (是否自動設定資料庫)
    • 選擇 「Yes」 (是)
  3. MySQL application password for phpmyadmin:
    • 系統會要求您設定一個 phpMyAdmin 程式本身連線資料庫用的密碼
    • 您可以輸入一個新密碼,或是直接按 Enter 讓它隨機產生(通常按 Enter 即可)

啟用必要的 PHP 擴充功能

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

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

sudo phpenmod mbstring
sudo systemctl restart apache2

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

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

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

# 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. 重啟服務

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

#!/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 更新而記憶體不足時,會發生以下情況:

  1. 資源搶奪: CPU 和 RAM 被佔滿,系統變得極度緩慢
  2. 程序崩潰: 不只是 MySQL 資料庫會崩潰,連 GCP 的背景服務(如您看到的 Guest Agent)也會因為拿不到資源而運作異常、超時或被強制終止
  3. 產生錯誤日誌: 系統試圖恢復這些服務失敗,就會留下您貼出的這些紀錄

結論: 這些日誌證實了您的伺服器在 12-10和12-13 這幾天曾經歷過嚴重的資源不穩,這與您「更新導致當機」的描述完全吻合


1.建立 2GB 的 Swap 檔案

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

sudo fallocate -l 2G /swapfile

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

sudo chmod 600 /swapfile

3.啟用 Swap

sudo mkswap /swapfile
sudo swapon /swapfile

4.檢查是否成功

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

sudo swapon --show

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

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

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

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,也可以用新的名稱來建立資料庫,再將檔案匯入