#!/bin/bash
#Nifty: Install nginx with PHP-FPM from Remi repository

# shellcheck source=../../lib/universal/niftylib.sh
source <(curl -fSs https://nifty.sh/lib/universal/niftylib.sh)

# Requirements
require_root
require_64bit
require_os alma8 alma9 alma10

ce "Updating system"
dnf update -y 

ce "Installing EPEL"
dnf install -y epel-release

ce "Installing remi repo"
OS_RELEASE="$(detect_os)"
OS_VERSION="$(get_os_version)"
[ "$OS_RELEASE" = "alma8" ] && dnf module reset -y php nginx httpd # Must be enabled to prevent a conflict when installing remi-release
rpm -Uvh "http://rpms.remirepo.net/enterprise/remi-release-${OS_VERSION/.*/}.rpm"

mapfile -t PHP_MODULES < <(dnf module list php | awk '/^php.+remi-/ { print $1 ":" $2 }')
if is_interactive; then
  echo
  PHP_MODULE="$(prompt_select_num_value "Which PHP module do you want to install?" "${PHP_MODULES[@]}")"
else
  PHP_MODULE="${PHP_MODULES[-1]}"
fi

ce "Enabling module $PHP_MODULE"
dnf module switch-to -y "$PHP_MODULE"

# nginx AppStream has multiple packages, official does not
# We need to delete the additional packages to avoid conflicts when updating
ce "Disabling appstream version of nginx if present"
dnf remove -y nginx nginx-core nginx-filesystem

ce "Disabling nginx dnf module"
dnf module disable -y nginx

ce "Installing nginx public repository"
cat <<EOF > /etc/yum.repos.d/nginx.repo
[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
EOF

ce "Installing required packages"
dnf install -y php-cli php-pdo php-opcache php-xml php-gd php-mbstring php-mcrypt php-soap php-mysqlnd php-bcmath php-pecl-zip php-fpm vim nginx

curl vim.dk >> /etc/vimrc

ce "Enabling nginx on startup"
systemctl enable nginx

ce "Enabling PHP on startup"
systemctl enable php-fpm

ce "Doing php.ini customization"
sed -i '/^;/d' /etc/php.ini
sed -i '/^$/d' /etc/php.ini
sed -i 's/memory_limit = 128M/memory_limit = 512M/g' /etc/php.ini
sed -i 's/max_execution_time = 30/max_execution_time = 600/g' /etc/php.ini
sed -i 's/max_input_time = 60/max_input_time = 600/g' /etc/php.ini
sed -i 's/upload_max_filesize = 2M/upload_max_filesize = 256M/g' /etc/php.ini
sed -i '3idate.timezone = "Europe/Copenhagen"' /etc/php.ini
sed -i 's/expose_php = On/expose_php = Off/g' /etc/php.ini

ce "Set up PHP-FPM"
cat <<EOF > /etc/php-fpm.d/www.conf
; Note! If you do not intend on using this file, then just empty it, do not delete it.
; otherwise yum will generate it again and php-fpm will break.
[nginx]
;listen = 127.0.0.1:9000
;listen.allowed_clients = 127.0.0.1

listen = /run/php-fpm-\$pool.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660

user = \$pool
group = nginx

pm = dynamic
pm.max_children = 500
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 150
pm.max_requests = 200
listen.backlog = -1
pm.status_path = /status
request_terminate_timeout = 2720s
rlimit_files = 131072
rlimit_core = unlimited
catch_workers_output = yes
EOF


ce "Starting PHP-FPM"
systemctl restart php-fpm

ce "Configuring nginx"
mkdir -p /var/www/.letsencrypt-root/
curl -s https://ssl-config.mozilla.org/ffdhe2048.txt > /etc/pki/tls/dhparam.pem
cat <<EOF > /etc/nginx/letsencrypt.common.conf
location ^~ /.well-known/acme-challenge/ {
  alias /var/www/.letsencrypt-root/.well-known/acme-challenge/;
}
EOF

cat <<EOF > /etc/nginx/ssl.common.conf
##
# SSL Settings - Mozilla Intermediate Configuration
##
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;

ssl_session_timeout 1d;
ssl_session_cache shared:SSLCache:10m;
ssl_session_tickets off;
ssl_dhparam /etc/pki/tls/dhparam.pem;
EOF

cat <<EOF > /etc/nginx/vhost.common.conf
index index.html index.htm index.php;

client_max_body_size 50m;
proxy_connect_timeout  60s;
proxy_send_timeout  60s;
proxy_read_timeout  60s;
fastcgi_send_timeout 60s;
fastcgi_read_timeout 60s;
EOF


mkdir /etc/nginx/vhosts.d/

cat <<EOF > /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '\$remote_addr - \$remote_user [\$time_local] "\$request" '
                      '\$status \$body_bytes_sent "\$http_referer" '
                      '"\$http_user_agent" "\$http_x_forwarded_for" \$request_time \$upstream_response_time';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    server_tokens       off;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;



    ##
    # Gzip Settings
    ##
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 5;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/x-javascript
    text/xml application/xml application/xml+rss text/javascript;

    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /var/www/default;

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

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

    include /etc/nginx/vhosts.d/*.conf;
}
EOF

cat <<EOF > /etc/nginx/vhosts.d/domain.tld
# redirect HTTP to HTTPS
server {
  listen 80;
  server_name  domain.tld;
  server_name  www.domain.tld;
  include /etc/nginx/letsencrypt.common.conf;
  return       301 https://\$host\$request_uri;
}

server {
  listen 443 ssl;
  http2 on;
  server_name domain.tld;
  root /var/www/domain.tld/public_html;

  access_log  /var/log/nginx/domain.tld-access.log  main;
  error_log   /var/log/nginx/domain.tld-error.log;

  ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem;
  
  include /etc/nginx/ssl.common.conf;
  include /etc/nginx/letsencrypt.common.conf;
  include /etc/nginx/vhost.common.conf;

  location / {
    fastcgi_read_timeout 60s;
    proxy_read_timeout 150;
    try_files \$uri \$uri/ /index.php?\$args;
  }

  location ~ \.php\$ {
    try_files \$uri =404;
    include fastcgi_params;
    expires off;
    fastcgi_split_path_info ^(.+\.php)(/.+)\$;
    fastcgi_pass unix:/var/run/php-fpm-domain.tld.sock;
    fastcgi_pass_request_headers on;
    fastcgi_keep_conn off;
    fastcgi_param SCRIPT_FILENAME \$document_root\${fastcgi_script_name};
  }
}
EOF

echo
ce "All done!"
