LAMP是指在許多web 伺服器上使用的一個軟體組合:Linux,Apache,MySQL/MariaDB以及PHP。
Apache HTTP 伺服器,簡稱 Apache,是非常流行的Web伺服器軟體。通常和腳本語言比如 PHP,資料庫 MySQL 一起工作,合稱為 LAMP 棧(Linux, Apache, MySQL, PHP). 本文介紹。本文檔描述了怎樣安裝設置 Apache 網頁伺服器。以及選擇安裝 PHP和 MySQL 併集成到Apache伺服器中。
安裝
配置
Apache 配置文件位於 /etc/httpd/conf,主要的配置文件是 /etc/httpd/conf/httpd.conf, 此文件會引用其它文件。
用默認配置可以啟動一個簡單的服務,有用戶訪問時會提供目錄 /srv/http 下的內容。
啟動 httpd.service systemd 服務,Apache 就會啟動,從瀏覽器中訪問 http://localhost/ 會顯示一個簡單的索引頁面。
高級選項
請參考 Apache 完整 directives 配置選項和 directive 快速參考.
請關注一下 /etc/httpd/conf/httpd.conf 中的下面選項:
User http
- 出於安全原因,Apache以root用戶身份啟動(直接的或者通過啟動腳本)後將立即切換為
/etc/httpd/conf/httpd.conf中指定的 UID,默認配置是 http, 安裝時會自動創建此用戶。
Listen 80
- Apache 監聽的埠,要被外網訪問,請在路由器開放此埠。
- 如果是本地調試用,可以用下面命令設置為僅供本地訪問
Listen 127.0.0.1:80.
ServerAdmin you@example.com
- 管理員的電子郵件,在錯誤頁面會展示給用戶。
DocumentRoot "/srv/http"
- 網頁的目錄.
- 如果需要可以修改這個目錄,請記得同步修改
<Directory "/srv/http">和DocumentRoot,否則訪問新位置時可能出現 403 Error (缺少權限)問題。不要忘記修改Require all denied行到Require all granted,否則會出現 403 Error. DocumentRoot 目錄及其父目錄必須有可執行權限,這樣再能被伺服器進程使用的用戶訪問到(用chmod o+x /path/to/DocumentRoot設置),否則會出現 403 Error.
AllowOverride None
- 在
<Directory>段落中的這個設置會讓 Apache 完全忽略.htaccess文件。從 Apache 2.4,這個設置以及是默認的,所以如果要使用.htaccess,請允許Overide. 如果要在.htaccess中使用mod_rewrite或其它設置, 可以指定哪些目錄允許覆蓋伺服器配置。更多信息請訪問 Apache 文檔.
apachectl configtest 檢查配置文件是否存在問題。更多設置可以訪問 /etc/httpd/conf/extra/httpd-default.conf,例如
關閉伺服器簽名:
ServerSignature Off
隱藏 Apache 和 PHP 版本等屬性:
ServerTokens Prod
用戶目錄
在默認設置下,可以通過 http://localhost/~yourusername/ 訪問用戶的主目錄並顯示 ~/public_html 中的內容 (可以通過 /etc/httpd/conf/extra/httpd-userdir.conf 設置). 要禁用這個訪問,請注釋掉 /etc/httpd/conf/httpd.conf 文件中的如下行:
Include conf/extra/httpd-userdir.conf
請正確設置目錄的權限,使得 Apache 可以訪問到文件。主目錄和 ~/public_html 必須是可被其它用戶執行:
$ chmod o+x ~ $ chmod o+x ~/public_html $ chmod -R o+r ~/public_html
重啟 httpd.service 服務以應用更改。參考 Umask#Set the mask value.
TLS/SSL
OpenSSL 提供了 TLS/SSL 支持,默認已經安裝在 Arch 中。
在 /etc/httpd/conf/httpd.conf 中,取消下面行的注釋:
LoadModule ssl_module modules/mod_ssl.so LoadModule socache_shmcb_module modules/mod_socache_shmcb.so Include conf/extra/httpd-ssl.conf
TLS/SSL 需要密鑰和認證,如果你有公開域名,可以使用 Let's Encrypt 免費獲取認證,如果沒有,請參考 #創建密鑰並自簽名.
獲取密鑰和認證之後,請將 /etc/httpd/conf/extra/httpd-ssl.conf 中的 SSLCertificateFile 和 SSLCertificateKeyFile 指向對應的文件。如果還生成了 CA 認證鏈,請將文件名設置到 SSLCertificateChainFile.
重啟 httpd.service.
創建密鑰並自簽名
創建一個私鑰並自己簽名認證,對於不需要 CSR 的大部分使用來說已經足夠:
# cd /etc/httpd/conf # openssl req -new -x509 -nodes -newkey rsa:4096 -keyout server.key -out server.crt -days 1095 # chmod 400 server.key
如果需要創建 CSR,用下面的密鑰創建方:
# openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out server.key # chmod 400 server.key # openssl req -new -sha256 -key server.key -out server.csr # openssl x509 -req -days 1095 -in server.csr -signkey server.key -out server.crt
Virtual Hosts
如果需要不止一個主機,取消 /etc/httpd/conf/httpd.conf行的注釋:
Include conf/extra/httpd-vhosts.conf
在 /etc/httpd/conf/extra/httpd-vhosts.conf 中設置虛擬主機,默認文件包含了一個示例。
要在本地機器測試虛擬主機,將虛擬名稱加入 /etc/hosts 文件:
127.0.0.1 domainname1.dom 127.0.0.1 domainname2.dom
重啟 httpd.service 服務。
管理多個主機
如果要管理的主機非常多,希望更方便的維護,建議為每一個虛擬主機創建一個配置文件並文件存儲到一個文件夾中 /etc/httpd/conf/vhosts。
創建目錄:
# mkdir /etc/httpd/conf/vhosts
編寫單獨的配置文件:
# nano /etc/httpd/conf/vhosts/domainname1.dom # nano /etc/httpd/conf/vhosts/domainname2.dom ...
在 /etc/httpd/conf/httpd.conf 中 Include 單獨的配置文件:
#Enabled Vhosts: Include conf/vhosts/domainname1.dom Include conf/vhosts/domainname2.dom
通過注釋或取消注釋可以單獨啟用或禁用一個虛擬主機。
基本的 vhost 文件:
/etc/httpd/conf/vhosts/domainname1.dom
<VirtualHost *:80>
ServerAdmin webmaster@domainname1.dom
DocumentRoot "/home/user/http/domainname1.dom"
ServerName domainname1.dom
ServerAlias domainname1.dom
ErrorLog "/var/log/httpd/domainname1.dom-error_log"
CustomLog "/var/log/httpd/domainname1.dom-access_log" common
<Directory "/home/user/http/domainname1.dom">
Require all granted
</Directory>
</VirtualHost>
<VirtualHost *:443>
ServerAdmin webmaster@domainname1.dom
DocumentRoot "/home/user/http/domainname1.dom"
ServerName domainname1.dom:443
ServerAlias domainname1.dom:443
SSLEngine on
SSLCertificateFile "/etc/httpd/conf/apache.crt"
SSLCertificateKeyFile "/etc/httpd/conf/apache.key"
ErrorLog "/var/log/httpd/domainname1.dom-error_log"
CustomLog "/var/log/httpd/domainname1.dom-access_log" common
<Directory "/home/user/http/domainname1.dom">
Require all granted
</Directory>
</VirtualHost>
擴展
PHP
首先,參考 PHP 頁面,完成 PHP 的安裝。
有多種方式可以在 Apache 下使用 PHP,#使用 libphp 最簡單,但是擴展性最差,libphp 還需要修改 mpm 模塊,可能影響其它擴展,比如和 #HTTP2 不兼容。
使用 libphp
安裝軟體包 php-apache包。
php-apache包 中包含的 libphp7.so 不支持 mod_mpm_event,僅支持 mod_mpm_prefork(FS#39218)。需要在 /etc/httpd/conf/httpd.conf 中注釋掉:
#LoadModule mpm_event_module modules/mod_mpm_event.so
取消下面行的注釋:
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
不然將發生下面的錯誤:
Apache is running a threaded MPM, but your PHP Module is not compiled to be threadsafe. You need to recompile PHP. AH00013: Pre-configuration failed httpd.service: control process exited, code=exited status=1
另外在本小節的下方還有兩種處理高並發的方案供選擇. ( 使用php-fpm管理進程和 使用mod_fcgid管理進程 )
要啟用 PHP,在 /etc/httpd/conf/httpd.conf 中添加如下行:
- 將這一行放在
LoadModule的末尾:
LoadModule php_module modules/libphp.so AddHandler php-script php
- 將這一行放到
Include列表的末尾:
Include conf/extra/php_module.conf
重啟 httpd.service。
使用 php-fpm 和 mod_proxy_fcgi
這種方式是使用php-fpm來管理進程的,進程不是由apache啟動和管理的.
ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/run/php-fpm/php-fpm.sock|fcgi://localhost/srv/http/$1
啟用代理模塊:
/etc/httpd/conf/httpd.conf
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
創建文件: /etc/httpd/conf/extra/php-fpm.conf 寫入以下內容:
/etc/httpd/conf/extra/php-fpm.conf
DirectoryIndex index.php index.html
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php-fpm/php-fpm.sock|fcgi://localhost/"
</FilesMatch>
把以下這句添加到配置文件 /etc/httpd/conf/httpd.conf 中 include 部份的最後
Include conf/extra/php-fpm.conf
你可以自行配置 PHP-FPM 通過這個編輯這個配置文件 /etc/php/php-fpm.d/www.conf, 但是默認的配置已經工作的很好了.
重啟 httpd.service 和 php-fpm.service 這兩個服務.
httpd.conf 加入了下面內容,請刪除它們,已經不再需要:
LoadModule php7_module modules/libphp7.so Include conf/extra/php7_module.conf
使用 apache2-mpm-worker 和 mod_fcgid
這種方式和上一種方式(php-fpm)的區別:
php-fgi进程是由apache模块启动并管理,而不需要配置和使用php-fpm来管理进程。 在php-cgi进程以apache用户身份运行,php程序写的文件,其权限为apache用户(而不像php-fpm下写文件为php-fpm用户所有,默认是nobody),这样在目录权限管理方面一致性高些。
安裝軟體包 mod_fcgidAUR(詳情)和 php-cgi包。
創建需要的目錄並建立軟連結:
# mkdir /srv/http/fcgid-bin # ln -s /usr/bin/php-cgi /srv/http/fcgid-bin/php-fcgid-wrapper
創建 /etc/httpd/conf/extra/php-fcgid.conf,內容是:
/etc/httpd/conf/extra/php-fcgid.conf
# Required modules: fcgid_module
<IfModule fcgid_module>
AddHandler php-fcgid .php
AddType application/x-httpd-php .php
Action php-fcgid /fcgid-bin/php-fcgid-wrapper
ScriptAlias /fcgid-bin/ /srv/http/fcgid-bin/
SocketPath /var/run/httpd/fcgidsock
SharememPath /var/run/httpd/fcgid_shm
# If you don't allow bigger requests many applications may fail (such as WordPress login)
FcgidMaxRequestLen 536870912
# Path to php.ini – defaults to /etc/phpX/cgi
DefaultInitEnv PHPRC=/etc/php/
# Number of PHP childs that will be launched. Leave undefined to let PHP decide.
#DefaultInitEnv PHP_FCGI_CHILDREN 3
# Maximum requests before a process is stopped and a new one is launched
#DefaultInitEnv PHP_FCGI_MAX_REQUESTS 5000
<Location /fcgid-bin/>
SetHandler fcgid-script
Options +ExecCGI
</Location>
</IfModule>
編輯 /etc/httpd/conf/httpd.conf,啟用 actions 模塊:
LoadModule actions_module modules/mod_actions.so
並添加如下配置:
LoadModule fcgid_module modules/mod_fcgid.so Include conf/extra/httpd-mpm.conf Include conf/extra/php-fcgid.conf
Restart httpd.service.
測試 PHP
在 apache 文檔根目錄(即/srv/http/或~public_html)中創建test.php文件,在其中寫入:
<?php phpinfo(); ?>
然後訪問: http://localhost/test.php 或者 http://localhost/~myname/test.php
高級的配置和擴展,請設置 PHP.
HTTP2
要啟用 http2,安裝 libnghttp2包 軟體包(屬於core倉庫,一般默認已經安裝)。然後取消 httpd.conf 中下面行前的注釋:
LoadModule http2_module modules/mod_http2.so
並加入:
Protocols h2 http/1.1
更多信息請參考 mod_http2 文檔。
問題處理
Apache 的狀態和日誌
狀態信息可以用 systemctl 查詢。
Apache 默認的系統日誌位於 /var/log/httpd/。
啟動後出現 Error: PID file /run/httpd/httpd.pid not readable
在 httpd.conf 中注釋掉 unique_id_module 行:
#LoadModule unique_id_module modules/mod_unique_id.so
AH00534: httpd: Configuration error: No MPM loaded.
最近的升級需要修改 httpd.conf 配置文件,取消下面行前的注釋:
/etc/httpd/conf/httpd.conf
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
AH00072: make_sock: could not bind to address
多種都可能導致此問題,最常見的問題是已經有程序監聽了設置的埠,通過下面命令確認:
# netstat -lnp | grep -e :80 -e :443
如該能查到結果,關閉占用埠的程序,然後重試。
還有一個原因是 Apache 沒有以 root 執行,運行下面命令看看問題是否依然發生:
# httpd -k start
最後,可能配置有問題,導致程序同時監聽了埠兩次,例如下面的配置就有這個問題:
Listen 0.0.0.0:80 Listen [::]:80
php.ini 中的 max_execution_time 設置無效
php.ini 中的 max_execution_time 設置為大於 30 (秒), 還會受到 503 Service Unavailable 的話,還需要添加 ProxyTimeout 到 <FilesMatch \.php$> 段落之前:
/etc/httpd/conf/httpd.conf
ProxyTimeout 300
重啟 httpd.service.