Install Nginx + PHP-FPM + MariaDB + SSL at Debian 12

Clean & uninstall Apache2 on Debian 12

#systemctl stop apache2
#systemctl disable apache2
#apt purge apache2 apache2-utils apache2-bin apache2.2-common -y
#apt autoremove --purge -y
#sudo apt autoclean

Update, Upgrade, Install Zip Unzip Vim, Hostname

$sudo apt-get update -y && sudo apt-get upgrade -y
$sudo nano /etc/hostname
$sudo apt-get install zip -y && sudo apt-get install unzip -y
$sudo apt-get install vim -y

Enable Vim Copy Paste with mouse

Enable vim cut paste Debian 9

Install Nginx + PHP-FPM + MariaDB

$sudo apt install nginx -y
$sudo systemctl enable nginx
$sudo systemctl start nginx

Install PHP, then PHP-FPM and extensions

$apt install php -y
$sudo php -v
PHP 8.2.29 (cli) (built: Jul 3 2025 16:16:05) (NTS)
$apt install php8.2 php8.2-fpm php8.2-mysql php8.2-cli php8.2-curl php8.2-mbstring php8.2-xml php8.2-zip unzip -y php8.2-gd

Enable and start PHP-FPM:

$sudo systemctl enable php8.2-fpm
$sudo systemctl start php8.2-fpm

Enable NGINX default (symlink to /etc/nginx/sites-enabled/)

#ln -s /etc/nginx/sites-available/mysite.conf /etc/nginx/sites-enabled/
#nginx -t && systemctl reload nginx

Configure NGINX to Use PHP 8.2-FPM

In your NGINX config paste the PHP Handling:

#cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default-backup
#vim /etc/nginx/sites-available/default
  # PHP handling
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        include fastcgi_params;
        fastcgi_index index.php;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

Restart NGINX AND PHP 8.2-FPM

$sudo systemctl restart php8.2-fpm
$sudo nginx -t && sudo systemctl restart nginx

Add test file:

$sudo echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/info.php

Visit: http://ipaddress/info.php and look for

Server API → FPM/FastCGI

Install MariaDB

$sudo apt install mariadb-server mariadb-client -y
$sudo systemctl enable mariadb
$sudo systemctl start mariadb
$sudo mysql_secure_installation

Nginx Seo Friendly URL/Permalinks for WordPress

$sudo vim /etc/nginx/sites-available/default

Find this block

location / {
    try_files $uri $uri/ /index.php?$args;
}

Nginx Seo Friendly URL migrated from .htaccess

# Serve existing files or route to @rewrite
  location / {
      try_files $uri $uri/ @rewrite;
  }

Restart NGINX AND PHP 8.2-FPM

$sudo systemctl restart php8.2-fpm
$sudo systemctl restart nginx

Configure NGINX real default for domain,  SSL has been installed correctly

#vim /etc/nginx/sites-available/default
server {
    listen 80;
    listen [::]:80;
    server_name mywebsite.com www.mywebsite.com;
    # Force HTTPS + non-www
    return 301 https://mywebsite.com$request_uri;
}

# 2) HTTPS REAL
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name mywebsite.com www.mywebsite.com;
    root /var/www/html;
    index index.php index.html;

    ssl_certificate /etc/nginx/ssl/mywebsite.com.fullchain.crt;
    ssl_certificate_key /etc/nginx/ssl/mywebsite.com.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # Default charset
    charset utf-8;
    # Disable directory listing
    autoindex off;
    # Serve existing files or route to @rewrite
    location / {
        try_files $uri $uri/ @rewrite;
    }
    # PHP handling
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        include fastcgi_params;
        fastcgi_index index.php;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

	location @rewrite {
			rewrite ^/contact-us/?$ /contact-us.php last;
			rewrite ^/sitemap\.xml$ /sitemap.php last;
			#rewrite ^/404/?$ /404.php last;
			return 404;
	}
	error_page 404 /404.php;
	location = /404.php {
			internal;
			include fastcgi_params;
			fastcgi_pass unix:/run/php/php8.2-fpm.sock;
			fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
	}
	location ~* \.(css|js|jpg|jpeg|png|gif|svg|ico|webp|ttf|woff|woff2|eot)$ {
			try_files $uri =404;
			expires max;
			access_log off;
	}
	location ~ /\.ht {
			deny all;
	}
}

Configure NGINX for multiple domains (virtual hosts) on one server

Create Root Folders for Each Domain

$sudo mkdir -p /var/www/domain1.com
$sudo mkdir -p /var/www/domain2.com
$sudo mkdir -p /var/www/domain3.com

$sudo chown -R www-data:www-data /var/www/domain1.com
$sudo chown -R www-data:www-data /var/www/domain3.com
$sudo chown -R www-data:www-data /var/www/domain3.com
$sudo find /var/www/domain1.com -type d -exec chmod 755 {} \; $sudo find /var/www/domain1.com -type f -exec chmod 644 {} \;

Create Nginx Server Blocks (Virtual Host Configs)

#sudo vim sudo vim /etc/nginx/sites-available/domain1.com
# Virtual Host configuration for domain1.com
#
# You can move that to a different file under sites-available/ and symlink that to sites-enabled/ to enable it.
#
server {
       listen 80;
       listen [::]:80;

       server_name domain1.com www.domain1.com;

       root /var/www/domain1.com;
       index index.php index.html;

       #location / {
       #        try_files $uri $uri/ =404;
       #}

	location / {
		try_files $uri $uri/ /index.php?$args;
	}
	
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        }
}

Enable the Sites

$sudo ln -s /etc/nginx/sites-available/domain1.com /etc/nginx/sites-enabled/

Test Nginx Configuration

$sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok

Reload Nginx

$sudo systemctl reload nginx

Test by add file then http://domain1.com/index.html

$sudo echo "It Works" | sudo tee /var/www/domain1.com/index.html

Install Certbot SSL HTTPS Using Snap

Install snapd (if not already installed)

#sudo apt update
#sudo apt install snapd -y

Enable and start snap:

$sudo systemctl enable snapd
$sudo systemctl start snapd

Let the system link classic snaps:

$sudo snap install core
$sudo snap refresh core

Install Certbot via Snap

$sudo snap install --classic certbot

Create symlink so certbot works globally:

$sudo ln -s /snap/bin/certbot /usr/bin/certbot

Check Certbot version:

$sudo certbot --version
certbot 2.x.x

Obtain SSL certificate for Nginx, make sure your Nginx config for http is working at http://yourdomain.com, then run:

#certbot --nginx -d yourdomain.com -d www.yourdomain.com
Certbot will: Auto-detect your Nginx config
Request and install a certificate
Ask if you want HTTP to HTTPS redirect (say yes)

Test HTTPS: Open https://yourdomain.com and You should see the lock icon

Auto-renew is set up by Snap

You don’t need to manually configure cron jobs. Snap installs a systemd timer to auto-renew: Check it:

$sudo systemctl list-timers | grep certbot
✅ Done!

You now have: Fresh Certbot installed via Snap Nginx auto-configured for HTTPS Auto-renewals enabled

Delete Certbot SSL Certificate and Domain

Show all certificate

$sudo certbot certificates
Found the following certs:
Certificate Name: mydomainname.com
Serial Number: 6810f862e51702da43e0e1bc2f80f0d1123
Key Type: ECDSA

Delete the  SSL Certificate that you want

$sudo delete --cert-name mydomainname.com
Are you sure you want to delete the above certificate(s)?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
Deleted all files relating to certificate mydomainname.com.

Would you like to:

Set up SSL hardening / A+ SSL Labs rating?

Force www → non-www redirect (or vice versa)?

Use wildcard SSL with DNS challenge?

I can help with any of those too!

If needed “Add Swap Memory”

Add Swap Memory on Debian 10

If needed “Increase SSH Connection Timeout”

#vim /etc/ssh/sshd_config
ClientAliveInterval 1200
ClientAliveCountMax 3
#systemctl status sshd.service

Configure Iptables Firewall Rules

Debian 11 12 go to this configuration

Iptables Debian 11 Bullseye configuration

Configure UFW Firewall Rules

UFW Firewall Basic Rules and Commands

Setup and Configure Fail2ban

Setup Fail2ban on Debian 9

Install php7 on Debian 8

Install php7 on Debian 8

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install -y php7.3

Check php version

php -v

Installing PHP 7.3 Extensions

sudo apt install php7.3-cli php7.3-fpm php7.3-json php7.3-pdo php7.3-mysql php7.3-zip php7.3-gd  php7.3-mbstring php7.3-curl php7.3-xml php7.3-bcmath php7.3-json

To install Apache Module for PHP, run:

sudo apt install libapache2-mod-php7.3

PHP Warning: date(): It is not safe to rely on the system timezone settings

PHP Warning: date(): It is not safe to rely on the system’s timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier

You probably need to put the timezone in a configuration line in your php.ini file. You should have a block like this in your php.ini file:

[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = America/New_York
then restart httpd
#service httpd restart

PHP date.timezone list visit http://php.net/manual/en/timezones.php

Block other domain pointing our website ip address with .htaccess

How to block other domain pointing our website ip address with .htaccess

Simply add this code below to .htaccess

RewriteEngine on
RewriteCond %{HTTP_HOST} !^www.mydomain.com$
RewriteRule ^/?(.*) http://www.mydomain.com/$1 [QSA,R=301,L]

This rule will redirects to mydomain.com if another domain is pointing to our website or ip address

 

CaptchaSecurityImages.php Error function imagettfbbox Debian 7

CaptchaSecurityImages.php Error function imagettfbbox Debian 7

Php gd has been installed

Error Image security code not show

Solutions:

Open and edit CaptchaSecurityImages.php

Changed: "var $font = 'monofont.ttf';" to "var $font = './monofont.ttf';"

Save and restart apache2

Note: On CentOS server working good without any modification on code