Dedicated Servers & VPSDecember 10, 2025 8 views

Install Nginx and PHP-FPM on a Linux VPS

Install Nginx and PHP-FPM on a Linux VPS

Introduction

Nginx (pronounced "engine-x") is a high-performance web server, known for its speed, stability, and low resource consumption. Combined with PHP-FPM (FastCGI Process Manager), it forms a powerful stack for hosting modern PHP applications like WordPress, Laravel, Symfony, or Drupal.

Why Choose Nginx + PHP-FPM?

Feature Apache + mod_php Nginx + PHP-FPM
Memory High consumption Low footprint
Simultaneous Connections Limited Thousands
Static Files Good Excellent
Configuration Distributed .htaccess Centralized
Performance Good Excellent

Versions Included per OS

System Nginx PHP Kernel
Debian 13 "Trixie" 1.26 8.4 6.12 LTS
Ubuntu 24.04 LTS 1.24 8.3 6.8

📋 Prerequisites

  • A VPS with Ubuntu 24.04 LTS or Debian 13 "Trixie"
  • Root access or user with sudo privileges
  • Established SSH connection
  • Domain name pointing to the VPS IP (optional but recommended)

🔄 Step 1: System Update

Before any installation, update the system packages:

sudo apt update && sudo apt upgrade -y

If a reboot is required:

[ -f /var/run/reboot-required ] && sudo reboot

📦 Step 2: Install Nginx

Installation

sudo apt install nginx -y

Verify the Installation

nginx -v

Expected Output:

  • Debian 13: nginx version: nginx/1.26.x
  • Ubuntu 24.04: nginx version: nginx/1.24.x

Check Service Status

sudo systemctl status nginx

The service should display active (running).

Nginx Management Commands

Action Command
Start sudo systemctl start nginx
Stop sudo systemctl stop nginx
Restart sudo systemctl restart nginx
Reload config sudo systemctl reload nginx
Enable at boot sudo systemctl enable nginx
Disable at boot sudo systemctl disable nginx
Test configuration sudo nginx -t

Configure Firewall (UFW)

If UFW is active, allow HTTP and HTTPS traffic:

# Check UFW status
sudo ufw status

# Allow Nginx (HTTP + HTTPS)
sudo ufw allow 'Nginx Full'

# Or allow separately
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Test the Installation

Open your browser and access http://YOUR_VPS_IP. You should see the Nginx welcome page with "Welcome to nginx!" message.


🐘 Step 3: Install PHP-FPM

For Debian 13 "Trixie" (PHP 8.4)

sudo apt install php8.4-fpm php8.4-cli php8.4-common php8.4-mysql \
php8.4-zip php8.4-gd php8.4-mbstring php8.4-curl php8.4-xml \
php8.4-bcmath php8.4-intl php8.4-soap php8.4-opcache php8.4-readline -y

For Ubuntu 24.04 LTS (PHP 8.3)

sudo apt install php8.3-fpm php8.3-cli php8.3-common php8.3-mysql \
php8.3-zip php8.3-gd php8.3-mbstring php8.3-curl php8.3-xml \
php8.3-bcmath php8.3-intl php8.3-soap php8.3-opcache php8.3-readline -y

Install Specific Version via PPA (Ubuntu Only)

If you need a different PHP version on Ubuntu:

# Add Ondřej PPA repository
sudo apt install software-properties-common -y
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update

# Example: Install PHP 8.4
sudo apt install php8.4-fpm php8.4-cli php8.4-common php8.4-mysql \
php8.4-zip php8.4-gd php8.4-mbstring php8.4-curl php8.4-xml \
php8.4-bcmath php8.4-intl php8.4-soap php8.4-opcache -y

Verify PHP Installation

php -v

Expected Output:

  • Debian 13: PHP 8.4.x (cli)
  • Ubuntu 24.04: PHP 8.3.x (cli)

Check PHP-FPM Status

Debian 13:

sudo systemctl status php8.4-fpm

Ubuntu 24.04:

sudo systemctl status php8.3-fpm

The service should display active (running).

Identify PHP-FPM Socket

The socket is crucial for communication between Nginx and PHP:

ls /run/php/

Typical Output:

  • Debian 13: php8.4-fpm.sock
  • Ubuntu 24.04: php8.3-fpm.sock

⚙️ Step 4: Configure Nginx for PHP-FPM

Modify Default Configuration

Edit the default configuration file:

sudo nano /etc/nginx/sites-available/default

Configuration for Debian 13 (PHP 8.4)

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;
    index index.php index.html index.htm;

    server_name _;

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

    # PHP-FPM Configuration
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.4-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # Block access to .htaccess files
    location ~ /\.ht {
        deny all;
    }
}

Configuration for Ubuntu 24.04 (PHP 8.3)

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;
    index index.php index.html index.htm;

    server_name _;

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

    # PHP-FPM Configuration
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # Block access to .htaccess files
    location ~ /\.ht {
        deny all;
    }
}

Test the Configuration

sudo nginx -t

Expected Output:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Reload Nginx

sudo systemctl reload nginx

✅ Step 5: Test PHP with Nginx

Create a PHP Test File

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

Access the Test Page

Open your browser: http://YOUR_IP_VPS/info.php

You should see the phpinfo() page displaying:

  • PHP Version (8.4.x or 8.3.x)
  • Server API: FPM/FastCGI
  • Installed Extensions
  • Configuration Variables

Delete the Test File (Security)

sudo rm /var/www/html/info.php

⚠️ Security: Never leave a phpinfo() file in production, as it exposes sensitive information.


🌐 Step 6: Create a Virtual Host (Server Block)

Virtual hosts allow hosting multiple sites on the same server.

Create Site Directory

sudo mkdir -p /var/www/monsite.com/html
sudo chown -R $USER:$USER /var/www/monsite.com
sudo chmod -R 755 /var/www/monsite.com

Create Homepage

nano /var/www/monsite.com/html/index.php

Add:

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>Welcome to MonSite.com</title>
    <style>
        body { font-family: Arial, sans-serif; text-align: center; padding: 50px; }
        h1 { color: #333; }
    </style>
</head>
<body>
    <h1>MonSite.com is working!</h1>
    <p>Nginx + PHP-FPM configured successfully.</p>
    <p>PHP Version: <?php echo phpversion(); ?></p>
</body>
</html>

Create Virtual Host Configuration

sudo nano /etc/nginx/sites-available/monsite.com

For Debian 13 (PHP 8.4):

server {
    listen 80;
    listen [::]:80;

    server_name monsite.com www.monsite.com;
    root /var/www/monsite.com/html;

    index index.php index.html index.htm;

    # Logs
    access_log /var/log/nginx/monsite.com.access.log;
    error_log /var/log/nginx/monsite.com.error.log;

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

    # PHP-FPM
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.4-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # Security - block hidden files
    location ~ /\. {
        deny all;
    }

    # Cache for static files
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|pdf|txt|woff|woff2|ttf|svg)$ {
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }
}

For Ubuntu 24.04 (PHP 8.3): Replace php8.4-fpm.sock with php8.3-fpm.sock.

Enable the Virtual Host

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

Disable Default Site (Optional)

sudo rm /etc/nginx/sites-enabled/default

Test and Reload

sudo nginx -t
sudo systemctl reload nginx

🔒 Step 7: Install an SSL Certificate (Let's Encrypt)

Install Certbot

sudo apt install certbot python3-certbot-nginx -y

Obtain an SSL Certificate

sudo certbot --nginx -d monsite.com -d www.monsite.com

Follow the instructions:

  1. Enter your email address
  2. Agree to the terms
  3. Choose to redirect HTTP to HTTPS (recommended)

Check Automatic Renewal

sudo certbot renew --dry-run

⚡ Step 8: Optimize PHP-FPM

PHP-FPM Pool Configuration

Debian 13:

sudo nano /etc/php/8.4/fpm/pool.d/www.conf

Ubuntu 24.04:

sudo nano /etc/php/8.3/fpm/pool.d/www.conf

Recommended Parameters based on RAM

VPS 1-2 GB RAM:

pm = dynamic
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 500

VPS 4 GB RAM:

pm = dynamic
pm.max_children = 25
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 10
pm.max_requests = 1000

VPS 8+ GB RAM:

pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 2000
user www-data; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 1024; multi_accept on; use epoll; } http { # Basic settings sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; server_tokens off; # Buffer sizes client_max_body_size 64M; client_body_buffer_size 128k; # MIME types include /etc/nginx/mime.types; default_type application/octet-stream; # Logging access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; # Gzip compression gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml; # Includes include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }


Restart Nginx

sudo nginx -t
sudo systemctl restart nginx

🛡️ Step 10: Secure the Installation

Security Headers

Add in your server block configuration:

# Security Headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

Limit Requests (Rate Limiting)

In /etc/nginx/nginx.conf, http section:

# Limiting zones
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;

In your server block:

location / {
    limit_req zone=one burst=20 nodelay;
    limit_conn addr 10;
}

📁 File Structure

Nginx

Path Description
/etc/nginx/nginx.conf Main configuration
/etc/nginx/sites-available/ Available configurations
/etc/nginx/sites-enabled/ Active configurations (symbolic links)
/etc/nginx/snippets/ Configuration snippets
/var/log/nginx/ Access and error logs

PHP-FPM

Path (Debian 13) Path (Ubuntu 24.04) Description
/etc/php/8.4/fpm/php.ini /etc/php/8.3/fpm/php.ini PHP configuration
/etc/php/8.4/fpm/pool.d/www.conf /etc/php/8.3/fpm/pool.d/www.conf Pool configuration
/run/php/php8.4-fpm.sock /run/php/php8.3-fpm.sock FPM socket

Websites

Path Description
/var/www/html/ Default site
/var/www/monsite.com/html/ Root of a custom site

🔧 Useful Commands

Service Management

# Nginx
sudo systemctl start|stop|restart|reload|status nginx

# PHP-FPM (Debian 13)
sudo systemctl start|stop|restart|status php8.4-fpm

# PHP-FPM (Ubuntu 24.04)
sudo systemctl start|stop|restart|status php8.3-fpm

Tests and Diagnostics

# Test Nginx config
sudo nginx -t

# Test PHP-FPM config (Debian 13)
sudo php-fpm8.4 -t

# Test PHP-FPM config (Ubuntu 24.04)
sudo php-fpm8.3 -t

# View PHP-FPM processes
ps aux | grep php-fpm

# View active connections
ss -tlnp | grep -E 'nginx|php'

# Real-time logs
sudo tail -f /var/log/nginx/error.log

Site Management

# Enable a site
sudo ln -s /etc/nginx/sites-available/monsite.com /etc/nginx/sites-enabled/

# Disable a site
sudo rm /etc/nginx/sites-enabled/monsite.com

# List active sites
ls -la /etc/nginx/sites-enabled/

🔍 Troubleshooting

"502 Bad Gateway"

Causes: PHP-FPM not working or incorrect socket

Solutions:

# Check PHP-FPM (adjust version)
sudo systemctl status php8.4-fpm

# Check the socket
ls -la /run/php/

# Restart PHP-FPM
sudo systemctl restart php8.4-fpm

"403 Forbidden"

Causes: Incorrect permissions

Solutions:

# Correct permissions
sudo chown -R www-data:www-data /var/www/monsite.com
sudo chmod -R 755 /var/www/monsite.com

"404 Not Found" for PHP files

Causes: Incorrect PHP-FPM configuration

Checks:

  1. The file exists
  2. The root directive is correct in Nginx
  3. The location ~ \.php$ block is present
  4. The socket matches the installed PHP version

Blank Page (PHP not executing)

Causes: PHP-FPM not connected to Nginx

Solutions:

# Check socket version
ls /run/php/

# Compare with Nginx config
grep fastcgi_pass /etc/nginx/sites-enabled/*

📋 Quick Recap

Complete Installation Debian 13

# Update
sudo apt update && sudo apt upgrade -y

# Nginx
sudo apt install nginx -y

# PHP-FPM 8.4
sudo apt install php8.4-fpm php8.4-cli php8.4-common php8.4-mysql \
php8.4-zip php8.4-gd php8.4-mbstring php8.4-curl php8.4-xml \
php8.4-bcmath php8.4-intl php8.4-opcache -y

# Firewall
sudo ufw allow 'Nginx Full'

# SSL
sudo apt install certbot python3-certbot-nginx -y

Complete Installation Ubuntu 24.04

# Update
sudo apt update && sudo apt upgrade -y

# Nginx
sudo apt install nginx -y

# PHP-FPM 8.3
sudo apt install php8.3-fpm php8.3-cli php8.3-common php8.3-mysql \
php8.3-zip php8.3-gd php8.3-mbstring php8.3-curl php8.3-xml \
php8.3-bcmath php8.3-intl php8.3-opcache -y

# Firewall
sudo ufw allow 'Nginx Full'

# SSL
sudo apt install certbot python3-certbot-nginx -y

💡 Best Practices

  1. Always test the configuration before reloading: sudo nginx -t

  2. Use separate virtual hosts for each site

  3. Enable HTTPS with Let's Encrypt for all sites

  4. Regularly monitor logs to detect issues

  5. Backup your configurations before making changes

  6. Optimize PHP-FPM according to your VPS resources

  7. Regularly update Nginx and PHP for security

  8. Remove test files (info.php) after verification