PHP 5 在今年(2018)年底將完全終止安全更新,PHP 7.0 甚至早了一個月,在今年12月初就終止安全更新。將 PHP 升級到較新 7.1 或 7.2 甚至 7.3 會是比較好的選擇
在 CentOS 7 中將 PHP 升級到 5.6 或 7.0 及以上版本,大多數是選擇以 yum 搭配 Remi Repository 或 Webtatic Repository 這兩個 repo 來做升級,這樣的作法簡單迅速、不太影響以往的操作模式又好維護。在升級過程中不論選擇哪一個 yum repo 都是必須要原本的 php 先移除後 yum install
新的套件,這過程其實再自然不過了
但前提是,必須非常肯定目前在線上的 php 原始碼在升級後都可以正確執行
鸚鵡目前有上線在運作的程式,蠻大量都是自己寫的,真心沒這個把握!
基於網站不能停或不想中斷服務的前提,上述的方案只能直接放棄
過去鸚鵡都盡可能使用 yum 來管理維護相關套件,盡可能不要自己編譯。但之前有次遇到一個狀況,選用的 repo 終止維護計畫,甚至連網站和 mirror 站點都移除。而該 repo 會有覆蓋基本套件的情況,造成更新完全被卡住,花了一點時間才搞定
所以本次的過程會需要自行編譯一些東西,當然在許可的情況盡量使用 CentOS 的基本套件,編譯及安裝時都選擇獨立的路徑來進行,盡量和既有的系統服務做出區隔
再透過設定 httpd.conf 將服務 listen 在 8080 和 8443 兩個 port,並直接對應到已在線上的網站根目錄,如此即可直接測試原有的網站在新的環境下能否正確運作。遇到不能正常的,將整個網站根目錄 cp -R
複製一份後就可以開始修正問題直到可以在新環境正常運作
這樣就可以在完全不影響原有網站的情況下,逐步更新程式碼
最後可以選擇直接使用,也可以選擇回頭使用第三方 repo 直接升級套用
所有編譯安裝的套件都會安裝到 /usr/local/http2 中的個別目錄,原始碼放在 /usr/local/http2/src 裡面
除了方便版本區隔,要完全移除的方式也很簡單:rm -rf
即可
會編譯的清單:
- openssl 1.1.1
- nghttp2 1.34
- brotli 1.0.6
- Apache 2.4.35 (包含 apr 及 apr-util)
- libzip 1.3.0
- libssh2 1.8.0
- cURL 7.61.1
- PHP 7.2.11
以上是編譯順序
因為在編譯 PHP 時使用新版本的 openssl ,卻發生 cURL 內的 libssh2 依賴系統上的 openssl 1.0.2k-fips 而造成版本衝突,才另外重新編譯 libssh2 和 cURL 來解決衝突的問題,所以編譯 apache 時搭配的 cURL 還是 CentOS 7 本身的 7.29.0-46
如果希望 Apache 一併使用最新版本的 cURL,可以將 apache 的順序往後移到 PHP 之前,並在 ./configure
命令中 加上 --with-curl=PATH
參數,PATH 指向 cURL 路徑即可
編譯環境:CentOS 7.5.1804
更新系統、安裝依賴套件
1 2 3 4 5 6 7 8 9 10 11 12 |
yum -y update // for apache yum -y install wget perl perl-core zlib-devel gcc gcc-c++ \ cmake git automake autoconf libtool \ pcre-devel libxml2-devel openssl-devel expat-devel curl-devel // for php yum -y install bison re2c libcurl-devel bzip2-devel gd-devel gmp-devel libc-client-devel \ libicu-devel libtidy-devel libxslt-devel zlib-devel libwebp-devel e2fsprogs-devel krb5-devel libidn-devel mkdir -p /usr/local/http2/src |
安裝過程中如果 ./configure
的時候有錯誤或提示缺少函式庫,可以直接用 yum search
函式庫名稱,再安裝該函式庫的 devel 套件,應該就可以解決
編譯 openssl 1.1.1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
cd /usr/local/http2/src wget https://www.openssl.org/source/openssl-1.1.1.tar.gz tar zxvf openssl-1.1.1.tar.gz cd openssl-1.1.1/ ./config --prefix=/usr/local/http2/ssl --openssldir=/usr/local/http2/ssl shared zlib-dynamic make make install // 連結 library echo "# /etc/ld.so/conf.d/openssl-1.1.1.conf" > /etc/ld.so.conf.d/openssl-1.1.1.conf echo "/usr/local/http2/ssl/lib" >> /etc/ld.so.conf.d/openssl-1.1.1.conf ldconfig -v // 查詢版本和相關資訊 /usr/local/http2/ssl/bin/openssl version -a |
編譯 nghttp2 1.34
1 2 3 4 5 6 7 8 9 10 11 |
// 安裝依賴 yum install libev-devel python-devel c-ares-devel jemalloc-devel jansson-devel CUnit-devel cd /usr/local/http2/src wget https://github.com/nghttp2/nghttp2/releases/download/v1.34.0/nghttp2-1.34.0.tar.gz tar zxvf nghttp2-1.34.0.tar.gz cd nghttp2-1.34.0 OPENSSL_CFLAGS="-I/usr/local/http2/ssl/include" OPENSSL_LIBS="-L/usr/local/http2/ssl/lib64 -lssl -lcrypto" ./configure --prefix=/usr/local/http2/nghttp2 --with-boost make make install |
編譯 brotli 1.0.6
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// 安裝依賴 yum install -y cmake.x86_64 cd /usr/local/http2/src wget https://github.com/google/brotli/archive/v1.0.6.tar.gz mv v1.0.6.tar.gz brotli-1.0.6.tar.gz tar zxvf brotli-1.0.6.tar.gz cd brotli-1.0.6 mkdir out && cd out ../configure-cmake --prefix=/usr/local/http2/brotli make make test make install |
編譯Apache 2.4.35
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
// 下載 apr 和 apr-util cd /usr/local/http2/src wget http://ftp.mirror.tw/pub/apache/apr/apr-1.6.5.tar.gz wget http://ftp.mirror.tw/pub/apache/apr/apr-util-1.6.1.tar.gz tar zxvf apr-1.6.5.tar.gz tar zxvf apr-util-1.6.1.tar.gz // 下載 apache 2.4.35 wget http://ftp.tc.edu.tw/pub/Apache/httpd/httpd-2.4.35.tar.gz tar zxvf httpd-2.4.35.tar.gz // 將 apr 和 apr-util 置入 apache 的 srclib cp -r apr-1.6.5 httpd-2.4.35/srclib/apr cp -r apr-util-1.6.1 httpd-2.4.35/srclib/apr-util cd httpd-2.4.35 ./configure --prefix=/usr/local/http2/apache2 \ --with-included-apr \ --with-pcre \ --enable-mods-shared=all \ --enable-mpms-shared=all \ --enable-static-support \ --enable-unique-id \ --enable-so \ --enable-http2 \ --with-nghttp2=/usr/local/http2/nghttp2 \ --enable-brotli \ --with-brotli=/usr/local/http2/brotli \ --enable-ssl \ --with-ssl=/usr/local/http2/ssl \ --enable-deflate \ --with-curl make make install // 將 brotli 的路徑加入 apache 的 envvars // 也可以使用 ldconfig 的方式來處,擇一即可 sed -i s#http2/apache2/lib#http2/apache2/lib:/usr/local/http2/brotli/lib#g /usr/local/http2/apache2/bin/envvars |
httpd.conf 路徑: /usr/local/http2/apache2/conf/httpd.conf
預設使用的 mpm 模式是 event
啟動、停止、重啟:/usr/local/http2/apache2/bin/apachectl -k start|stop|restart
編譯 libzip 1.3.0
1 2 3 4 5 6 7 8 |
cd /usr/local/http2/src wget https://libzip.org/download/libzip-1.3.0.tar.gz tar zxvf libzip-1.3.0.tar.gz cd libzip-1.3.0 ./configure --prefix=/usr/local/http2/libzip make make install |
編譯 libssh2 1.8.0
1 2 3 4 5 6 7 8 |
cd /usr/local/http2/src wget https://www.libssh2.org/download/libssh2-1.8.0.tar.gz tar zxvf libssh2-1.8.0.tar.gz cd libssh2-1.8.0 ./configure --prefix=/usr/local/http2/libssh2 --with-openssl --with-libz --with-libssl-prefix=/usr/local/http2/ssl make make install |
編譯 cURL 7.61.1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
cd /usr/local/http2/src wget https://curl.haxx.se/download/curl-7.61.1.tar.gz tar zxvf curl-7.61.1.tar.gz cd curl-7.61.1 ./configure --prefix=/usr/local/http2/curl \ --with-ca-bundle=/etc/pki/tls/certs/ca-bundle.crt \ --enable-threaded-resolver \ --enable-ipv6 \ --without-nss \ --with-ssl=/usr/local/http2/ssl \ --with-libssh2=/usr/local/http2/libssh2 \ --with-zlib \ --with-gssapi \ --with-libidn2 \ --disable-ldap make make install |
根憑證使用 CentOS 7 基礎套件:ca-certificates
編譯 PHP 7.2.11
執行 ./configure
之前,請先確認上面編譯的 apache 設定使用的 mpm
模式
設定 event
則 PHP 會編譯出 Thread Safe (API20170718,TS)
設定 prefork
則 PHP 會編譯出 None-Thread Safe (API20170718,NTS)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
// 幫 openssl 及 libzip 各做一個 lib64 對 lib 的連結 ln -s lib /usr/local/http2/ssl/lib64 ln -s lib /usr/local/http2/libzip/lib64 cd /usr/local/http2/src wget http://tw2.php.net/distributions/php-7.2.11.tar.gz tar zxvf php-7.2.11.tar.gz cd php-7.2.11 ./configure --prefix=/usr/local/http2/php7211 \ --with-config-file-path=/usr/local/http2/php7211/etc \ --with-config-file-scan-dir=/usr/local/http2/php7211/etc/php.d \ --with-apxs2=/usr/local/http2/apache2/bin/apxs \ --enable-fpm --with-fpm-user=nobody --with-fpm-group=nobody \ --with-pear \ --enable-shared \ --enable-opcache \ --enable-mysqlnd \ --with-pdo-mysql \ --with-mysqli=shared,mysqlnd \ --with-mysql-sock=/var/lib/mysql/mysql.sock \ --with-sqlite3=shared \ --with-pdo-sqlite=shared \ --with-openssl=/usr/local/http2/ssl \ --with-openssl-dir=/usr/local/http2/ssl \ --with-curl=shared,/usr/local/http2/curl \ --with-gettext=shared \ --with-iconv=shared \ --with-bz2 \ --with-zlib \ --enable-zip=shared \ --with-libzip=/usr/local/http2/libzip \ --enable-sockets \ --with-pcre-regex \ --enable-xml=shared \ --with-xsl=shared \ --with-libxml-dir \ --with-xmlrpc=shared \ --enable-xmlreader=shared --enable-xmlwriter=shared \ --enable-mbstring \ --with-gmp \ --with-mhash \ --with-tidy=shared \ --enable-shmop=shared \ --enable-sysvmsg=shared \ --enable-sysvsem=shared \ --enable-sysvshm=shared \ --enable-wddx=shared \ --enable-exif=shared \ --enable-ftp=shared \ --enable-soap=shared \ --with-gd=shared \ --enable-gd-jis-conv \ --with-png-dir --with-jpeg-dir --with-webp-dir --with-xpm-dir --with-freetype-dir \ --with-imap=shared \ --with-imap-ssl \ --with-kerberos \ --enable-intl=shared \ --with-snmp=shared \ --enable-bcmath=shared \ --enable-fileinfo=shared \ --enable-phar=shared \ --enable-simplexml=shared \ --enable-inline-optimization \ --with-libdir=lib64 make make install // 相關設定檔 // php-fpm 服務 cp ./sapi/fpm/php-fpm.service /usr/lib/systemd/system/ // 初始化 php.ini cp php.ini-production /usr/local/http2/php7211/etc/php.ini // 啟用 opcache mkdir /usr/local/http2/php7211/etc/php.d cd /usr/local/http2/php7211/etc/php.d touch opcache.ini echo "zend_extension=opcache.so" >> opcache.ini echo "opcache.enable=1" >> opcache.ini echo "opcache.enable_cli=1" >> opcache.ini echo "opcache.memory_consumption=128" >> opcache.ini echo "opcache.interned_strings_buffer=8" >> opcache.ini echo "opcache.max_accelerated_files=4000" >> opcache.ini echo "opcache.huge_code_pages=1" >> opcache.ini |
大多數的 extension 我設定為 shared 需要用到時再修改 php.ini 設定載入
php.ini 也可以選用 php.ini-development,並依照需求設定預設時區 date.timezone
opcache 有啟用 huge_page 功能,可使用 sysctl vm.nr_hugepages
將系統功能啟動,相關資訊可以自尋查詢
到這邊基本需求就算是建制完成
Apache 針對 php 檔案的設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// apache module <FilesMatch \.php$> SetHandler application/x-httpd-php </FilesMatch> // 以下兩種模式都依賴 apache 的 mod_proxy 及 mod_proxy_fcgi 兩個模組 // php-fpm (TCP/IP) <FilesMatch \.php$> SetHandler "proxy:fcgi://127.0.0.1:9000" </FilesMatch> // php-fpm (UNIX Socket) <FilesMatch \.php$> SetHandler "proxy:unix:/usr/local/http2/php7211/var/run/php-fpm.sock|fcgi://localhost" </FilesMatch> |
設定方式參考:https://cnzhx.net/blog/apache-httpd-mod_proxy_fcgi-php-fpm/
php.ini 依照需求載入相關模組及相關配置設定
httpd.conf 中將 Listen 修改為 8080 和 8443 或任何想使用的 port,再將目前服務中的網站的根目錄的路徑設定好,就可以測試網站能不能在新的環境正常運作
而 HTTPS 的 8443 port 也可以直接將 SSL/TLS 證書設定上去
啟用 HTTP/2 協定,在 <VirtualHost>
中加入:Protocols h2 http/1.1
以上,有須由的預祝升級順利