MIS 腳印 logo

MIS 腳印

記錄 IT 學習的軌跡

CentOS 8 安裝與設定 LEMP (NGINX、MariaDB、PHP) 和 phpMyAdmin

CentOS 8 安裝與設定 NGINX、MariaDB 與 PHP 來架設 Wbe 伺服器環境,並搭配 phpMyAdmin 在 Web 介面管理 MariaDB 資料庫,以及 SELinux 和常見問題的故障排除。

CentOS

NGINX

安裝 NGINX:

dnf install -y nginx

設定 NGINX 開機自動啟用 (enable) 且立即啟用 (--now):

systemctl enable --now nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.

firewall 設定允許 http (port 80) 和 https (port 443):

firewall-cmd --permanent --add-service={http,https}
success

設定完 firewall 必須重新載入設定檔才會生效:

firewall-cmd --reload
success

查看 firewall 設定:

firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3
  sources:
  services: cockpit dhcpv6-client http https ssh
… 以下省略 …

開啟瀏覽器輸入 IP,呈現下圖畫面表示 NGINX 正常運作:

MariaDB

安裝 MariaDB:

dnf install -y mariadb-server

設定 MariaDB 開機自動啟用 (enable) 且立即啟用 (--now):

systemctl enable --now mariadb
Created symlink /etc/systemd/system/mysql.service → /usr/lib/systemd/system/mariadb.service.
Created symlink /etc/systemd/system/mysqld.service → /usr/lib/systemd/system/mariadb.service.
Created symlink /etc/systemd/system/multi-user.target.wants/mariadb.service → /usr/lib/systemd/system/mariadb.service.

執行 MariaDB 的安全性設定 script:

mysql_secure_installation
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

# root 未有密碼,直接 enter 即可
Enter current password for root (enter for none):
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

# 設定 root 密碼 (直接 enter 等同大寫字母 Y)
Set root password? [Y/n]
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

# 移除匿名帳戶
Remove anonymous users? [Y/n]
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

# 禁止 root 遠端登入
Disallow root login remotely? [Y/n]
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

# 移除 test 資料庫
Remove test database and access to it? [Y/n]
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

# 現在重新加載特權表
Reload privilege tables now? [Y/n]
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

PHP

安裝 PHP:

dnf install -y php

查看 PHP 版本:

php -v
PHP 7.2.11 (cli) (built: Oct  9 2018 15:09:36) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies

安裝 PHP 常用相關模組:

  • php-mysqlnd:連結 MySQL 驅動 (也會一併安裝 PDO)。
  • php-mbstring:處理各種不同語言編碼的的字元 (例如中文的雙字元文字),phpMyAdmin 依賴。
  • php-json:處理 JSON (JavaScript 物件表示法)。
dnf install -y php-mysqlnd php-mbstring php-json

Xdebug

Xdebug 是一個很強大的 PHP 除錯器,直接安裝:

pecl install xdebug
# ... 以上省略 ...

Build process completed successfully
Installing '/usr/lib64/php/modules/xdebug.so'
install ok: channel://pecl.php.net/xdebug-2.9.6
configuration option "php_ini" is not set to php.ini location
You should add "zend_extension=/usr/lib64/php/modules/xdebug.so" to php.ini

依上述提示將 Xdebug 設定至 php.ini 的結尾:

vim /etc/php.ini
# ... 以上省略 ...

zend_extension=/usr/lib64/php/modules/xdebug.so

重啟服務後驗證 Xdebug 是否正確加入 (有顯示 debug 表示成功):

systemctl restart nginx php-fpm
php -m | grep xdebug
xdebug

PHP-FPM

備份 PHP-FPM 設定檔:

cp /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.bak

設定 PHP-FPM:

vim /etc/php-fpm.d/www.conf
;user = apache
user = nginx

;group = apache
group = nginx

NGINX 權限設定:

chown nginx:nginx /var/lib/php/session/
ls -ald /var/lib/php/session/
drwxrwx---. 2 nginx nginx 6 11月 14 12:09 /var/lib/php/session/

設定 PHP-FPM 開機自動啟用 (enable) 且立即啟用 (--now):

systemctl enable --now php-fpm
Created symlink /etc/systemd/system/multi-user.target.wants/php-fpm.service → /usr/lib/systemd/system/php-fpm.service.

故障排除

Class 'ZipArchive' not found

PHP 出現 Uncaught Error: Class 'ZipArchive' not found,必須安裝 php-pecl-zip:

dnf install php-pecl-zip

undefined function mysqli_connect()

PHP 出現 Fatal error: Call to undefined function mysqli_connect(),必須安裝 php-mysqlnd:

dnf install -y php-mysqlnd

mysqli_connect(): (HY000/2002)

PHP 出現 Warning: mysqli_connect(): (HY000/2002): Permission denied,必須設定 SELinux 允許網路連線 httpd_can_network_connect,查看目前為 off:

getsebool -a | grep httpd_can_network_connect
httpd_can_network_connect --> off
httpd_can_network_connect_cobbler --> off
httpd_can_network_connect_db --> off

設定允許 httpd_can_network_connect:

sudo setsebool -P httpd_can_network_connect 1

undefined function json_encode()

PHP 出現 Fatal error: Uncaught Error: Call to undefined function json_encode(),PHP 5.5 之後 json 不在與 PHP 捆綁在一起,所以必須自行安裝:

dnf install -y php-json

undefined function imagecreatefromjpeg()

PHP 出現 Fatal error: Uncaught Error: Call to undefined function imagecreatefromjpeg(),必須安裝 php-gd:

dnf install -y php-gd

Permission denied

無法新增目錄的訊息:
Warning: mkdir(): Permission denied in /usr/share/nginx/html/index.php on line 3

無法新增檔案的訊息:
Warning: error_log(/usr/share/nginx/html/my-errors.log): failed to open stream: Permission denied in /usr/share/nginx/html/index.php on line 6

查看目錄無法讓 httpd 可 rw (讀寫) 的權限:

ls -ldZ /usr/share/nginx/html
drwxr-xr-x. 3 nginx nginx system_u:object_r:httpd_sys_content_t:s0 137  2月 15 14:02 /usr/share/nginx/html

需要 httpd_sys_rw_content_t 才能讓 httpd 有建立目錄和檔案的權限:

chcon -t httpd_sys_content_rw_t /usr/share/nginx/html
ls -ldZ /usr/share/nginx/html
drwxr-xr-x. 3 nginx nginx system_u:object_r:httpd_sys_rw_content_t:s0 137  2月 15 14:02 /usr/share/nginx/html

phpMyAdmin

下載

開啟 phpMyAdmin 複製軟體連結:

貼上軟體連結下載 phpMyAdmin:

wget https://files.phpmyadmin.net/phpMyAdmin/5.0.1/phpMyAdmin-5.0.1-all-languages.tar.gz

解壓縮檔案:

tar -zxv -f phpMyAdmin-5.0.1-all-languages.tar.gz

刪除壓縮檔案:

rm phpMyAdmin-5.0.1-all-languages.tar.gz
rm:是否移除普通檔案'phpMyAdmin-5.0.1-all-languages.tar.gz'? y

將 phpMyAdmin 搬移至 NGINX 的網站根目錄:

mv phpMyAdmin-5.0.1-all-languages/ /usr/share/nginx/html/phpMyAdmin

設定

複製 phpMyAdmin 設定檔:

cp /usr/share/nginx/html/phpMyAdmin/config.sample.inc.php /usr/share/nginx/html/phpMyAdmin/config.inc.php

前往 phpMyAdmin blowfish secret generator 將自動生成的密鑰更新到 phpMyAdmin 設定檔:

vim /usr/share/nginx/html/phpMyAdmin/config.inc.php
/**
 * This is needed for cookie based authentication to encrypt password in
 * cookie. Needs to be 32 chars long.
 */
$cfg['blowfish_secret'] = 'BkdX}Kl2LCVqUKMET-:JUqvvV5.cLzNB'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */

設定 phpMyAdmin 儲存空間:

mysql < /usr/share/nginx/html/phpMyAdmin/sql/create_tables.sql -u root -p
Enter password:

設定 phpMyAdmin 快取模版:

mkdir /usr/share/nginx/html/phpMyAdmin/tmp
chown nginx:nginx /usr/share/nginx/html/phpMyAdmin/tmp
chmod 755 /usr/share/nginx/html/phpMyAdmin/tmp

設定 SELinux 目錄類型:

chcon -R -t httpd_sys_rw_content_t /usr/share/nginx/html/phpMyAdmin

NGINX

新增 phpMyAdmin 的 NGINX 設定檔:

vim /etc/nginx/conf.d/phpmyadmin.conf
server {
    listen       80 default_server;
    listen       [::]:80 default_server;
    server_name  _;
    root         /usr/share/nginx/html;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;
}

重啟 NGINX:

systemctl restart nginx

使用 phpMyAdmin

開啟瀏覽器輸入 IP,如果沒問題就會開啟下圖的 phpMyAdmin:

限制允許訪問 IP

透過 NGINX 的設定,來允許訪問 phpMyAdmin 的 IP:

vim /etc/nginx/conf.d/phpmyadmin.conf
server {
    listen       80 default_server;
    listen       [::]:80 default_server;
    server_name  _;
    root         /usr/share/nginx/html;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    # 允許訪問 phpMyAdmin 的 IP
    location /phpMyAdmin {
        # 可空格指定多個 IP
        allow 61.xxx.xxx.60;
        deny all;
    }
}

登錄超時,請重新登入

在登入 phpMyAdmin 一段時間未操作時 (預設為 1440 秒),系統會自動登出並顯示《登錄超時 (1440 秒未操作),請重新登入》。

登入超時可透過調整 PHP 和 phpMyAdmin 設定檔來增加時間,這裡將登錄超時預設的 1440 秒 (24 分鐘) 上調至 7200 秒 (120 分鐘)。

調整 php.ini 設定檔:

vim /etc/php.ini
session.gc_maxlifetime = 7200

於 phpMyAdmin 的 config.inc.php 設定檔最下面新增 (秒數和 php.ini 設定一樣)

vim /usr/share/nginx/html/phpMyAdmin/config.inc.php 
$cfg['LoginCookieValidity'] = 7200;

SELinux

PHP 無法連結資料庫 MariaDB/MySQL,須設定允許 httpd 程序能使用網絡連線:

setsebool -P httpd_can_sendmail on

PHP 無法發送 email,須設定允許 httpd 程序能夠發送 mail:

setsebool -P httpd_can_network_connect on

在〈CentOS 8 安裝與設定 LEMP (NGINX、MariaDB、PHP) 和 phpMyAdmin〉中有 8 則留言

  1. 您好:
    我依照您的教學在新增 phpMyAdmin 的 NGINX 設定檔:這邊完成後
    重啟 NGINX:都會遇到下面的錯誤
    Job for nginx.service failed because the control process exited with error code.
    See "systemctl status nginx.service" and "journalctl -xe" for details.

    請問這要如何設定呢?
    謝謝

    • 您執行錯誤訊息內的指令 journalctl -xe,會詳細說明您的錯誤資訊。

      • 您好:
        經過您的指導查看journalctl -xe的錯誤說明,網路查詢資料大多說是PORT被占用的問題
        -- 單位 nginx.service 已關閉結束。
        5月 07 21:20:34 anj.com systemd[1]: Starting The nginx HTTP and reverse proxy server...
        -- Subject: 單位 nginx.service 已開始啟動
        -- Defined-By: systemd
        -- Support: https://access.redhat.com/support
        --
        -- 單位 nginx.service 已開始啟動。
        5月 07 21:20:34 anj.com nginx[5862]: nginx: [emerg] a duplicate default server for 0.0.0.0:80 in /etc/nginx/nginx.conf:39
        5月 07 21:20:34 anj.com nginx[5862]: nginx: configuration file /etc/nginx/nginx.conf test failed
        5月 07 21:20:34 anj.com systemd[1]: nginx.service: Control process exited, code=exited status=1
        5月 07 21:20:34 anj.com systemd[1]: nginx.service: Failed with result 'exit-code'.
        5月 07 21:20:34 anj.com systemd[1]: Failed to start The nginx HTTP and reverse proxy server.
        -- Subject: 單位 nginx.service 已失敗
        -- Defined-By: systemd
        -- Support: https://access.redhat.com/support
        --
        -- 單位 nginx.service 已失敗。
        --
        -- 結果為 RESULT。

        查看

        [root@anj ~]# sudo netstat -tulpn
        Active Internet connections (only servers)
        Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
        tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1/systemd
        tcp 0 0 192.168.122.1:53 0.0.0.0:* LISTEN 1875/dnsmasq
        tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1134/sshd
        tcp6 0 0 :::111 :::* LISTEN 1/systemd
        tcp6 0 0 :::22 :::* LISTEN 1134/sshd
        tcp6 0 0 :::3306 :::* LISTEN 3887/mysqld
        udp 0 0 0.0.0.0:5353 0.0.0.0:* 995/avahi-daemon: r
        udp 0 0 192.168.122.1:53 0.0.0.0:* 1875/dnsmasq
        udp 0 0 0.0.0.0:67 0.0.0.0:* 1875/dnsmasq
        udp 0 0 0.0.0.0:111 0.0.0.0:* 1/systemd
        udp 0 0 0.0.0.0:53690 0.0.0.0:* 995/avahi-daemon: r
        udp6 0 0 :::5353 :::* 995/avahi-daemon: r
        udp6 0 0 :::111 :::* 1/systemd
        udp6 0 0 :::43584 :::* 995/avahi-daemon: r

        似乎沒看到80 PORT被占用
        可以再請你指導一下嗎?
        謝謝

        • in /etc/nginx/nginx.conf:39 為 nginx.conf 第 39 行有問題。
          我真的未遇過您發生的狀況,如方便將您的 nginx.conf 寄給我看看。

  2. 我測也是卡住了,但用比較笨的方法,一個一個測,在步驟 ( vim /etc/nginx/conf.d/phpmyadmin.conf ) ,這應該是建立一個phpmyadmin.conf 的檔案,可是建立完後再貼上內容,存檔完重啟nginx就起不來了,後來刪掉再重啟nginx 就可以啟動了,至於會不會有什麼影響或要怎麼改,要請其他高手協助了。

    • 但我使用都正常,會不會是 NGINX 版本,因我後來是安裝 1.16.1 (預設為 1.14.1),請問您是安裝哪個版本?
      請問您 NGINX 無法重啟的錯誤訊息是什麼呢!

      • 我NGINX更新至 1.18.0,就可以了,謝謝您的網頁教學,對我這新手學到好多東西。
        P.S 我有卡閞,重看您的教學,發現我Firewall 忘了開,後來就正常了。

發表迴響