CentOS 7 → Rocky Linux 8 遷移筆記
把服務器上面的 CentOS7 升級到 Rocky
Rocky Linux / AlmaLinux(最接近 CentOS 的替代)
完全相容 RHEL,指令習慣幾乎一樣
適合原本用 CentOS 的團隊,遷移成本最低
Rocky Linux 由原 CentOS 創始人主導,社群活躍
推薦給:習慣 yum/dnf、SELinux 環境的用戶
Ubuntu Server LTS(最廣泛使用)
GCP 官方支援最完整,文件與社群資源最豐富
LTS 版本提供 5 年支援(如 22.04、24.04)
套件最新,apt 生態完善
推薦給:新專案、容器化環境、需要最新軟體版本
下面是遷移筆記
CentOS 7 → Rocky Linux 8 遷移筆記
一、遷移方式
建議做法:Snapshot 複製新機(不要原地升級)
- GCP Console → 磁碟 → 建立快照
- 從快照建立新 VM
- 在新 VM 上跑 ELevate 腳本升級 OS
- 測試完成後切換 IP / Load Balancer
⚠️ 原地升級風險高,有 DB 和應用服務時特別不建議
OS 升級腳本(CentOS 7 → Rocky 8)
sudo yum install -y http://repo.almalinux.org/elevate/elevate-release-latest-el7.noarch.rpm
sudo yum install -y leapp-upgrade leapp-data-rocky
sudo leapp preupgrade # 先跑檢查,看 /var/log/leapp/leapp-report.txt
sudo leapp upgrade
sudo reboot
二、systemd service 修復(MySQL 手動安裝)
問題:Type=forking 沒有 PIDFile,systemd 一直 activating
解法:改用 Type=notify 直接啟動 mysqld(不透過 mysqld_safe)
[Service]
Type=notify
User=mysql
Group=mysql
ExecStart=/usr/local/mysql8/bin/mysqld --defaults-file=/usr/local/etc/my.cnf
ExecStop=/usr/local/mysql8/bin/mysqladmin --defaults-file=/usr/local/etc/my.cnf shutdown
Restart=on-failure
LimitNOFILE=65535
TimeoutStartSec=300
TimeoutStopSec=300
三、PHP 升級(5.6 → 7.4)
安裝 Remi repo 和 PHP 7.4
sudo dnf install -y https://rpms.remirepo.net/enterprise/remi-release-8.rpm
sudo dnf module reset php
sudo dnf module enable php:remi-7.4
sudo dnf install -y php php-fpm php-mysqlnd php-gd php-mbstring \
php-xml php-igbinary php-ldap php-gmp php-bcmath php-sockets php-pcntl php-process
php-gd 依賴問題(libraqm / libimagequant 找不到)
# 啟用 powertools
sudo dnf config-manager --set-enabled powertools
# 強制安裝(nodeps)
sudo dnf download --enablerepo=remi-modular php-gd
sudo rpm -ivh --nodeps php-gd-*.rpm
# 建立 libgd symlink
sudo ln -s /usr/lib64/libgd.so.3 /usr/lib64/libgd.so.103
sudo ldconfig
php-redis 無法安裝(liblzf 找不到)
# 改用 pecl 編譯安裝
sudo dnf install -y php-devel php-pear gcc make
printf "no\nno\nno\nno\n" | sudo pecl install redis
echo "extension=redis.so" | sudo tee /etc/php.d/50-redis.ini
ionCube 重新安裝
cd /tmp
wget https://downloads.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz
tar xzf ioncube_loaders_lin_x86-64.tar.gz
cp ioncube/ioncube_loader_lin_7.4.so /usr/lib64/php/modules/
echo "zend_extension=/usr/lib64/php/modules/ioncube_loader_lin_7.4.so" \
> /etc/php.d/00-ioncube.ini
php-fpm 設定
# Rocky 8 預設 user 是 apache,改成 nginx
sudo sed -i 's/^user = apache/user = nginx/' /etc/php-fpm.d/www.conf
sudo sed -i 's/^group = apache/group = nginx/' /etc/php-fpm.d/www.conf
# 改用 port(對應 nginx fastcgi_pass 127.0.0.1:9000)
sudo sed -i 's|^listen = /run/php-fpm/www.sock|listen = 127.0.0.1:9000|' /etc/php-fpm.d/www.conf
PHP 7.4 移除的函數
| 函數 | 狀態 | 處理方式 |
|---|---|---|
mcrypt_* |
PHP 7.2+ 移除 | 改用 openssl |
ereg |
PHP 7.0+ 移除 | 改用 preg_* |
wddx |
PHP 7.4+ 移除 | 幾乎不再使用 |
get_magic_quotes_gpc() |
PHP 7.4 deprecated | 用 function_exists 包住 |
四、Nginx 設定問題
nginx.conf 有預設 server block 攔截所有請求
# 把 nginx.conf 裡的 default server block 全部註解掉
vi /etc/nginx/nginx.conf
# 找到並註解:
# server {
# listen 80 default_server;
# ...
# }
統一所有 conf 改用 port
sudo sed -i 's|fastcgi_pass unix:/run/php-fpm/www.sock;|fastcgi_pass 127.0.0.1:9000;|g' /etc/nginx/conf.d/*.conf
rewrite 無限循環問題
# ❌ 會造成無限循環
location / {
rewrite ^/(.*)$ /index.php?s=/$1 last;
}
location ~ \.php {
if (!-f $request_filename) {
rewrite (.*) /index.php; # 沒有 break,造成循環
}
}
# ✅ 正確做法
location / {
try_files $uri $uri/ /index.php?s=/$1;
}
# 刪掉 php location 裡的 if rewrite
五、MySQL 連線問題
MySQL socket 路徑
- 手動安裝的 MySQL socket 在
/tmp/mysql.sock - PHP 預設找
/var/lib/mysql/mysql.sock - 解法:建立 symlink 或在 php.ini 設定
mkdir -p /var/lib/mysql
ln -s /tmp/mysql.sock /var/lib/mysql/mysql.sock
# 或在 php.ini 設定
echo "mysqli.default_socket = /tmp/mysql.sock" >> /etc/php.ini
echo "pdo_mysql.default_socket = /tmp/mysql.sock" >> /etc/php.ini
root 用戶 host 權限
-- PHP 用 127.0.0.1 連線,需要加 127.0.0.1 的權限
CREATE USER 'root'@'127.0.0.1' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'127.0.0.1' WITH GRANT OPTION;
FLUSH PRIVILEGES;
六、Typecho 升級相容問題
config.inc.php 修改
- 把 adapter 從
Mysql改成Mysqli - 把 host 從
localhost改成127.0.0.1
// ❌ 舊的
$db = new Typecho_Db('Mysql', 'typecho_');
// ✅ 新的
$db = new Typecho_Db('Mysqli', 'typecho_');
Mysqli.php quoteColumn bug
quoteColumn() 在 Query building 階段被呼叫時,連線尚未建立,$this->_dbLink 為 null。
// 在 Mysqli.php 的 quoteColumn 函數加 fallback
public function quoteColumn($string)
{
if ($this->_dbLink) {
return $this->_dbLink->real_escape_string($string);
}
return str_replace('`', '``', $string); // fallback
}
php.ini 關閉 deprecated 警告
# 避免 get_magic_quotes_gpc() deprecated 被 Typecho 當錯誤處理
sed -i 's/^error_reporting.*/error_reporting = E_ALL \& ~E_DEPRECATED \& ~E_NOTICE/' /etc/php.ini
七、.NET 升級
# 移除舊版 .NET Core 2.1
sudo dnf remove dotnet-runtime-2.1 dotnet-hostfxr-2.1
# 安裝 .NET 8
sudo dnf install -y dotnet-runtime-8.0
# 確認(注意:--version 需要 SDK,只有 runtime 用這個)
dotnet --list-runtimes
⚠️ .NET 2.1 → 8.0 跨度大,framework-dependent 發布的應用需要重新編譯
八、Claude Code 安裝
# 需要 Node.js 18+,用 nvm 安裝
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
source ~/.bashrc
nvm install 18
nvm use 18
# 安裝 Claude Code
npm install -g @anthropic-ai/claude-code
claude
九、開機自動啟動確認
sudo systemctl enable nginx
sudo systemctl enable php-fpm
sudo systemctl enable mysql8
sudo systemctl enable redis
十、處理掉的問題總結
| 問題 | 原因 | 解法 |
|---|---|---|
| php-gd 裝不了 | libraqm/libimagequant 不在 repo | nodeps 強制裝 + libgd symlink |
| php-redis 裝不了 | liblzf 找不到 | pecl 編譯安裝 |
| MySQL 一直 activating | Type=forking 沒有 PIDFile | 改 Type=notify |
| nginx 全部回傳預設頁 | nginx.conf 有 default_server | 註解掉預設 server block |
| php-fpm 連線失敗 | socket vs port 不一致 | 統一用 127.0.0.1:9000 |
| MySQL 連線拒絕 | root 只有 localhost,沒有 127.0.0.1 | 新增 root@127.0.0.1 權限 |
| Typecho 500 錯誤 | 舊版 Mysql adapter + quoteColumn bug | 改 Mysqli + 修 quoteColumn |
| rewrite 無限循環 | php location 裡有多餘 rewrite | 刪掉多餘的 if rewrite |