把服務器上面的 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 複製新機(不要原地升級)

  1. GCP Console → 磁碟 → 建立快照
  2. 從快照建立新 VM
  3. 在新 VM 上跑 ELevate 腳本升級 OS
  4. 測試完成後切換 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 修改

  1. 把 adapter 從 Mysql 改成 Mysqli
  2. 把 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

無標籤

新增評論