Berikut merupakan cara untuk menginstall webserver Nginx dengan PHP-FPM dan Userdir. Sebelum memulai pastikan Anda sudah memilki 1 server CentOS dengan RAM minimal 1GB.
Install Nginx #
Tambah repo nginx, buat file bernama /etc/yum.repos.d/nginx.repo lalu edit seperti berikut.
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
Install nginx.
yum -y install nginx
Buat user web1.
useradd -m web1
Edit konfigurasi /etc/nginx/conf.d/default.conf untuk enable userdir.
# add into [server] section
server {
location ~ ^/~(.+?)(/.*)?$ {
alias /home/$1/public_html$2;
index index.html index.htm;
}
}
Install PHP #
Install repo PHP
yum -y install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
Lalu install PHP
yum -y install php74.x86_64 php74-php.x86_64 php74-php-bcmath.x86_64 php74-php-brotli.x86_64 php74-php-fpm.x86_64 php74-php-gd.x86_64 php74-php-imap.x86_64 php74-php-intl.x86_64 php74-php-ioncube-loader.x86_64 php74-php-json.x86_64 php74-php-mbstring.x86_64 php74-php-mysqlnd.x86_64 php74-php-opcache.x86_64 php74-php-pecl-imagick.x86_64 php74-php-pecl-zip.x86_64 php74-php-sodium.x86_64 php74-php-xml.x86_64 php74-php-xmlrpc.x86_64
Buat pool fpm untuk user web1
nano /etc/opt/remi/php74/php-fpm.d/web1.conf
Edit web1.conf
[web1]
user = web1
group = web1
catch_workers_output = yes
chdir = /home/web1/public_html/
listen = /var/opt/remi/php74/run/php-fpm/web1.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
listen.acl_users = web1,nginx
listen.allowed_clients = 127.0.0.1
request_slowlog_timeout = 5s
slowlog = /var/opt/remi/php74/log/php-fpm/web1-slow.log
pm = ondemand
pm.max_children = 50
pm.max_requests = 200
pm.process_idle_timeout = 10
pm.start_servers = 1
pm.max_spare_servers = 1
pm.min_spare_servers = 1
pm.status_path = /status
ping.path = /ping
request_terminate_timeout = 120s
security.limit_extensions = .phtml .php .php3 .php4 .php5 .php6 .php7 .php8
; php.ini custom configuration directives
php_admin_flag[allow_url_fopen] = on
php_admin_flag[log_errors] = on
php_admin_value[disable_functions] = exec,passthru,shell_exec,system
php_admin_value[short_open_tag] = on
php_value[doc_root] = ""
php_value[error_log] = /home/web1/logs/php.error.log
php_value[error_reporting] = E_ALL & ~E_NOTICE
php_value[max_execution_time] = 300
php_value[max_input_time] = 300
php_value[memory_limit] = 512M
;php_value[open_basedir] = "/home/web1/:/tmp/"
php_value[post_max_size] = 256M
php_value[upload_max_filesize] = 128M
Buat virtualhost #
Login sebagai user web1
su - web1
Selanjutnya buat direktori public_html lalu atur permission home user
mkdir public_html
chmod 711 /home/web1/
Buat file index.php untuk test PHP
nano ~/public_html/index.php
Edit index.php
<?php phpinfo(); ?>
Buat virtualhost web1
nano /etc/nginx/conf.d/web1.conf
server {
listen 80;
server_name web1.example.com;
client_max_body_size 128m;
access_log /var/log/nginx/web1.access.log main;
error_log /var/log/nginx/web1.error.log;
root /home/web1/public_html;
index "index.html" "index.cgi" "index.pl" "index.php" "index.xhtml" "index.htm" "index.shtml";
disable_symlinks if_not_owner "from=/home/web1/public_html";
set $sef_entry_point /;
if ($uri ~* "^/") {
set $sef_entry_point "/index.php?$args";
}
location @wpt_permalinks_fallback {
try_files $uri $sef_entry_point;
}
error_page 404 = @wpt_permalinks_fallback;
error_page 405 = @wpt_permalinks_fallback;
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
location ~ \.php(/.*)?$ {
fastcgi_read_timeout 300;
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
try_files $uri $fastcgi_script_name =404;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass "unix:/var/opt/remi/php74/run/php-fpm/web1.sock";
include /etc/nginx/fastcgi.conf;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Buat file fastcgi.conf jika belum ada.
nano /etc/nginx/fastcgi.conf
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
# https://httpoxy.org/
fastcgi_param HTTP_PROXY "";
Cache #
Langkah ini opsional dan dapat Anda lewati apabila tidak ingin mengaktifkan cache nginx.
Konfigurasikan cache dengan menambahkan beberapa file berikut.
nano /etc/nginx/cache_common
fastcgi_cache_key "$scheme$request_method$host$request_uri";
# fastcgi_no_cache $no_cache $http_pragma $http_authorization $arg_nocache;
# fastcgi_cache_bypass $no_cache $http_pragma $http_authorization $arg_nocache;
fastcgi_no_cache $no_cache $http_authorization;
fastcgi_cache_bypass $no_cache $http_authorization;
fastcgi_cache_valid "5";
fastcgi_cache_use_stale http_500 http_503 updating;
fastcgi_cache_background_update on;
Custom cache
nano /etc/nginx/custom_cache
add_header X-Cache-Status $upstream_cache_status;
set $no_cache "";
set $cache_cookie $http_cookie;
if ($cache_cookie !~ "^\s*$") {
set $no_cache 1;
}
# CMS (& CMS extension) specific cookies (e.g. Joomla, K2 for Joomla, WordPress, WooCommerce, PrestaShop, Magento etc.)
if ($http_cookie ~* "(joomla_[a-zA-Z0-9_]+|userID|wordpress_(?!test_)[a-zA-Z0-9_]+|wp-postpass|comment_author_[a-zA-Z0-9_]+|woocommerce_cart_hash|woocommerce_items_in_cart|wp_woocommerce_session_[a-zA-Z0-9]+|wordpress_logged_in_[a-zA-Z0-9]+|sid_customer_|sid_admin_|PrestaShop-[a-zA-Z0-9]+|SESS[a-zA-Z0-9]+|SSESS[a-zA-Z0-9]+|NO_CACHE|external_no_cache|adminhtml|private_content_version)") {
set $no_cache 1;
}
# Admin sections for CMSs
if ($request_uri ~* "(/administrator|/wp-admin|/wp-login.php)") {
set $no_cache 1;
}
Edit konfigurasi /etc/nginx/conf.d/web1.conf menjadi seperti berikut.
fastcgi_cache_path /var/cache/nginx/web1.example.com levels=1:2 keys_zone=web1.example.com:50m max_size=256m;
server {
listen 80;
server_name web1.example.com;
client_max_body_size 128m;
access_log /var/log/nginx/web1.access.log main;
error_log /var/log/nginx/web1.error.log;
root /home/web1/public_html;
index "index.html" "index.cgi" "index.pl" "index.php" "index.xhtml" "index.htm" "index.shtml";
disable_symlinks if_not_owner "from=/home/web1/public_html";
include custom_cache
location ~ \.php(/.*)?$ {
fastcgi_read_timeout 300;
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
try_files $uri $fastcgi_script_name =404;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass "unix:/var/opt/remi/php74/run/php-fpm/web1.sock";
include /etc/nginx/fastcgi.conf;
fastcgi_cache web1.example.com;
include cache_common;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Restart service #
Terakhir restart service apache dan php-fpm
systemctl restart php74-php-fpm nginx
Test akses web melalui http://web1.example.com
Optimasi #
Berikut merupakan tambahan konfigurasi untuk optimasi webserver dan php-fpm.
Langkah ini opsional dan dapat Anda lewati.
nginx.conf
server_tokens off;
worker_processes auto;
worker_rlimit_nofile 65535;
events {
multi_accept on;
use epoll;
worker_connections 65535;
}
http {
## Basic Settings ##
client_body_buffer_size 128k;
client_header_buffer_size 1k;
large_client_header_buffers 4 16k;
client_body_timeout 30s; # Use 5s for high-traffic sites
client_header_timeout 30s; # Use 5s for high-traffic sites
client_max_body_size 1024m;
keepalive_timeout 30s;
send_timeout 30s;
open_file_cache max=200000 inactive=20s;
open_file_cache_errors on;
open_file_cache_min_uses 2;
open_file_cache_valid 30s;
port_in_redirect off;
reset_timedout_connection on;
sendfile on;
server_name_in_redirect off;
server_names_hash_bucket_size 1024;
server_names_hash_max_size 1024;
server_tokens off;
tcp_nodelay on;
tcp_nopush on;
types_hash_max_size 2048;
## Gzip Settings ##
gzip on;
gzip_buffers 16 8k;
gzip_comp_level 5;
gzip_disable "msie6";
gzip_min_length 1000;
gzip_proxied any;
gzip_types
application/atom+xml
application/javascript
application/json
application/ld+json
application/manifest+json
application/rss+xml
application/vnd.geo+json
application/vnd.ms-fontobject
application/x-font-ttf
application/x-javascript
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/bmp
image/svg+xml
image/x-icon
text/cache-manifest
text/css
text/javascript
text/plain
text/vcard
text/vnd.rim.location.xloc
text/vtt
text/x-component
text/x-cross-domain-policy
text/x-js
text/xml;
gzip_vary on;
# Security Headers
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
dhparams2048.pem
openssl dhparam -out dhparams2048.pem 2048
conf.d/ssl.conf
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
ssl_dhparam /etc/nginx/dhparams2048.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+AESGCM+AES128:EECDH+AESGCM+AES256:EECDH+CHACHA20:EECDH+SHA256+AES128:EECDH+SHA384+AES256:EECDH+SHA1+AES128:EECDH+SHA1+AES256:EECDH+HIGH:AESGCM+AES128:AESGCM+AES256:CHACHA20:SHA256+AES128:SHA256+AES256:SHA1+AES128:SHA1+AES256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK:!KRB5:!aECDH:!kDH:!EDH;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=15552000; preload" always;
php-fpm.conf
process_control_timeout = 10
Referensi: