Blog

  • CresignSys Learn — Lesson 064

    Build the hosting-create Provisioning Engine

    We now move from learning individual server components to building the actual automation layer for your CresignSys Hosting Platform.

    The goal is:

    sudo hosting-create example.com

    and the server automatically performs the required provisioning steps.


    1. What Are We Building?

    We want a command:

    hosting-create DOMAIN

    For example:

    sudo hosting-create learn.cresignsys.com

    The system should create:

    Domain
     ↓
    Site ID
     ↓
    Linux user
     ↓
    Website directories
     ↓
    Permissions
     ↓
    MySQL database
     ↓
    MySQL user
     ↓
    PHP-FPM pool
     ↓
    Nginx configuration
     ↓
    WordPress
     ↓
    SSL
     ↓
    Health check

    2. Why Build Our Own Tool?

    Instead of manually doing:

    mkdir
    useradd
    chown
    mysql
    wp
    nginx
    certbot
    systemctl

    for every website, create one controlled interface:

    sudo hosting-create domain.com

    This becomes the foundation of your own:

    CresignSys Hosting Platform — CHP


    3. High-Level Architecture

                         HOSTING-CREATE
                               │
                 ┌─────────────┼─────────────┐
                 │             │             │
                 ▼             ▼             ▼
              Linux          MySQL          PHP-FPM
                 │             │             │
                 └─────────────┼─────────────┘
                               │
                               ▼
                             Nginx
                               │
                               ▼
                           WordPress
                               │
                               ▼
                              SSL

    4. Directory Structure

    We should keep the hosting platform organized.

    /etc/cresignsys/
    │
    ├── hosting.conf
    │
    ├── nginx-templates/
    │   └── wordpress.conf
    │
    ├── php-templates/
    │   └── wordpress-pool.conf
    │
    └── scripts/
        ├── common.sh
        ├── mysql.sh
        ├── nginx.sh
        ├── php-fpm.sh
        └── wordpress.sh

    Command:

    /usr/local/bin/hosting-create

    5. Website Storage

    Your websites can remain under:

    /storage/websites/

    For example:

    /storage/websites/
    │
    ├── learn.cresignsys.com/
    │   └── public/
    │
    ├── shop.cresignsys.com/
    │   └── public/
    │
    └── example.com/
        └── public/

    6. Central Configuration

    Create:

    /etc/cresignsys/hosting.conf

    Conceptually:

    WEB_ROOT_BASE="/storage/websites"
    NGINX_AVAILABLE="/etc/nginx/sites-available"
    NGINX_ENABLED="/etc/nginx/sites-enabled"
    PHP_SOCKET_BASE="/run/php"

    Now the script doesn’t need these paths hard-coded everywhere.


    7. Why Central Configuration?

    Suppose later you change:

    /storage/websites

    to:

    /storage/hosting

    You should ideally change:

    hosting.conf

    rather than editing ten different scripts.


    8. Script Entry Point

    Create:

    /usr/local/bin/hosting-create

    The first line:

    #!/usr/bin/env bash

    This tells Linux to execute the script using Bash.


    9. Strict Bash Mode

    A good starting point is:

    set -Eeuo pipefail

    This provides stronger error handling.

    Conceptually:

    -e
    → stop when a command fails
    
    -u
    → detect unset variables
    
    -E
    → preserve ERR traps
    
    pipefail
    → detect failures inside pipelines

    10. Require Root

    Website provisioning needs privileged operations.

    Therefore:

    if [[ $EUID -ne 0 ]]; then
        echo "Run as root."
        exit 1
    fi

    Then:

    sudo hosting-create example.com

    works because sudo executes the script as root.


    11. Validate Arguments

    The command requires a domain:

    hosting-create example.com

    If somebody runs:

    hosting-create

    the script should stop.

    Conceptually:

    if [[ $# -ne 1 ]]; then
        echo "Usage: hosting-create DOMAIN"
        exit 1
    fi

    12. Store the Domain

    DOMAIN="$1"

    Now:

    DOMAIN
    =
    example.com

    13. Domain Validation

    Never directly use arbitrary user input in:

    Linux usernames
    SQL identifiers
    file paths
    Nginx configuration

    First validate and normalize it.

    For example:

    example.com

    is acceptable.

    But:

    ../../something

    must never become a filesystem path.


    14. Generate Site ID

    The domain:

    learn.cresignsys.com

    could become:

    learn_cresignsys_com

    Conceptually:

    SITE_ID="${DOMAIN//./_}"

    But a production implementation should also remove/reject unsafe characters and enforce length/uniqueness rules.


    15. Don’t Trust the Site ID Blindly

    A safe provisioning system should check:

    allowed characters
    maximum length
    reserved names
    existing users
    existing directories
    existing databases
    existing Nginx configuration

    before creating anything.


    16. Detect Existing Website

    Before provisioning:

    Does directory exist?
    Does Linux user exist?
    Does database exist?
    Does PHP pool exist?
    Does Nginx config exist?

    If the site already exists, don’t blindly overwrite it.


    17. Idempotency

    A very important automation concept:

    Idempotency

    A provisioning command should ideally be safe to run again or should detect that provisioning has already occurred.

    For example:

    hosting-create example.com

    first run:

    CREATE

    second run:

    ALREADY EXISTS

    rather than destroying the website.


    18. Provisioning State

    Create a state directory:

    /var/lib/cresignsys/sites/

    For example:

    /var/lib/cresignsys/sites/example.com/

    Store metadata such as:

    status
    site_id
    created_at
    php_version
    database_name

    19. Site Metadata

    A conceptual record:

    DOMAIN=learn.cresignsys.com
    SITE_ID=learn_cresignsys_com
    USER=learn_cresignsys_com
    DATABASE=learn_cresignsys_com_db
    DB_USER=learn_cresignsys_com_dbuser
    PHP_SOCKET=/run/php/learn_cresignsys_com.sock
    WEB_ROOT=/storage/websites/learn.cresignsys.com/public

    This gives every component a common identity.


    20. Step 1 — Create Linux User

    The provisioning engine checks:

    Does user exist?

    If not:

    create user

    If it already exists:

    don't recreate it

    This is safer than:

    useradd ...

    every time.


    21. Step 2 — Create Directories

    Create:

    /storage/websites/example.com/

    with:

    public/
    logs/
    private/

    For example:

    /storage/websites/example.com/
    ├── public/
    ├── logs/
    └── private/

    22. Why Separate Directories?

    public

    Web-accessible files.

    logs

    Site-related logs if your architecture uses them.

    private

    Files that must not be directly accessible from HTTP.


    23. Step 3 — Set Ownership

    The site user should own its website files according to your chosen security model.

    For example:

    example.com/
    owner = example_user
    group = example_user

    24. Step 4 — Create Database

    The script generates:

    DATABASE_NAME
    DATABASE_USER
    DATABASE_PASSWORD

    For example:

    example_db
    example_dbuser
    [random password]

    The password should be generated securely.


    25. Generate Secrets

    Don’t use:

    password123

    or:

    example.com123

    Use a cryptographically secure random generator.

    For example, Linux provides:

    openssl rand -base64 32

    or other secure methods.

    The exact secret-management strategy becomes especially important when building a control panel.


    26. Database Password Storage

    Do not casually store database passwords in:

    public/

    or:

    Nginx configuration

    The password belongs in the site’s protected configuration.

    WordPress itself needs the credential, so the file containing it must have appropriate permissions.


    27. Step 5 — PHP-FPM Pool

    Generate:

    /etc/php/<version>/fpm/pool.d/example.conf

    from a template.

    The template receives:

    SITE_ID
    USER
    GROUP
    SOCKET

    28. Template Concept

    Instead of manually generating:

    [example]
    user = example_user
    group = example_user
    listen = /run/php/example.sock

    create a reusable template:

    [{{SITE_ID}}]
    
    user = {{SITE_USER}}
    group = {{SITE_USER}}
    
    listen = {{PHP_SOCKET}}

    Then replace the variables.


    29. Why Templates?

    You can have:

    100 websites

    but only:

    1 standard PHP-FPM template

    This dramatically reduces configuration inconsistencies.


    30. Validate PHP-FPM

    After creating a pool:

    PHP-FPM configuration
            ↓
    validate
            ↓
    reload PHP-FPM

    Don’t reload first and discover later that the configuration is invalid.


    31. Step 6 — Nginx Template

    Use:

    /etc/cresignsys/nginx-templates/wordpress.conf

    Variables:

    DOMAIN
    WEB_ROOT
    PHP_SOCKET

    Generated configuration:

    /etc/nginx/sites-available/example.com

    32. Enable Nginx Site

    Create the symlink:

    sites-available/example.com
              ↓
    sites-enabled/example.com

    Then:

    nginx -t

    If successful:

    systemctl reload nginx

    33. Never Skip nginx -t

    Your automation should follow:

    write config
     ↓
    nginx -t
     ↓
    success?
     ├── NO → stop
     └── YES
           ↓
        reload

    This prevents a bad site configuration from being blindly activated.


    34. Step 7 — WordPress

    Once:

    Nginx ✓
    PHP-FPM ✓
    MySQL ✓

    the script downloads WordPress.

    Use WP-CLI where possible.


    35. Why WP-CLI Is Ideal

    Your hosting system can execute:

    wp core download
    wp config create
    wp core install
    wp option update
    wp plugin install

    This makes WordPress provisioning highly automatable.


    36. WordPress Configuration

    The script supplies:

    DB_NAME
    DB_USER
    DB_PASSWORD
    DB_HOST

    and creates:

    wp-config.php

    37. WordPress Installation

    Then supply:

    URL
    title
    administrator username
    administrator password
    administrator email

    The site becomes operational.


    38. Step 8 — SSL

    SSL should be installed only after:

    DNS ✓
    HTTP ✓
    Nginx ✓

    Otherwise certificate validation can fail.


    39. SSL Workflow

    DNS
     ↓
    HTTP website
     ↓
    Certificate request
     ↓
    Certificate issued
     ↓
    Nginx HTTPS configuration
     ↓
    HTTP → HTTPS redirect

    40. Step 9 — Health Check

    Your provisioning engine should not simply assume success.

    Check:

    Nginx running?
    PHP-FPM running?
    MySQL running?
    socket exists?
    database accessible?
    WordPress installed?
    HTTPS accessible?

    41. Health Check Example

    Conceptually:

    [✓] Linux user
    [✓] Website directory
    [✓] Database
    [✓] Database user
    [✓] PHP-FPM pool
    [✓] PHP socket
    [✓] Nginx configuration
    [✓] WordPress
    [✓] SSL
    [✓] HTTPS

    Then:

    SITE STATUS: ACTIVE

    42. Failure Handling

    Suppose:

    [✓] Linux user
    [✓] Directory
    [✓] Database
    [✓] PHP-FPM
    [✗] Nginx

    The script should produce something like:

    Provisioning failed.
    Stage: Nginx
    Reason: configuration test failed.

    Not:

    Website created successfully.

    43. Logging

    Create:

    /var/log/cresignsys/

    Then:

    /var/log/cresignsys/hosting-create.log

    The provisioning engine can record:

    timestamp
    domain
    stage
    success/failure
    error

    44. Example Log

    2026-08-13 15:20 example.com CREATE_USER SUCCESS
    2026-08-13 15:20 example.com CREATE_DIRECTORY SUCCESS
    2026-08-13 15:20 example.com CREATE_DATABASE SUCCESS
    2026-08-13 15:21 example.com CREATE_PHP_POOL SUCCESS
    2026-08-13 15:21 example.com CREATE_NGINX SUCCESS
    2026-08-13 15:21 example.com NGINX_TEST SUCCESS
    2026-08-13 15:22 example.com WORDPRESS SUCCESS
    2026-08-13 15:23 example.com SSL SUCCESS
    2026-08-13 15:23 example.com HEALTH_CHECK SUCCESS

    45. Recommended Script Structure

    Rather than putting everything into one enormous Bash file:

    hosting-create

    can call helper functions/scripts.

    For example:

    hosting-create
    │
    ├── validate
    ├── create-user
    ├── create-files
    ├── create-database
    ├── create-php
    ├── create-nginx
    ├── install-wordpress
    ├── install-ssl
    └── health-check

    This makes debugging easier.


    46. Function-Based Design

    Even if everything remains in one Bash script initially, divide it into functions:

    validate_domain()
    create_site_user()
    create_directories()
    create_database()
    create_php_pool()
    create_nginx_config()
    install_wordpress()
    install_ssl()
    health_check()

    Then the main flow becomes:

    validate
     ↓
    create user
     ↓
    create directories
     ↓
    create database
     ↓
    create PHP
     ↓
    create Nginx
     ↓
    WordPress
     ↓
    SSL
     ↓
    health check

    47. Validation Before Creation

    A strong design validates:

    domain syntax
    available disk space
    PHP version
    MySQL availability
    Nginx availability
    WP-CLI availability
    SSL tool availability
    DNS status

    before performing irreversible operations.


    48. Disk Space Check

    Before creating a website:

    df -h /storage

    If storage is almost full:

    don't provision

    Instead:

    ERROR: insufficient storage

    49. Memory Check

    You can inspect:

    free -h

    This is important because creating many PHP-FPM pools can increase memory usage.


    50. CPU Check

    Check:

    nproc

    This tells you the number of available processing units.

    It helps inform PHP-FPM sizing.


    51. Never Automatically Choose Huge PHP Limits

    Your script should not create every site with:

    pm.max_children = 100

    Instead, use a centrally defined profile.

    For example:

    Starter
    Business
    Professional

    Each profile can have resource settings appropriate to the plan.


    52. Hosting Plan Profiles

    For example:

    STARTER
    PHP workers: low
    
    BUSINESS
    PHP workers: moderate
    
    PROFESSIONAL
    PHP workers: higher

    These should be tuned from actual server capacity and workload rather than arbitrary marketing numbers.


    53. This Connects to Your Hosting Plans

    Your hosting platform can eventually store:

    Plan
     ↓
    Storage limit
     ↓
    PHP worker limit
     ↓
    Database limit
     ↓
    Bandwidth policy
     ↓
    Backup policy

    Then provisioning reads the customer’s plan.


    54. Example

    Customer chooses:

    Business

    The platform creates:

    5 GB storage
    appropriate PHP-FPM limits
    database
    backup policy
    SSL

    This turns your infrastructure into an actual hosting product.


    55. Site Database

    Your control panel itself can maintain a database containing:

    sites

    Example fields:

    id
    domain
    site_id
    linux_user
    document_root
    database_name
    database_user
    php_version
    plan_id
    status
    created_at

    56. Why Have Two Database Layers?

    You now have:

    Hosting control database

    Stores:

    which websites exist

    WordPress database

    Stores:

    what each WordPress website contains

    They serve different purposes.


    57. Example

    Control database:

    site_id = 27
    domain = learn.cresignsys.com
    plan = business
    status = active

    WordPress database:

    wp_posts
    wp_users
    wp_options
    ...

    58. This Is the Control Plane

    Your hosting panel becomes the:

    Control Plane

    while the actual websites are:

    Workloads

    Conceptually:

                     CONTROL PLANE
                          │
              ┌───────────┼───────────┐
              ▼           ▼           ▼
            Site 1      Site 2      Site 3
            workload    workload    workload

    59. Provisioning Is the Bridge

    The control panel says:

    Create site example.com

    The provisioning engine translates that request into:

    Linux
    +
    Nginx
    +
    PHP-FPM
    +
    MySQL
    +
    WordPress
    +
    SSL

    60. The Long-Term CHP Architecture

                         CHP PANEL
                             │
                             ▼
                      SITE DATABASE
                             │
                             ▼
                    PROVISIONING ENGINE
                             │
              ┌──────────────┼──────────────┐
              ▼              ▼              ▼
            Linux          Nginx          MySQL
              │              │              │
              └──────────────┼──────────────┘
                             ▼
                          PHP-FPM
                             │
                             ▼
                        WordPress
                             │
                             ▼
                            SSL

    61. Important Security Rule

    The web browser should never directly execute:

    hosting-create

    The control panel must authenticate and authorize the request first.

    Eventually:

    Admin
     ↓
    CHP Panel
     ↓
    authenticated API
     ↓
    provisioning service
     ↓
    root-level operations

    62. Don’t Run the Web Application as Root

    This is critical.

    Do not make:

    PHP
    WordPress
    control-panel web process

    run as root merely because provisioning requires root.

    Instead:

    Web application
     ↓
    restricted user
     ↓
    controlled provisioning mechanism

    63. Why?

    If a WordPress vulnerability or panel vulnerability occurs and the application itself has root privileges:

    application compromise
     ↓
    root compromise
     ↓
    entire server

    The blast radius becomes enormous.


    64. Separate Control Plane and Workload

    Your architecture should eventually look like:

    CHP Web Application
            │
            │ controlled request
            ▼
    Provisioning Service
            │
            │ privileged operations
            ▼
    Server

    rather than:

    WordPress/PHP
            │
            ▼
    root shell

    65. Lesson 064 — Core Principle

    The provisioning engine is the automation bridge between your control panel and the Linux server.

    The command:

    sudo hosting-create example.com

    is conceptually:

    INPUT
      ↓
    VALIDATE
      ↓
    CREATE
      ↓
    CONFIGURE
      ↓
    TEST
      ↓
    ACTIVATE

    not simply:

    INPUT
      ↓
    RUN 20 COMMANDS

    66. Final Architecture

                     CresignSys Hosting Platform
                               │
                               ▼
                         hosting-create
                               │
              ┌────────────────┼────────────────┐
              ▼                ▼                ▼
          Linux User        MySQL            PHP-FPM
              │                │                │
              ▼                ▼                ▼
           Website          Database          Socket
              │                │                │
              └────────────────┼────────────────┘
                               ▼
                             Nginx
                               │
                               ▼
                           WordPress
                               │
                               ▼
                              SSL
                               │
                               ▼
                         HEALTH CHECK
                               │
                               ▼
                             ACTIVE

    Next Lesson — 065

    Build the First Working hosting-create Script

    The next lesson will be practical.

    We will build the first version of:

    sudo hosting-create example.com

    using Bash, with:

    • domain validation
    • safe site-ID generation
    • Linux user creation
    • directory creation
    • ownership/permissions
    • MySQL database creation
    • database-user creation
    • PHP-FPM pool generation
    • Nginx template generation
    • configuration validation
    • WordPress installation
    • error handling
    • logging
    • final health check

    The goal will be a real working first-generation CresignSys provisioning script, rather than only pseudocode.

  • CresignSys Learn — Lesson 063

    WordPress Installation Automation — From Empty Domain to Working Website

    We now combine the previous lessons into a complete hosting workflow.

    The objective is to understand how a new domain goes from:

    Empty domain
          ↓
    DNS
          ↓
    Server
          ↓
    Nginx
          ↓
    PHP-FPM
          ↓
    MySQL
          ↓
    WordPress
          ↓
    SSL
          ↓
    Working website

    1. The Final Architecture

    For one website:

    learn.cresignsys.com
            │
            ▼
          DNS
            │
            ▼
       Public IP address
            │
            ▼
          Nginx
            │
            ▼
       PHP-FPM pool
            │
            ▼
        WordPress
            │
            ▼
          MySQL

    The filesystem is:

    /storage/websites/
    └── learn.cresignsys.com/
        └── public/

    2. What We Want to Automate

    Instead of manually performing 15–20 commands for every website, we want:

    sudo hosting-create learn.cresignsys.com

    to eventually perform the provisioning process.

    Conceptually:

    hosting-create
           │
           ├── create user
           ├── create directories
           ├── set permissions
           ├── create database
           ├── create database user
           ├── create PHP-FPM pool
           ├── create Nginx config
           ├── validate Nginx
           ├── reload services
           ├── download WordPress
           ├── configure wp-config.php
           └── install SSL

    3. Step 1 — Domain

    Start with:

    learn.cresignsys.com

    Your hosting system should first validate the domain.

    For example:

    DOMAIN=learn.cresignsys.com

    4. Generate a Site ID

    Don’t blindly use arbitrary domain text as a Linux username.

    Generate a safe internal identifier.

    For example:

    learn_cresignsys_com

    You can use this internally for:

    Linux user
    PHP-FPM pool
    database naming
    logging
    configuration

    5. Site Configuration

    A site record could conceptually contain:

    DOMAIN:
    learn.cresignsys.com
    
    SITE_ID:
    learn_cresignsys_com
    
    WEB_ROOT:
    /storage/websites/learn.cresignsys.com/public
    
    LINUX_USER:
    learn_cresignsys_com
    
    DATABASE:
    learn_cresignsys_com_db
    
    DATABASE_USER:
    learn_cresignsys_com_dbuser

    Your actual naming scheme can be shorter.


    6. Step 2 — Create Directory

    Create:

    sudo mkdir -p /storage/websites/learn.cresignsys.com/public

    Now:

    /storage/websites/
    └── learn.cresignsys.com/
        └── public/

    7. Why mkdir -p?

    The:

    -p

    option creates missing parent directories as necessary.

    Therefore:

    mkdir -p /storage/websites/domain.com/public

    can create the entire directory path if it doesn’t already exist.


    8. Step 3 — Create Linux User

    Create a dedicated hosting identity.

    Conceptually:

    sudo useradd ...

    The exact account configuration should match your hosting architecture.

    For example:

    site user
        ↓
    website files
        ↓
    PHP-FPM pool

    9. Step 4 — Ownership

    Set the website ownership appropriately.

    For example:

    sudo chown -R siteuser:siteuser /storage/websites/learn.cresignsys.com

    Then verify:

    ls -la /storage/websites/learn.cresignsys.com

    10. Step 5 — Directory Permissions

    Start with a restrictive model.

    For example:

    sudo chmod 755 /storage/websites/learn.cresignsys.com
    sudo chmod 755 /storage/websites/learn.cresignsys.com/public

    Do not use:

    chmod -R 777

    11. Step 6 — MySQL Database

    Create a database:

    CREATE DATABASE learn_cresignsys_com_db
    CHARACTER SET utf8mb4
    COLLATE utf8mb4_unicode_ci;

    12. Step 7 — Database User

    Create a dedicated user:

    CREATE USER 'learn_dbuser'@'localhost'
    IDENTIFIED BY 'STRONG_RANDOM_PASSWORD';

    Use a generated random password in automation rather than a hard-coded password.


    13. Step 8 — Database Privileges

    Grant access only to this database:

    GRANT ALL PRIVILEGES
    ON learn_cresignsys_com_db.*
    TO 'learn_dbuser'@'localhost';

    The important relationship is:

    learn_dbuser
          ↓
    learn_cresignsys_com_db

    not:

    learn_dbuser
          ↓
    ALL DATABASES

    14. Step 9 — PHP-FPM Pool

    Create a dedicated PHP-FPM pool.

    Conceptually:

    site:
    learn
    
    user:
    siteuser
    
    group:
    siteuser
    
    socket:
    /run/php/learn.sock

    15. Example Pool

    A simplified configuration:

    [learn]
    
    user = siteuser
    group = siteuser
    
    listen = /run/php/learn.sock
    
    pm = dynamic
    pm.max_children = 10
    pm.start_servers = 2
    pm.min_spare_servers = 2
    pm.max_spare_servers = 5
    pm.max_requests = 500

    These values are examples for learning, not universal production settings.


    16. Why Dedicated Pool?

    The request becomes:

    Nginx
     ↓
    learn.sock
     ↓
    learn PHP-FPM pool
     ↓
    siteuser
     ↓
    WordPress

    This connects:

    domain
    +
    PHP
    +
    Linux identity

    17. Step 10 — Nginx Server Block

    Create:

    /etc/nginx/sites-available/learn.cresignsys.com

    A simplified configuration:

    server {
        listen 80;
        server_name learn.cresignsys.com;
    
        root /storage/websites/learn.cresignsys.com/public;
        index index.php index.html;
    
        location / {
            try_files $uri $uri/ /index.php?$args;
        }
    
        location ~ \.php$ {
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_pass unix:/run/php/learn.sock;
        }
    }

    This is an educational baseline. Production configurations should be hardened and adapted to the PHP-FPM version and your exact Nginx layout.


    18. Understand the Server Block

    This line:

    server_name learn.cresignsys.com;

    means:

    Request for learn.cresignsys.com
            ↓
    this server block

    19. Document Root

    This:

    root /storage/websites/learn.cresignsys.com/public;

    means the web root is:

    /storage/websites/learn.cresignsys.com/public

    20. WordPress Rewrite

    This:

    try_files $uri $uri/ /index.php?$args;

    is critical.

    For:

    /about/

    Nginx can eventually send the request to:

    index.php

    and WordPress determines which page should be returned.


    21. PHP Routing

    This:

    location ~ \.php$

    matches PHP requests.

    Then:

    fastcgi_pass unix:/run/php/learn.sock;

    sends PHP processing to:

    learn PHP-FPM pool

    22. Step 11 — Enable Site

    On systems using sites-available / sites-enabled, create the symbolic link:

    sudo ln -s /etc/nginx/sites-available/learn.cresignsys.com \
    /etc/nginx/sites-enabled/learn.cresignsys.com

    Your exact Nginx installation may instead use another configuration directory.


    23. Step 12 — Validate Nginx

    Never immediately reload after generating a configuration.

    First:

    sudo nginx -t

    You want:

    syntax is ok
    test is successful

    24. Step 13 — Reload Nginx

    If validation succeeds:

    sudo systemctl reload nginx

    A reload normally allows Nginx to apply the new configuration without requiring a full machine reboot.


    25. Step 14 — Restart/Reload PHP-FPM

    After adding a new pool, reload the relevant PHP-FPM service.

    For example:

    sudo systemctl reload php8.3-fpm

    Use the PHP version actually installed on your server.


    26. Check the PHP Socket

    Run:

    ls -l /run/php/

    You should find your socket, for example:

    learn.sock

    If it doesn’t exist:

    Nginx
     ↓
    missing socket
     ↓
    502

    27. Step 15 — Test Nginx

    Before installing WordPress, create a simple test file:

    echo "CresignSys OK" | sudo tee \
    /storage/websites/learn.cresignsys.com/public/index.html

    Then:

    curl -I http://learn.cresignsys.com

    If everything is correct:

    HTTP/1.1 200 OK

    28. Browser Test

    Open:

    http://learn.cresignsys.com

    You should see:

    CresignSys OK

    This confirms:

    DNS
     ↓
    Nginx
     ↓
    document root
     ↓
    static file

    are working.


    29. Remove the Test File

    Once confirmed:

    sudo rm /storage/websites/learn.cresignsys.com/public/index.html

    Now the directory is ready for WordPress.


    30. Step 16 — Download WordPress

    From the site’s public directory:

    cd /storage/websites/learn.cresignsys.com/public

    Then download WordPress.

    A standard approach is:

    sudo -u siteuser wp core download

    if WP-CLI is installed and configured for your environment.


    31. Why Use WP-CLI?

    WP-CLI allows you to automate WordPress management from the command line.

    Instead of:

    browser
     ↓
    WordPress installation wizard

    you can use:

    terminal
     ↓
    WP-CLI
     ↓
    WordPress

    This is ideal for hosting automation.


    32. WP-CLI Installation

    Check:

    wp --info

    You may see:

    OS:
    PHP binary:
    PHP version:
    WP-CLI version:

    If WP-CLI isn’t installed, install it separately before building the provisioning script.


    33. Step 17 — Create wp-config.php

    WP-CLI can generate configuration.

    Conceptually:

    wp config create \
      --dbname=learn_cresignsys_com_db \
      --dbuser=learn_dbuser \
      --dbpass='PASSWORD' \
      --dbhost=localhost

    This generates:

    wp-config.php

    with the database connection information.


    34. Why wp-config.php Matters

    It connects:

    WordPress
          ↓
    MySQL

    It contains information such as:

    DB_NAME
    DB_USER
    DB_PASSWORD
    DB_HOST

    It also contains WordPress authentication salts and other configuration.


    35. Don’t Put Passwords in Shell History

    Be careful with commands such as:

    --dbpass='password'

    because secrets can accidentally become visible through:

    shell history
    process listings
    logs
    scripts

    A production provisioning system should handle secrets carefully.


    36. Step 18 — Install WordPress

    You can use WP-CLI:

    wp core install \
      --url='https://learn.cresignsys.com' \
      --title='Learn' \
      --admin_user='admin' \
      --admin_password='STRONG_PASSWORD' \
      --admin_email='admin@example.com'

    Again, do not hard-code production credentials.


    37. Better Admin Username

    Avoid using:

    admin

    as the primary administrator username when creating a new WordPress installation.

    Use a unique administrator account name.


    38. Strong Password

    Use a generated password rather than:

    admin123

    or:

    password

    A hosting platform should generate strong credentials automatically.


    39. WordPress Installation Flow

    At this point:

    Nginx
     ↓
    PHP-FPM
     ↓
    WordPress
     ↓
    MySQL

    should be functional.


    40. Step 19 — Check WordPress

    Run:

    wp core is-installed

    A successful installation should report that WordPress is installed.

    You can also:

    wp option get siteurl

    and:

    wp option get home

    41. Check Database Connection

    Run:

    wp db check

    If successful, WP-CLI should confirm the database connection.

    This is a very useful provisioning test.


    42. Step 20 — Permissions

    After WordPress installation:

    sudo chown -R siteuser:siteuser \
    /storage/websites/learn.cresignsys.com

    Then apply your intended directory/file permissions.

    Avoid blindly applying one recursive mode to everything.


    43. WordPress File Model

    Conceptually:

    public/
    ├── index.php
    ├── wp-admin/
    ├── wp-includes/
    ├── wp-content/
    │   ├── plugins/
    │   ├── themes/
    │   └── uploads/
    └── wp-config.php

    44. Important Files

    index.php

    Entry point.

    wp-config.php

    Database and core configuration.

    wp-content/

    Site-specific content.

    wp-admin/

    Administration interface.

    wp-includes/

    WordPress core libraries.


    45. Step 21 — DNS

    Now your domain needs to point to your server.

    For:

    learn.cresignsys.com

    you need the appropriate DNS record.

    For example:

    A
    learn.cresignsys.com
    →
    YOUR_SERVER_IP

    If using IPv6, an appropriate AAAA record may also be configured.


    46. DNS Verification

    From your computer:

    nslookup learn.cresignsys.com

    or:

    nslookup learn.cresignsys.com 8.8.8.8

    You should see your server IP.


    47. Important

    Do not confuse:

    DNS points correctly

    with:

    Nginx configured correctly

    Both are required.


    48. Troubleshooting DNS

    If:

    nslookup

    returns:

    wrong IP

    the problem is DNS.

    If it returns the correct IP but the site doesn’t work:

    DNS ✓

    then investigate:

    network
    Nginx
    PHP-FPM
    WordPress

    49. Step 22 — HTTP Test

    Before SSL:

    curl -I http://learn.cresignsys.com

    Expected:

    HTTP/1.1 200 OK

    or possibly a redirect depending on your configuration.


    50. Step 23 — SSL

    Once HTTP works, configure HTTPS.

    For a typical public website, Let’s Encrypt is a common certificate source.

    Your final flow becomes:

    https://learn.cresignsys.com
            ↓
    443
            ↓
    Nginx
            ↓
    PHP-FPM
            ↓
    WordPress

    51. Why Test HTTP First?

    If you configure everything simultaneously:

    DNS
    +
    Nginx
    +
    PHP
    +
    WordPress
    +
    SSL

    and the site fails, troubleshooting becomes harder.

    Instead:

    DNS
     ↓
    HTTP
     ↓
    Nginx
     ↓
    PHP
     ↓
    WordPress
     ↓
    SSL

    Test one layer at a time.


    52. Certificate Validation

    After SSL installation:

    curl -I https://learn.cresignsys.com

    You want a successful HTTPS response.

    For example:

    HTTP/2 200

    or a legitimate redirect.


    53. Test Certificate

    You can inspect TLS with:

    openssl s_client \
    -connect learn.cresignsys.com:443 \
    -servername learn.cresignsys.com

    This is useful for advanced certificate troubleshooting.


    54. HTTP → HTTPS Redirect

    A common final configuration is:

    http://learn.cresignsys.com
              ↓
    301
              ↓
    https://learn.cresignsys.com

    Then:

    HTTPS
     ↓
    Nginx
     ↓
    WordPress

    55. Why 301?

    A permanent redirect communicates that the preferred URL has moved permanently.

    Example:

    HTTP
     ↓
    301
     ↓
    HTTPS

    56. Final Website Test

    Test:

    curl -I https://learn.cresignsys.com

    Then:

    curl -IL http://learn.cresignsys.com

    You want to understand every response.

    For example:

    HTTP
     ↓
    301
     ↓
    HTTPS
     ↓
    200

    57. Test WordPress

    Run:

    wp core is-installed

    Then:

    wp db check

    Then:

    wp option get home

    Then:

    wp option get siteurl

    58. Test PHP-FPM

    Check:

    sudo systemctl status php8.3-fpm

    Then:

    ls -l /run/php/

    Confirm the expected socket exists.


    59. Test Nginx

    Run:

    sudo nginx -t

    Then:

    sudo systemctl status nginx

    60. Test MySQL

    Run:

    sudo systemctl status mysql

    Then:

    wp db check

    This tests the application-to-database path.


    61. Complete Health Check

    Your provisioning system can eventually run:

    DNS ✓
     ↓
    Nginx ✓
     ↓
    PHP-FPM ✓
     ↓
    PHP socket ✓
     ↓
    WordPress ✓
     ↓
    Database ✓
     ↓
    HTTPS ✓

    Only then mark the site:

    ACTIVE

    62. Site Status

    Your hosting database could maintain:

    PENDING
    PROVISIONING
    ACTIVE
    SUSPENDED
    ERROR
    DELETING

    For example:

    learn.cresignsys.com
    STATUS = ACTIVE

    63. What Happens If Provisioning Fails?

    Suppose:

    1. Linux user ✓
    2. Directory ✓
    3. Database ✓
    4. PHP-FPM ✓
    5. Nginx ✗

    Your automation should not report:

    Website created successfully

    Instead:

    PROVISIONING FAILED
    Stage: Nginx configuration
    Reason: nginx -t failed

    64. Atomic Provisioning

    A professional provisioning system should be designed so that partial failures are handled safely.

    Conceptually:

    Create
     ↓
    Validate
     ↓
    Continue
     ↓
    Validate
     ↓
    Continue

    rather than:

    run 20 commands
     ↓
    hope everything worked

    65. Example Provisioning State

    CREATE USER
          ↓
    SUCCESS
          ↓
    CREATE DIRECTORY
          ↓
    SUCCESS
          ↓
    CREATE DATABASE
          ↓
    SUCCESS
          ↓
    CREATE PHP-FPM
          ↓
    SUCCESS
          ↓
    CREATE NGINX
          ↓
    FAIL

    The system should record:

    site status = ERROR
    failed stage = NGINX

    and preserve enough information to repair or roll back safely.


    66. Rollback

    If a provisioning operation fails, you may need to remove resources that were already created.

    For example:

    database
    user
    directory
    PHP pool
    Nginx config

    But rollback should be deliberate.

    Never automatically delete customer data without carefully defining the lifecycle rules.


    67. Provisioning Log

    For each site, keep a log such as:

    2026-08-13 15:10 CREATE USER
    2026-08-13 15:10 CREATE DIRECTORY
    2026-08-13 15:11 CREATE DATABASE
    2026-08-13 15:11 CREATE PHP POOL
    2026-08-13 15:11 CREATE NGINX CONFIG
    2026-08-13 15:11 NGINX TEST
    2026-08-13 15:12 WORDPRESS INSTALL
    2026-08-13 15:12 SSL INSTALL
    2026-08-13 15:13 HEALTH CHECK
    2026-08-13 15:13 ACTIVE

    This will become very valuable when you have many websites.


    68. Your Hosting Platform Becomes a State Machine

    Conceptually:

    NEW
     ↓
    PROVISIONING
     ↓
    CONFIGURED
     ↓
    TESTING
     ↓
    ACTIVE

    Failure:

    PROVISIONING
     ↓
    ERROR

    Suspension:

    ACTIVE
     ↓
    SUSPENDED

    Deletion:

    SUSPENDED
     ↓
    DELETING
     ↓
    DELETED

    This is much more reliable than simply checking whether a directory exists.


    69. Manual vs Automated

    Manual

    20 commands
    ×
    100 websites
    =
    2000+ operations

    Automated

    hosting-create domain.com

    and the system performs the defined workflow.

    This is why automation is essential for your CresignSys hosting platform.


    70. Your Final Provisioning Architecture

                       HOSTING PANEL
                             │
                             ▼
                      SITE CREATION
                             │
                             ▼
                     PROVISIONING ENGINE
                             │
           ┌─────────────────┼─────────────────┐
           ▼                 ▼                 ▼
        Linux             Nginx             MySQL
        User              Config             DB
           │                 │                 │
           ▼                 ▼                 ▼
      Website Files      PHP-FPM          DB User
                             │
                             ▼
                        WordPress
                             │
                             ▼
                           SSL
                             │
                             ▼
                        HEALTH CHECK
                             │
                             ▼
                           ACTIVE

    71. The Complete Command-Level Workflow

    The actual automation eventually resembles:

    1. validate_domain
    2. generate_site_id
    3. create_linux_user
    4. create_directories
    5. set_permissions
    6. create_database
    7. create_database_user
    8. grant_database_privileges
    9. create_php_fpm_pool
    10. validate_php_fpm
    11. create_nginx_config
    12. validate_nginx
    13. reload_nginx
    14. download_wordpress
    15. create_wp_config
    16. install_wordpress
    17. configure_dns / verify_dns
    18. install_ssl
    19. test_https
    20. run_health_check
    21. mark_site_active

    72. Critical Rule

    Don’t make the provisioning script dependent on assumptions such as:

    PHP = 8.3
    socket = /run/php/php8.3-fpm.sock

    Instead, your hosting platform should detect or centrally define:

    PHP version
    PHP-FPM service
    socket location
    Nginx paths
    MySQL version
    website storage path

    This makes the platform maintainable.


    73. Configuration Template System

    Your previous CresignSys work with Nginx templates now becomes very useful.

    Instead of generating arbitrary configuration:

    template
    +
    site variables
    =
    site configuration

    For example:

    DOMAIN
    WEB_ROOT
    PHP_SOCKET
    LOG_PATH

    are inserted into a template.


    74. Example Template Variables

    {{DOMAIN}}
    {{WEB_ROOT}}
    {{PHP_SOCKET}}
    {{SITE_USER}}
    {{SITE_ID}}

    Then:

    learn.cresignsys.com

    generates:

    server_name learn.cresignsys.com;
    root /storage/websites/learn.cresignsys.com/public;
    fastcgi_pass unix:/run/php/learn.sock;

    75. Why Templates Are Better

    Without templates:

    manual configuration

    With templates:

    standardized configuration

    Benefits:

    consistency
    repeatability
    fewer mistakes
    easy updates
    automation

    76. The Golden Rule of Provisioning

    Every site should be created from the same validated architecture.

    For example:

    Site A
    =
    standard template
    
    Site B
    =
    standard template
    
    Site C
    =
    standard template

    Only the site-specific variables change.


    77. Lesson 063 — Core Principle

    You now understand the complete journey:

                        DOMAIN
                           │
                           ▼
                          DNS
                           │
                           ▼
                      SERVER IP
                           │
                           ▼
                        NGINX
                           │
                           ▼
                     PHP-FPM POOL
                           │
                           ▼
                      WORDPRESS
                           │
                           ▼
                        MYSQL
                           │
                           ▼
                      HTTPS / SSL
                           │
                           ▼
                     HEALTH CHECK
                           │
                           ▼
                         LIVE

    And your future command:

    sudo hosting-create example.com

    is essentially an automation engine that creates and validates every layer above.


    Next Lesson — 064

    Build the hosting-create Provisioning Engine

    We will now stop discussing the architecture only conceptually and design the actual CresignSys Hosting Platform provisioning script.

    It will have a structure like:

    /usr/local/bin/
    └── hosting-create
    
    /etc/cresignsys/
    ├── hosting.conf
    ├── nginx-templates/
    ├── php-templates/
    └── site-defaults/
    
    /storage/websites/
    ├── site1.com/
    ├── site2.com/
    └── site3.com/

    The provisioning engine will accept:

    sudo hosting-create example.com

    and systematically create:

    Linux user
    → directories
    → permissions
    → MySQL database
    → database user
    → PHP-FPM pool
    → Nginx config
    → WordPress
    → SSL
    → health check

    with validation at every stage instead of blindly executing commands.

  • CresignSys Learn — Lesson 062

    Linux Users, Groups & Permissions for Multi-Website Hosting

    We now connect the three major security layers:

    Nginx
       ↓
    PHP-FPM
       ↓
    Linux permissions
       ↓
    Website files

    The goal is:

    Site 1 should not be able to modify Site 2’s files.

    This is one of the most important concepts in a hosting platform.


    1. Why Linux Permissions Matter

    Suppose your server contains:

    /storage/websites/
    ├── site1.com/
    ├── site2.com/
    └── site3.com/

    If all websites run with the same Linux identity:

    www-data

    then a compromised application may potentially access files belonging to other sites that www-data can access.

    A better model is:

    site1 → user1
    site2 → user2
    site3 → user3

    2. Linux User

    A Linux user has an identity.

    Example:

    site1

    The operating system assigns it a:

    UID

    UID means:

    User ID

    For example:

    site1 → UID 1001
    site2 → UID 1002

    The actual numbers are assigned by the system and should not be hard-coded in your automation without checking.


    3. Linux Group

    A group is a collection of users.

    Example:

    site1
     └── group: site1
    
    site2
     └── group: site2

    Groups allow you to control shared access to files and directories.


    4. User + Group

    A file may have:

    owner
    group
    permissions

    Example:

    site1:site1

    means:

    owner = site1
    group = site1

    5. Check Your User

    Run:

    id

    You may see:

    uid=1000(username) gid=1000(username) groups=...

    For another user:

    id site1

    6. Create a Hosting User

    For example:

    sudo useradd -m -s /bin/bash site1

    This creates a Linux user.

    However, for a production hosting platform, your creation script should explicitly define the account model rather than blindly using commands like this.


    7. Check the User

    id site1

    You should see the user’s:

    UID
    GID
    groups

    8. User Home Directory

    If created with -m, the user normally gets a home directory:

    /home/site1

    For your hosting architecture, website files can instead live under:

    /storage/websites/site1.com/

    9. Ownership

    Check ownership with:

    ls -la

    For a website:

    ls -la /storage/websites/site1.com

    You may see:

    site1 site1

    or another ownership model depending on your configuration.


    10. ls -l

    Example:

    -rw-r--r-- 1 site1 site1 1234 index.php

    Break it down:

    -rw-r--r--
    │
    ├── file type
    ├── owner permissions
    ├── group permissions
    └── other permissions

    11. The Three Permission Classes

    Linux permissions are divided into:

    User
    Group
    Other

    Often abbreviated:

    u
    g
    o

    Example:

    u = owner
    g = group
    o = everyone else

    12. Read

    r

    means:

    Read the contents.

    For a file:

    r = 4

    13. Write

    w

    means:

    Modify the contents.

    Numeric value:

    w = 2

    14. Execute

    x

    means:

    Execute the file.

    Numeric value:

    x = 1

    For directories, x has an important additional meaning: it permits traversal/searching through the directory.


    15. Numeric Permissions

    Combine:

    r = 4
    w = 2
    x = 1

    Therefore:

    rwx = 7
    rw- = 6
    r-x = 5
    r-- = 4
    -wx = 3
    -w- = 2
    --x = 1
    --- = 0

    16. 755

    A very common permission mode:

    755

    means:

    Owner  = rwx = 7
    Group  = r-x = 5
    Other  = r-x = 5

    So:

    rwxr-xr-x

    17. 644

    Another common mode:

    644

    means:

    Owner  = rw- = 6
    Group  = r-- = 4
    Other  = r-- = 4

    So:

    rw-r--r--

    18. Why Files and Directories Differ

    For a file:

    r

    means read its contents.

    For a directory:

    r

    means list directory entries.

    For a directory:

    x

    means traverse/search the directory.

    This distinction is essential when troubleshooting WordPress permissions.


    19. Example Directory

    Suppose:

    /storage/websites/site1.com/public

    has:

    755

    Then:

    site1

    can:

    read
    write
    enter

    while other users may be able to:

    read
    enter

    but not modify its contents.


    20. File Permissions

    Suppose:

    index.php

    has:

    644

    Then the owner can:

    read
    write

    while group and others can:

    read

    but not modify it.


    21. chmod

    chmod changes permissions.

    Example:

    chmod 644 index.php

    or:

    chmod 755 public

    22. Recursive Permissions

    You can use:

    chmod -R ...

    but be careful.

    Running:

    chmod -R 777 /storage/websites/site1.com

    is a bad hosting practice.

    It gives excessively broad permissions.


    23. Why 777 Is Dangerous

    777

    means:

    owner  rwx
    group  rwx
    other  rwx

    Everyone can potentially modify the files.

    For a web hosting environment this can create serious security problems.

    Avoid using:

    chmod -R 777

    as a generic solution to permission errors.


    24. chown

    chown changes ownership.

    Example:

    sudo chown site1:site1 index.php

    Now:

    owner = site1
    group = site1

    25. Recursive chown

    You can change an entire site:

    sudo chown -R site1:site1 /storage/websites/site1.com

    But again, don’t blindly apply recursive ownership changes to directories containing files that intentionally need different ownership.

    Understand the desired ownership model first.


    26. The Basic Hosting Model

    For independent sites:

    site1.com
    owner = site1
    group = site1
    
    site2.com
    owner = site2
    group = site2

    Then:

    site1

    should not automatically have write access to:

    site2.com

    27. Test Isolation

    Create:

    /storage/websites/site1.com/test.txt

    owned by:

    site1:site1

    Then attempt access as site2:

    sudo -u site2 cat /storage/websites/site1.com/test.txt

    If permissions are correctly isolated, site2 should be denied.

    This is an excellent security test.


    28. Don’t Test as Root

    Remember:

    root

    can bypass many normal permission restrictions.

    Therefore:

    sudo -u site2 ...

    is useful for testing what the actual hosting user can do.


    29. PHP-FPM User

    Now connect this to the previous lesson.

    Suppose:

    site1 PHP-FPM pool

    runs as:

    site1

    Then PHP code executed by that pool has the Linux identity:

    site1

    This is extremely important.


    30. The Security Chain

    For Site 1:

    Browser
     ↓
    Nginx
     ↓
    PHP-FPM pool 1
     ↓
    Linux user site1
     ↓
    Site 1 files

    For Site 2:

    Browser
     ↓
    Nginx
     ↓
    PHP-FPM pool 2
     ↓
    Linux user site2
     ↓
    Site 2 files

    31. What Happens During a Compromise?

    Suppose:

    site1.com

    has a vulnerable plugin.

    An attacker manages to execute PHP code through that application.

    The PHP process should ideally run as:

    site1

    Therefore the attacker’s access is constrained by the permissions of:

    site1

    rather than a broad shared account.

    This is not a complete security guarantee, but it significantly improves isolation.


    32. Site 1 Should Not Own Site 2

    Bad model:

    site1
    site2
    site3
          ↓
    www-data

    Better model:

    site1 → site1
    site2 → site2
    site3 → site3

    33. Nginx Complication

    Nginx workers may still run as:

    www-data

    So Nginx needs enough access to:

    read static files
    traverse directories
    access PHP-FPM sockets

    without gaining unnecessary write access.

    This requires careful permissions.


    34. Important Principle

    A good architecture is:

    Nginx
    → read-only access to website files where possible
    
    PHP-FPM
    → write access only where the application needs it

    This is safer than giving the web server universal write access.


    35. WordPress Needs Some Write Access

    WordPress may need to write to:

    wp-content/uploads/

    and sometimes other directories depending on plugins and update methods.

    Therefore you should not blindly make the entire WordPress installation writable.


    36. Better WordPress Permission Model

    Conceptually:

    WordPress core
    → mostly read-only
    
    themes
    → mostly read-only
    
    plugins
    → mostly read-only
    
    uploads
    → writable where needed

    The exact model depends on how WordPress updates and plugin management are handled.


    37. Why wp-content/uploads?

    When you upload:

    image.jpg

    through WordPress:

    WordPress
     ↓
    PHP
     ↓
    wp-content/uploads/
     ↓
    image.jpg

    Therefore the PHP process must have appropriate write access.


    38. But Don’t Make Everything Writable

    Avoid:

    chmod -R 777 public

    Instead, identify exactly what needs to be writable.

    For example:

    public/
    ├── index.php
    ├── wp-admin/
    ├── wp-includes/
    ├── wp-content/
    │   ├── plugins/
    │   ├── themes/
    │   └── uploads/

    The required write permissions should be deliberately designed.


    39. WordPress Updates

    There is an architectural decision:

    Model A

    PHP can modify WordPress core/plugin files.

    Advantages:

    easy automatic updates

    Disadvantages:

    larger write surface

    Model B

    Core/plugin files are more restricted.

    Updates are performed through controlled deployment/administrative mechanisms.

    Advantages:

    stronger security

    Disadvantages:

    more management complexity

    For a hosting platform, this tradeoff matters.


    40. Directory Traversal

    Suppose:

    /storage/

    has restrictive permissions.

    Even if:

    public/

    is readable, PHP may still fail if the process cannot traverse the parent directories.

    Remember:

    directory x permission
    =
    ability to traverse/search

    41. Example

    Suppose:

    /storage

    is:

    700 root:root

    Then:

    site1

    may not be able to reach:

    /storage/websites/site1.com/public

    even if the final directory is:

    755

    The entire path matters.


    42. Check Every Level

    Use:

    namei -l /storage/websites/site1.com/public

    This is an extremely useful command.

    It shows permissions and ownership for each component of the path.


    43. Example

    Conceptually:

    f: /storage/websites/site1.com/public
    drwxr-xr-x root root storage
    drwxr-xr-x root root websites
    drwx------ site1 site1 site1.com
    drwxr-xr-x site1 site1 public

    Now you can identify exactly where traversal fails.


    44. umask

    umask controls default permission restrictions applied when new files/directories are created.

    Check it:

    umask

    You might see:

    0022

    or another value depending on the process/user.


    45. Why umask Matters

    When PHP creates:

    newfile.txt

    the resulting permissions depend partly on:

    requested mode
    +
    umask

    Therefore your hosting environment should have predictable defaults.


    46. Setgid Directory

    A directory can use the setgid bit.

    For example:

    chmod 2770 directory

    The leading:

    2

    sets the setgid bit.

    For directories, this can cause newly created files/directories to inherit the directory’s group.

    This can be useful when multiple trusted processes/users need to share a group.


    47. Why Setgid Can Help

    Suppose:

    site1

    has:

    group = site1

    and multiple processes need to cooperate through that group.

    A setgid directory can help maintain consistent group ownership.

    But don’t add it everywhere without a clear group-sharing requirement.


    48. ACL

    Linux also supports:

    Access Control Lists

    ACLs allow more granular permissions than the basic:

    owner
    group
    other

    model.

    For example:

    site1

    could have special access without changing the primary group model.


    49. Check ACL

    If ACLs are installed and used:

    getfacl /storage/websites/site1.com

    You may see:

    user::...
    group::...
    other::...

    plus additional entries.


    50. setfacl

    ACLs can be modified with:

    setfacl

    For example, you can grant a specific user read access without changing ownership.

    However, for your hosting platform, start with normal Unix ownership and permissions.

    Add ACLs only when there is a real requirement.


    51. Recommended Starting Model

    For each site:

    Linux user = site1
    Primary group = site1
    Website ownership = site1:site1
    PHP-FPM pool = site1
    PHP worker user = site1
    Database = site1_database
    Database user = site1_dbuser

    This gives a consistent identity across the system.


    52. Directory Structure

    Use:

    /storage/websites/
    └── site1.com/
        ├── public/
        ├── logs/
        ├── backups/
        └── private/

    Only:

    public/

    should be exposed through Nginx.


    53. Public Directory

    Example:

    /storage/websites/site1.com/public

    contains:

    index.php
    wp-admin/
    wp-content/
    wp-includes/

    Nginx:

    root /storage/websites/site1.com/public;

    54. Private Directory

    You could maintain:

    /storage/websites/site1.com/private

    for internal files.

    Do not configure Nginx to serve it.

    For example:

    private/
    ├── backups/
    ├── temporary/
    └── configuration/

    55. Logs

    Site-specific logs can be stored separately:

    /storage/websites/site1.com/logs/

    But be careful with ownership and Nginx’s ability to write logs.

    An alternative is to keep logs under:

    /var/log/nginx/

    with appropriate per-site log configuration.


    56. Backup Directory

    Backups should ideally not be directly web-accessible.

    Bad:

    public/backups/database.sql

    because someone could potentially request:

    https://site1.com/backups/database.sql

    if the file is exposed.

    Better:

    /storage/backups/site1/

    outside the web root.


    57. Database Credentials

    Similarly, never store a backup such as:

    database.sql

    inside the public web root.

    And never expose:

    .env
    backup.zip
    database.sql

    through HTTP.


    58. Site Isolation Test

    Suppose:

    site1
    site2

    exist.

    Test:

    sudo -u site1 touch /storage/websites/site1.com/public/test1.txt

    This should succeed.

    Then:

    sudo -u site1 touch /storage/websites/site2.com/public/test2.txt

    This should fail if site2 is properly isolated.


    59. Test PHP Identity

    Create a temporary PHP diagnostic file carefully:

    <?php
    echo get_current_user();

    However, get_current_user() isn’t necessarily the best way to determine the OS process identity.

    For an actual process identity, you can use server-side diagnostics carefully, then delete the diagnostic file immediately after testing.

    Never leave debugging information exposed on a production website.


    60. Better Conceptual Test

    The important question is:

    Which Linux user is executing PHP?

    If Site 1’s PHP process runs as:

    site1

    then its filesystem operations are governed by Site 1’s permissions.


    61. Nginx and PHP-FPM Relationship

    Your final permission model could look like:

                        NGINX
                          │
                 reads public files
                          │
                          ▼
                     PHP-FPM
                          │
              ┌───────────┴───────────┐
              ▼                       ▼
           site1                    site2
           user                     user
              │                       │
              ▼                       ▼
          site1 files             site2 files

    62. What Site 1 Should NOT Access

    Site 1 should not have write access to:

    site2/public/
    site2/private/
    site2/backups/
    site2/configuration/
    site2/database credentials

    unless explicitly required.


    63. What Root Can Access

    Remember:

    root

    is different.

    A hosting administrator/root account can access all sites.

    Therefore:

    customer isolation
    ≠
    administrator isolation

    Your goal is tenant-to-tenant isolation.


    64. Linux Security Is Layered

    Do not depend on only one mechanism.

    Use:

    Linux users
    +
    groups
    +
    filesystem permissions
    +
    PHP-FPM pools
    +
    database users
    +
    Nginx isolation
    +
    firewall
    +
    application updates

    65. A Complete Site Identity

    For:

    learn.cresignsys.com

    you can conceptually define:

    SITE ID
    learn
    
    DOMAIN
    learn.cresignsys.com
    
    LINUX USER
    learn
    
    LINUX GROUP
    learn
    
    WEB ROOT
    /storage/websites/learn.cresignsys.com/public
    
    PHP-FPM POOL
    learn
    
    PHP SOCKET
    /run/php/learn.sock
    
    DATABASE
    learn_cresignsys
    
    DATABASE USER
    learn_dbuser

    This is an excellent pattern for automation.


    66. Why Consistent Naming Matters

    Your scripts become much easier if everything follows a predictable naming scheme.

    For example:

    Domain:
    learn.cresignsys.com
    
    Linux user:
    learn
    
    PHP pool:
    learn
    
    Socket:
    learn.sock
    
    Database:
    learn_db
    
    Database user:
    learn_dbuser

    For domains with unusual characters, your automation should sanitize and generate safe identifiers rather than using arbitrary domain strings directly.


    67. Don’t Use Domain as a Linux Username Blindly

    A domain may contain:

    www.example.com

    but system account naming rules and your platform’s conventions may make a normalized identifier preferable.

    Your provisioning script should generate a safe unique site ID.

    Example:

    SITE_ID = learn_cresignsys_com

    or another collision-resistant identifier.


    68. Hosting Control Panel Data

    Eventually your control panel database might contain:

    sites

    with:

    site_id
    domain
    linux_user
    document_root
    php_version
    php_pool
    database_name
    database_user
    ssl_status
    created_at

    Then your automation can generate the actual server configuration.


    69. Control Plane → Server

    Conceptually:

    Hosting Panel
          ↓
    Site record
          ↓
    Provisioning script
          ↓
    Linux user
          ↓
    Directories
          ↓
    PHP-FPM
          ↓
    Nginx
          ↓
    MySQL
          ↓
    SSL

    This is the beginning of a real hosting control plane.


    70. Permission Troubleshooting

    When WordPress says:

    Unable to create directory

    don’t immediately run:

    chmod -R 777

    Instead ask:

    Which user is PHP running as?
            ↓
    Does that user own the directory?
            ↓
    Does it have write permission?
            ↓
    Can it traverse every parent directory?
            ↓
    Is an ACL involved?
            ↓
    Is the filesystem read-only?

    71. Useful Diagnostic Commands

    Current identity

    id

    File ownership

    ls -la

    Full path permissions

    namei -l /storage/websites/site1.com/public

    Ownership

    stat /storage/websites/site1.com

    ACL

    getfacl /storage/websites/site1.com

    Processes

    ps aux | grep php-fpm

    72. A Practical Diagnostic

    Suppose:

    WordPress
    ↓
    Unable to write uploads

    Check:

    ls -ld /storage/websites/site1.com/public/wp-content/uploads

    Then:

    namei -l /storage/websites/site1.com/public/wp-content/uploads

    Then determine the PHP-FPM pool’s user.

    Finally test:

    sudo -u site1 touch /storage/websites/site1.com/public/wp-content/uploads/test.txt

    If this fails, the problem is likely filesystem permissions/path access rather than WordPress itself.


    73. Don’t Forget SELinux/AppArmor

    Linux security can have additional layers such as:

    SELinux
    AppArmor

    Ubuntu commonly uses AppArmor for certain services.

    Therefore:

    Unix permissions correct

    does not always guarantee:

    application access allowed

    This becomes an advanced troubleshooting topic.


    74. Permission Layers

    Think of access as:

    Application
       ↓
    Linux process identity
       ↓
    Unix permissions
       ↓
    ACL
       ↓
    AppArmor/other security policy
       ↓
    Filesystem

    All relevant controls must permit the operation.


    75. The Hosting Security Principle

    For every website:

    Identity
    +
    Ownership
    +
    Permissions
    +
    Process isolation
    +
    Database isolation

    should agree with each other.

    For example:

    site1

    should consistently map to:

    site1 files
    site1 PHP-FPM
    site1 database
    site1 database user

    76. Lesson 062 — Core Principle

    The most important idea is:

    PHP-FPM should execute a site’s PHP as that site’s Linux identity whenever your hosting architecture calls for per-site isolation.

    Then:

    site1 PHP
       ↓
    Linux user site1
       ↓
    site1 permissions
       ↓
    site1 files

    while:

    site2 PHP
       ↓
    Linux user site2
       ↓
    site2 permissions
       ↓
    site2 files

    This creates the foundation for secure multi-tenant hosting.


    Next Lesson — 063

    WordPress Installation Automation — From Empty Domain to Working Website

    We will now combine the previous lessons into one complete provisioning workflow:

    Domain
     ↓
    DNS
     ↓
    Website directory
     ↓
    Linux user
     ↓
    Permissions
     ↓
    MySQL database
     ↓
    Database user
     ↓
    PHP-FPM pool
     ↓
    Nginx server block
     ↓
    WordPress download
     ↓
    wp-config.php
     ↓
    WordPress installation
     ↓
    SSL
     ↓
    Final testing

    The next lesson will turn these individual concepts into a repeatable command-line installation procedure for any domain on your CresignSys VPS.

  • CresignSys Learn — Lesson 061

    MySQL for Web Hosting — Databases, Users, Privileges & WordPress

    We now move to the database layer.

    Your WordPress request currently travels like this:

    Browser
     ↓
    DNS
     ↓
    IP
     ↓
    Nginx
     ↓
    PHP-FPM
     ↓
    WordPress
     ↓
    MySQL

    The purpose of MySQL is to store and retrieve the structured data WordPress needs.


    1. What Is MySQL?

    MySQL is a relational database management system.

    It stores information in structured tables.

    For WordPress, that includes things such as:

    posts
    pages
    users
    settings
    comments
    categories
    menus
    plugin data
    theme data
    metadata

    2. WordPress Is Not the Database

    This distinction is important.

    WordPress
    =
    application
    MySQL
    =
    database

    The relationship is:

    WordPress
       ↓
    SQL queries
       ↓
    MySQL
       ↓
    data

    3. What Is a Database?

    A database is a logical collection of related data.

    For example:

    wordpress_learn

    might contain tables such as:

    wp_posts
    wp_users
    wp_options
    wp_terms
    wp_comments

    4. Database Server vs Database

    These are different.

    MySQL server

    The running database service.

    Database

    A logical collection inside that server.

    Conceptually:

    MySQL Server
    │
    ├── database1
    ├── database2
    ├── database3
    └── database4

    5. Your Hosting Server

    You may have:

    Ubuntu VPS
    │
    ├── Nginx
    ├── PHP-FPM
    ├── MySQL
    ├── WordPress site 1
    ├── WordPress site 2
    └── WordPress site 3

    All websites can use the same MySQL server while having separate databases.


    6. One Database Per Website

    For hosting, a good model is:

    site1.com
     ↓
    database_site1
    
    site2.com
     ↓
    database_site2
    
    site3.com
     ↓
    database_site3

    This makes management and isolation easier.


    7. Why Not One Database for Everything?

    You could technically put many websites into one database.

    But it creates problems:

    harder backup
    harder restore
    harder migration
    harder isolation
    harder troubleshooting

    Therefore, for your hosting platform:

    One website → one database is a useful standard.


    8. Database User

    A database should also have a dedicated database user.

    For example:

    Website:
    learn.cresignsys.com
    
    Database:
    learn_cresignsys
    
    User:
    learn_user

    The application uses that user to access its database.


    9. Why Dedicated Users?

    Suppose:

    site1
    site2

    both use the same MySQL account.

    If site1 is compromised, the attacker may potentially gain access to site2’s database as well.

    Instead:

    site1 → db_user1 → database1
    
    site2 → db_user2 → database2

    provides better isolation.


    10. MySQL Architecture

    Conceptually:

    WordPress
        │
        │ SQL
        ▼
    MySQL Server
        │
        ├── Database 1
        │
        ├── Database 2
        │
        └── Database 3

    11. Check MySQL

    On Ubuntu:

    sudo systemctl status mysql

    You want:

    Active: active (running)

    12. Check MySQL Version

    Run:

    mysql --version

    You may see something similar to:

    mysql  Ver 8.0...

    The exact version depends on your installation.


    13. Enter MySQL

    On a server using local administrative authentication, you may use:

    sudo mysql

    You should then see:

    mysql>

    14. Exit

    To leave MySQL:

    EXIT;

    or:

    \q

    15. List Databases

    Inside MySQL:

    SHOW DATABASES;

    You may see:

    information_schema
    mysql
    performance_schema
    sys

    plus your WordPress databases.


    16. System Databases

    MySQL includes databases used internally.

    For example:

    mysql
    information_schema
    performance_schema
    sys

    Don’t delete these casually.


    17. Create a Database

    Example:

    CREATE DATABASE learn_cresignsys;

    Now:

    learn_cresignsys

    exists.


    18. Better Character Set

    For WordPress, Unicode support is important.

    A commonly used configuration is:

    CREATE DATABASE learn_cresignsys
    CHARACTER SET utf8mb4
    COLLATE utf8mb4_unicode_ci;

    The exact collation choice can vary by MySQL version and application requirements.


    19. Why utf8mb4?

    It supports a much broader range of Unicode characters than the older MySQL utf8 implementation.

    For example:

    English
    Malayalam
    Hindi
    Arabic
    Chinese
    emoji

    can all be represented properly when the application and database configuration are compatible.


    20. Database User

    Create a dedicated user:

    CREATE USER 'learn_user'@'localhost'
    IDENTIFIED BY 'STRONG_PASSWORD';

    Use a strong, unique password.

    Do not reuse your Linux password.


    21. Grant Privileges

    Give the user access to its own database:

    GRANT ALL PRIVILEGES
    ON learn_cresignsys.*
    TO 'learn_user'@'localhost';

    Now:

    learn_user

    can operate on:

    learn_cresignsys

    22. What Does *.* Mean?

    This is important.

    database.*

    means:

    All tables in this database.

    For example:

    learn_cresignsys.*

    means:

    all tables inside learn_cresignsys

    23. Why Not Give Global Privileges?

    Avoid doing this for normal WordPress users:

    GRANT ALL PRIVILEGES ON *.* ...

    That could give access to every database.

    Instead:

    learn_user
     ↓
    learn_cresignsys.*

    This follows least privilege.


    24. Least Privilege

    A core security principle:

    Give an application only the permissions it needs.

    For example:

    Site 1
     ↓
    Database 1

    not:

    Site 1
     ↓
    Every database

    25. WordPress Database Credentials

    WordPress stores database connection information in:

    wp-config.php

    Typically:

    DB_NAME
    DB_USER
    DB_PASSWORD
    DB_HOST

    26. Example

    Conceptually:

    define( 'DB_NAME', 'learn_cresignsys' );
    define( 'DB_USER', 'learn_user' );
    define( 'DB_PASSWORD', 'STRONG_PASSWORD' );
    define( 'DB_HOST', 'localhost' );

    Do not publish real credentials.


    27. What Happens During a Request?

    Suppose:

    https://learn.cresignsys.com/about/

    is requested.

    The flow is:

    Browser
     ↓
    Nginx
     ↓
    PHP-FPM
     ↓
    WordPress
     ↓
    wp-config.php
     ↓
    MySQL

    WordPress reads the database connection settings and connects to MySQL.


    28. MySQL Query

    WordPress may execute queries conceptually similar to:

    SELECT *
    FROM wp_posts
    WHERE ID = 123;

    MySQL processes the query.

    Then returns the result to PHP.


    29. PHP Receives Data

    The flow becomes:

    MySQL
     ↓
    database result
     ↓
    WordPress/PHP
     ↓
    HTML
     ↓
    Nginx
     ↓
    Browser

    30. Tables

    A relational database stores data in tables.

    For example:

    wp_users

    may contain:

    ID
    user_login
    user_email
    user_pass

    and other fields.


    31. Rows

    A row represents one record.

    For example:

    ID = 15
    user_login = john

    is one user record.


    32. Columns

    Columns describe the fields.

    Example:

    wp_users
    
    ID
    user_login
    user_email
    user_registered

    33. Primary Key

    A table normally has a way to uniquely identify each record.

    For example:

    ID

    can act as a primary key.

    Conceptually:

    ID
    --
    1
    2
    3
    4

    Each identifies a particular record.


    34. WordPress Tables

    A standard WordPress installation commonly creates tables such as:

    wp_posts
    wp_postmeta
    wp_users
    wp_usermeta
    wp_options
    wp_terms
    wp_term_taxonomy
    wp_term_relationships
    wp_comments
    wp_commentmeta

    Plugins can create additional tables.


    35. Table Prefix

    Notice:

    wp_

    is a common table prefix.

    WordPress can use another prefix.

    For example:

    abc_posts
    abc_users
    abc_options

    36. Why Prefix Exists

    The prefix can help distinguish WordPress tables.

    It can also allow multiple WordPress installations to use the same database in some configurations, although separate databases are generally cleaner for independent hosted sites.


    37. Never Treat Prefix as Complete Security

    Changing:

    wp_

    to:

    abc_

    does not provide meaningful protection by itself.

    Real security comes from:

    database privileges
    Linux permissions
    application security
    updates
    authentication
    network controls

    38. Check WordPress Tables

    Inside MySQL:

    USE learn_cresignsys;

    Then:

    SHOW TABLES;

    You should see the WordPress tables.


    39. Inspect a Table

    For example:

    DESCRIBE wp_options;

    This shows the columns.


    40. Count Posts

    You could query:

    SELECT COUNT(*)
    FROM wp_posts;

    This is a simple example of how WordPress data is stored.


    41. Don’t Modify WordPress Directly Without Understanding It

    You can technically run:

    UPDATE ...

    but be careful.

    WordPress plugins and themes can have relationships and serialized/structured data.

    Changing database records manually can break the application.

    For normal content management:

    WordPress Admin

    is usually safer.


    42. MySQL User Authentication

    MySQL identifies users by:

    username
    +
    host

    For example:

    'learn_user'@'localhost'

    is different from:

    'learn_user'@'%'

    43. localhost

    For:

    'learn_user'@'localhost'

    the account is intended for connections from the local host under MySQL’s account matching rules.

    This is appropriate when:

    WordPress
    +
    MySQL

    are on the same VPS.


    44. Why Avoid %?

    You may see:

    'learn_user'@'%'

    which broadly permits connections from hosts matching %.

    For a local-only WordPress database connection, you generally don’t need to expose the database user this broadly.

    Prefer the narrowest host requirement that works.


    45. Database Port

    MySQL commonly listens on:

    3306

    But don’t assume the port alone makes MySQL accessible.

    Check:

    sudo ss -ltnp | grep 3306

    46. MySQL Should Usually Not Be Public

    For your single VPS:

    Internet
       ✕
       ↓
    MySQL 3306

    You generally don’t want arbitrary Internet users connecting directly to your WordPress MySQL service.

    Instead:

    Internet
     ↓
    Nginx
     ↓
    PHP-FPM
     ↓
    MySQL

    MySQL remains internal to the server.


    47. Check MySQL Bind Address

    Inspect MySQL configuration.

    For example:

    sudo grep -R "bind-address" /etc/mysql/ 2>/dev/null

    You may find something such as:

    127.0.0.1

    This means MySQL is bound to the local interface.

    The exact configuration depends on your installation.


    48. Why This Is Secure

    If MySQL listens only locally:

    Internet
      ↓
    Nginx
      ↓
    PHP
      ↓
    localhost
      ↓
    MySQL

    external systems cannot directly reach the MySQL service through the network.


    49. If You Need Remote MySQL

    There are legitimate cases where:

    Application Server
            ↓
    network
            ↓
    Database Server

    is required.

    Then you need:

    TLS
    firewall rules
    restricted source IPs
    database privileges
    authentication

    Don’t simply open:

    3306

    to the whole Internet.


    50. WordPress Database Architecture

    Your current hosting architecture should be:

                        INTERNET
                            │
                            ▼
                          NGINX
                            │
                            ▼
                        PHP-FPM
                            │
                            ▼
                        WORDPRESS
                            │
                            ▼
                         MYSQL
                            │
                  ┌─────────┼─────────┐
                  ▼         ▼         ▼
                 DB1       DB2       DB3

    51. One Website

    For:

    learn.cresignsys.com

    use:

    Linux user:
    learn
    
    Website:
    learn.cresignsys.com
    
    Database:
    learn_cresignsys
    
    Database user:
    learn_user
    
    PHP-FPM pool:
    learn
    
    PHP socket:
    learn.sock

    Conceptually:

    learn.cresignsys.com
            │
            ├── files
            ├── Nginx
            ├── PHP-FPM
            └── MySQL
                 │
                 └── learn_cresignsys

    52. Another Website

    For:

    shop.cresignsys.com

    use:

    shop
    shop_cresignsys
    shop_user
    shop PHP-FPM pool
    shop.sock

    Now the two sites are logically separated.


    53. Database Backup

    Database backup is essential.

    A common tool is:

    mysqldump

    For example:

    mysqldump -u learn_user -p learn_cresignsys > learn_cresignsys.sql

    This exports database contents to a SQL file.


    54. What Is a SQL Dump?

    A dump can contain SQL statements that recreate database objects and data.

    Conceptually:

    Database
       ↓
    mysqldump
       ↓
    backup.sql

    Later:

    backup.sql
       ↓
    mysql
       ↓
    Database

    55. Restore Example

    Create the target database first, then import:

    mysql -u learn_user -p learn_cresignsys < learn_cresignsys.sql

    The exact restore procedure depends on what is contained in the dump and how the target database/user is configured.


    56. Database Backup Is Not Website Backup

    This is critical.

    A WordPress backup needs at least:

    Database
    +
    Website files

    because:

    database

    contains content/settings, while:

    wp-content
    themes
    plugins
    uploads
    WordPress files

    are stored on disk.


    57. Full WordPress Backup

    Conceptually:

    WordPress Backup
    │
    ├── Database
    │    └── .sql
    │
    └── Files
         └── website directory

    58. Why wp-content Is Important

    Among WordPress files:

    wp-content/

    usually contains important site-specific data such as:

    plugins
    themes
    uploads

    The uploads directory is particularly important because it contains media files.


    59. Backup Strategy for Hosting

    For each hosted website:

    site1
    ├── database backup
    └── files backup
    
    site2
    ├── database backup
    └── files backup
    
    site3
    ├── database backup
    └── files backup

    60. Database Size

    Check database size:

    SELECT
        table_schema AS database_name,
        ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS size_mb
    FROM information_schema.tables
    WHERE table_schema = 'learn_cresignsys'
    GROUP BY table_schema;

    This helps monitor growth.


    61. Why Database Size Matters

    A WordPress database can grow due to:

    posts
    revisions
    logs
    plugin tables
    transients
    analytics
    comments
    metadata

    Poorly configured plugins can create very large tables.


    62. MySQL Performance

    MySQL consumes:

    RAM
    CPU
    disk I/O

    WordPress performance therefore depends on:

    Nginx
    +
    PHP-FPM
    +
    MySQL
    +
    storage

    not only PHP.


    63. Request Flow With Database

    A dynamic request may look like:

    Browser
     ↓
    Nginx
     ↓
    PHP-FPM
     ↓
    WordPress
     ↓
    MySQL
     ↓
    data
     ↓
    WordPress
     ↓
    PHP
     ↓
    Nginx
     ↓
    Browser

    Every layer can become a bottleneck.


    64. Database Bottleneck

    Suppose PHP is fast but MySQL takes:

    5 seconds

    Then the page can still take roughly:

    5+ seconds

    before other processing and network overhead.

    Therefore:

    Faster PHP cannot completely compensate for a slow database.


    65. Query

    A database query asks MySQL to retrieve or modify information.

    For example:

    SELECT *
    FROM wp_posts
    WHERE post_status = 'publish';

    The database parses and executes it.


    66. Index

    Indexes help MySQL find records efficiently.

    Conceptually:

    Without index
     ↓
    scan many rows
    
    With appropriate index
     ↓
    find relevant rows faster

    WordPress core tables have indexes designed for common operations, and plugins may add their own.


    67. Too Many Queries

    A page can trigger many database queries.

    For example:

    WordPress
     ↓
    100 queries
     ↓
    MySQL

    If each query is expensive, page generation becomes slow.

    Caching can reduce the need to regenerate the page.


    68. Object Cache

    WordPress can also use object caching.

    Conceptually:

    WordPress
     ↓
    Object cache
     ↓
    data

    instead of querying MySQL repeatedly for the same information.

    Common technologies include Redis and Memcached, but these are later lessons.


    69. Database Security Model

    Your hosting platform should follow:

    Website
     ↓
    Dedicated database user
     ↓
    Dedicated database
     ↓
    Minimum required privileges

    Not:

    Website
     ↓
    root MySQL account
     ↓
    all databases

    70. Never Use MySQL Root in WordPress

    Do not configure:

    define( 'DB_USER', 'root' );

    for a normal WordPress site.

    Instead:

    site-specific database user

    should be used.


    71. Why Root Is Dangerous

    If WordPress is compromised and it has MySQL root privileges, the attacker could potentially perform actions far beyond that site’s database.

    Least privilege limits the potential impact.


    72. Your Hosting Creation Workflow

    A proper automated site creation process should eventually do:

    DOMAIN
      ↓
    Linux user
      ↓
    Website directory
      ↓
    PHP-FPM pool
      ↓
    Nginx server block
      ↓
    Database
      ↓
    Database user
      ↓
    Privileges
      ↓
    WordPress
      ↓
    SSL

    73. Example: learn.cresignsys.com

    Conceptual configuration:

    DOMAIN
    learn.cresignsys.com
    
    LINUX USER
    learn
    
    PATH
    /storage/websites/learn.cresignsys.com/public
    
    DATABASE
    learn_cresignsys
    
    DATABASE USER
    learn_user
    
    PHP POOL
    learn
    
    SOCKET
    /run/php/learn.sock

    Then:

    DNS
     ↓
    Nginx
     ↓
    learn PHP-FPM
     ↓
    learn WordPress
     ↓
    learn database

    74. This Is Multi-Tenant Hosting

    When multiple independent websites share one server, you are operating a form of:

    Multi-tenant hosting

    Example:

    Server
    │
    ├── Customer A
    ├── Customer B
    ├── Customer C
    └── Customer D

    Each tenant needs isolation.


    75. Isolation Layers

    You can isolate at several levels:

    Linux user
    +
    filesystem permissions
    +
    PHP-FPM pool
    +
    database
    +
    database user
    +
    Nginx configuration

    The more layers are correctly separated, the stronger the hosting architecture.


    76. Important Distinction

    Separate:

    database

    does not automatically mean:

    full security isolation

    You also need:

    filesystem isolation
    process isolation
    correct PHP-FPM users
    correct permissions
    secure Nginx configuration

    77. MySQL Commands to Memorize

    Check databases:

    SHOW DATABASES;

    Select database:

    USE database_name;

    List tables:

    SHOW TABLES;

    Describe table:

    DESCRIBE table_name;

    Create database:

    CREATE DATABASE database_name;

    Create user:

    CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';

    Grant access:

    GRANT ALL PRIVILEGES
    ON database_name.*
    TO 'user'@'localhost';

    78. Linux Commands to Memorize

    Check MySQL:

    sudo systemctl status mysql

    Enter MySQL:

    sudo mysql

    Check listening port:

    sudo ss -ltnp | grep 3306

    Check version:

    mysql --version

    Backup:

    mysqldump -u USER -p DATABASE > backup.sql

    Restore:

    mysql -u USER -p DATABASE < backup.sql

    79. Complete Architecture

    You now understand:

                         INTERNET
                            │
                            ▼
                           DNS
                            │
                            ▼
                        PUBLIC IP
                            │
                            ▼
                     OCI NETWORKING
                            │
                            ▼
                          NGINX
                            │
                            ▼
                        PHP-FPM
                            │
                            ▼
                       WORDPRESS
                            │
                            ▼
                          MYSQL

    And for multiple websites:

                          NGINX
                            │
              ┌─────────────┼─────────────┐
              ▼             ▼             ▼
           Site 1        Site 2        Site 3
              │             │             │
           PHP 1          PHP 2          PHP 3
              │             │             │
            DB 1           DB 2           DB 3

    80. Lesson 061 — Core Principle

    The most important principle is:

    Each hosted website should have its own application identity and database identity whenever practical.

    For your CresignSys hosting architecture:

    Domain
     ↓
    Linux User
     ↓
    Website Files
     ↓
    Nginx Server Block
     ↓
    PHP-FPM Pool
     ↓
    PHP Socket
     ↓
    WordPress
     ↓
    Dedicated Database
     ↓
    Dedicated Database User

    This gives you a clean foundation for automated multi-domain hosting.


    Next Lesson — 062

    Linux Users, Groups & Permissions for Multi-Website Hosting

    Next we will connect MySQL security with the filesystem and PHP-FPM security:

    Linux User
     ↓
    Group
     ↓
    UID
     ↓
    GID
     ↓
    file ownership
     ↓
    r / w / x
     ↓
    chmod
     ↓
    chown
     ↓
    umask
     ↓
    setgid
     ↓
    ACL

    Then we will design the correct permissions for:

    /storage/websites/
    ├── site1.com/
    ├── site2.com/
    └── site3.com/

    so that Site 1 cannot modify Site 2, even though both run on the same VPS.

  • CresignSys Learn — Lesson 060

    PHP-FPM Deep Dive — How Nginx Runs WordPress PHP

    We now move from Nginx to the PHP execution layer.

    The complete flow is:

    Browser
       ↓
    DNS
       ↓
    IP
       ↓
    TCP 443
       ↓
    Nginx
       ↓
    FastCGI
       ↓
    PHP-FPM
       ↓
    WordPress
       ↓
    MySQL

    The key concept:

    Nginx does not execute PHP. PHP-FPM executes PHP for Nginx.


    1. What Is PHP?

    PHP is a server-side programming language.

    WordPress is primarily written in PHP.

    For example:

    index.php
    wp-load.php
    wp-settings.php

    are PHP files.

    The browser does not normally receive the PHP source code.

    Instead:

    PHP source
       ↓
    PHP execution
       ↓
    HTML
       ↓
    Browser

    2. Why PHP-FPM Exists

    Nginx is excellent at:

    HTTP
    HTTPS
    static files
    connections
    proxying

    But it doesn’t execute PHP.

    Therefore:

    Nginx
       ↓
    FastCGI
       ↓
    PHP-FPM
       ↓
    PHP

    3. PHP-FPM

    PHP-FPM means:

    PHP FastCGI Process Manager

    It manages PHP worker processes.

    Conceptually:

    PHP-FPM
    │
    ├── Worker 1
    ├── Worker 2
    ├── Worker 3
    └── Worker 4

    Each worker can execute PHP requests.


    4. Check PHP-FPM

    On Ubuntu, first check which PHP version is installed:

    php -v

    Then:

    systemctl list-units --type=service | grep php

    You may see something similar to:

    php8.3-fpm.service

    The exact version on your server may be different.


    5. Check the Service

    For example:

    sudo systemctl status php8.3-fpm

    If your installed version differs, substitute it.

    You want:

    Active: active (running)

    6. PHP CLI vs PHP-FPM

    These are different.

    PHP CLI

    php

    runs PHP from the command line.

    PHP-FPM

    php-fpm

    runs PHP workers that applications such as Nginx can communicate with.

    So:

    CLI
    =
    command-line PHP

    while:

    FPM
    =
    web-request PHP execution

    7. PHP-FPM Master Process

    PHP-FPM generally has a master process.

    Conceptually:

    PHP-FPM
       │
       └── Master
             │
             ├── Worker
             ├── Worker
             ├── Worker
             └── Worker

    The master manages the worker pool.


    8. Worker Processes

    When PHP requests arrive:

    Nginx
     ↓
    PHP-FPM
     ↓
    available worker
     ↓
    execute PHP

    The worker processes the PHP request.


    9. Why Multiple Workers?

    Suppose:

    User A → WordPress
    User B → WordPress
    User C → WordPress
    User D → WordPress

    You don’t want one PHP process to handle everything serially.

    Multiple workers allow concurrent processing.

    Conceptually:

    Request A → Worker 1
    Request B → Worker 2
    Request C → Worker 3
    Request D → Worker 4

    10. PHP-FPM Pool

    A group of PHP workers is called a:

    Pool

    A PHP-FPM installation can have multiple pools.

    For example:

    PHP-FPM
    │
    ├── www pool
    ├── site1 pool
    ├── site2 pool
    └── site3 pool

    11. Why Pools Matter for Hosting

    If you have:

    site1.com
    site2.com
    site3.com

    you could use one shared pool:

    All websites
          ↓
    www pool

    or separate pools:

    site1 → site1 pool
    site2 → site2 pool
    site3 → site3 pool

    For a hosting platform, separate pools can provide stronger isolation and more controllable resource limits.


    12. Shared Pool

    Simple architecture:

    Nginx
       │
       ▼
    PHP-FPM
       │
       ▼
    www pool
       │
       ├── site1
       ├── site2
       └── site3

    Advantages:

    simple
    fewer processes
    easy management

    Disadvantages:

    weaker isolation
    one busy site can consume shared PHP capacity

    13. Separate Pools

    More isolated:

    Nginx
    │
    ├── site1 → PHP pool 1
    ├── site2 → PHP pool 2
    └── site3 → PHP pool 3

    Advantages:

    better isolation
    different users
    different limits
    different PHP settings

    Disadvantages:

    more configuration
    more process-management complexity
    more memory overhead

    14. Hosting Architecture

    For your CresignSys hosting platform, the long-term architecture can be:

    site1
     ├── Linux user
     ├── files
     ├── Nginx config
     ├── PHP-FPM pool
     ├── PHP socket
     └── database
    
    site2
     ├── Linux user
     ├── files
     ├── Nginx config
     ├── PHP-FPM pool
     ├── PHP socket
     └── database

    15. Unix Socket

    Nginx and PHP-FPM can communicate using a Unix socket.

    Example:

    /run/php/site1.sock

    Flow:

    Nginx
     ↓
    Unix socket
     ↓
    PHP-FPM

    16. Why Unix Socket?

    When both services are on the same server, a Unix socket is often a simple and efficient local communication mechanism.

    You don’t need a network IP/port between Nginx and PHP-FPM.


    17. TCP Socket

    PHP-FPM can also listen on TCP.

    For example:

    127.0.0.1:9000

    Then:

    Nginx
     ↓
    127.0.0.1:9000
     ↓
    PHP-FPM

    18. Unix vs TCP

    For your single-server hosting setup:

    Unix socket

    is often convenient.

    For distributed architectures:

    TCP

    can be more appropriate.

    For example:

    Nginx Server
         ↓
    network
         ↓
    PHP Application Server

    requires network communication.


    19. PHP-FPM Configuration

    Configuration locations vary by PHP version.

    A common structure is:

    /etc/php/<version>/fpm/

    with:

    php-fpm.conf
    pool.d/

    Inside:

    pool.d/

    you may find:

    www.conf

    20. Default Pool

    A common default pool is:

    www

    with configuration such as:

    /etc/php/8.x/fpm/pool.d/www.conf

    The exact path depends on your installed PHP version.


    21. Pool Configuration

    A simplified pool configuration might look like:

    [site1]
    
    user = site1
    group = site1
    
    listen = /run/php/site1.sock

    Then process-management settings can be added.


    22. User and Group

    This is extremely important for hosting.

    Suppose:

    site1

    has its own Linux user.

    PHP-FPM workers for that pool can run as:

    site1

    instead of:

    www-data

    This improves isolation between websites.


    23. Why User Isolation Matters

    Suppose:

    site1
    site2

    are owned by different customers.

    If both PHP applications run as:

    www-data

    then filesystem separation can become more difficult.

    With:

    site1 → user1
    site2 → user2

    you can enforce stronger boundaries.


    24. Example

    /storage/websites/
    │
    ├── site1.com/
    │   └── public/
    │
    └── site2.com/
        └── public/

    Ownership:

    site1.com → site1
    site2.com → site2

    PHP:

    site1 pool → site1
    site2 pool → site2

    This creates a consistent security model.


    25. Nginx Worker User

    Nginx may still run workers as:

    www-data

    while PHP runs as:

    site1

    This is possible if the relevant filesystem and socket permissions are configured correctly.


    26. Socket Permission Problem

    Suppose PHP-FPM creates:

    /run/php/site1.sock

    owned by:

    site1:site1

    If Nginx cannot access it:

    Nginx
     ↓
    socket permission denied
     ↓
    502 Bad Gateway

    This is one of the most important causes of PHP-related 502 errors.


    27. Socket Ownership

    Pool configuration can specify socket ownership and permissions.

    Conceptually:

    listen.owner = www-data
    listen.group = www-data
    listen.mode = 0660

    This is only an example; the correct ownership model depends on how you isolate Nginx and PHP-FPM.


    28. Process Manager

    PHP-FPM has process management settings.

    The most important modes are:

    static
    dynamic
    ondemand

    29. static

    With:

    pm = static

    PHP-FPM maintains a fixed number of worker processes.

    For example:

    pm.max_children = 5

    means approximately five worker processes are maintained.


    30. dynamic

    With:

    pm = dynamic

    PHP-FPM adjusts the number of workers within configured limits.

    Important settings include:

    pm.max_children
    pm.start_servers
    pm.min_spare_servers
    pm.max_spare_servers

    31. ondemand

    With:

    pm = ondemand

    workers are created when requests arrive and can be terminated after being idle.

    This can be useful for sites with relatively low or irregular traffic.


    32. pm.max_children

    This is one of the most important settings.

    Example:

    pm.max_children = 10

    It limits the maximum number of simultaneous PHP worker processes in that pool.


    33. Why This Matters

    Suppose one PHP request consumes:

    100 MB RAM

    and you allow:

    10 workers

    Very roughly:

    10 × 100 MB
    =
    1000 MB

    plus:

    Nginx
    MySQL
    OS
    cache
    other processes

    So PHP worker limits must be based on actual memory usage, not arbitrary large numbers.


    34. Too Few Workers

    Suppose:

    pm.max_children = 2

    but:

    20 requests

    arrive simultaneously.

    Only two PHP requests can execute at once.

    The others wait.

    This can increase response time.


    35. Too Many Workers

    Suppose:

    pm.max_children = 100

    but your VPS has limited RAM.

    If PHP workers consume significant memory:

    100 workers
     ↓
    RAM exhaustion
     ↓
    swap/OOM
     ↓
    slow server
     ↓
    possible crashes

    Therefore:

    More PHP workers does not automatically mean more performance.


    36. CPU Also Matters

    PHP workers consume:

    RAM
    CPU

    Some requests are CPU-intensive.

    For example:

    large WordPress plugin
    image processing
    complex database operations

    can consume significant resources.


    37. Worker Concurrency

    Think:

    pm.max_children
    =
    maximum PHP concurrency for that pool

    It is not simply:

    number of visitors

    One visitor can generate multiple requests.

    And not every request requires PHP.


    38. Static Files Don’t Need PHP

    For:

    logo.png
    style.css
    script.js

    Nginx can often serve them directly.

    Therefore:

    100 static requests

    do not necessarily mean:

    100 PHP workers

    39. WordPress Dynamic Requests

    Requests such as:

    /wp-admin/
    login
    uncached pages
    POST requests
    AJAX/API operations

    may require PHP.

    The exact behavior depends on the application and caching configuration.


    40. PHP-FPM Queue

    If all workers are busy:

    Request
     ↓
    PHP-FPM
     ↓
    no free worker
     ↓
    wait

    Too much waiting can produce slow responses and eventually upstream timeouts.


    41. pm.max_requests

    Another useful setting:

    pm.max_requests = 500

    This tells a worker to process a limited number of requests before being recycled.

    Why?

    Long-running PHP processes can sometimes accumulate memory or other state.

    Recycling workers can help mitigate certain forms of gradual memory growth.


    42. pm.start_servers

    For dynamic mode:

    pm.start_servers = 3

    controls how many workers are started initially.


    43. pm.min_spare_servers

    Example:

    pm.min_spare_servers = 2

    controls the minimum number of idle workers maintained in dynamic mode.


    44. pm.max_spare_servers

    Example:

    pm.max_spare_servers = 5

    controls the maximum number of idle workers maintained.


    45. Example Pool

    A simplified educational example:

    [site1]
    
    user = site1
    group = site1
    
    listen = /run/php/site1.sock
    
    pm = dynamic
    pm.max_children = 10
    pm.start_servers = 2
    pm.min_spare_servers = 2
    pm.max_spare_servers = 5
    pm.max_requests = 500

    These numbers are examples, not recommended defaults for your VPS.


    46. Resource Calculation

    Before choosing:

    pm.max_children

    measure actual PHP worker memory usage.

    For example:

    ps --no-headers -o rss,cmd -C php-fpm8.3

    The exact process name depends on your PHP version.


    47. RSS

    RSS means:

    Resident Set Size

    It provides an approximation of how much physical memory a process currently occupies.

    For PHP-FPM tuning, this is useful.


    48. Better Principle

    Don’t say:

    My VPS has 8 GB RAM, so I’ll set 50 PHP workers.

    Instead:

    Available RAM
     ↓
    reserve RAM for OS
     ↓
    reserve RAM for MySQL
     ↓
    reserve RAM for Nginx
     ↓
    reserve RAM for other services
     ↓
    remaining RAM
     ↓
    measure PHP worker size
     ↓
    calculate reasonable concurrency

    49. Example Calculation

    Suppose:

    VPS RAM = 8 GB

    Reserve approximately:

    OS + services = 2 GB
    MySQL = 2 GB

    Remaining:

    4 GB

    If average PHP worker usage is:

    100 MB

    then a theoretical upper bound is roughly:

    4000 / 100
    =
    40 workers

    But you should not automatically configure 40.

    You need safety margin and real workload measurements.


    50. WordPress Can Vary Greatly

    One PHP request might use:

    50 MB

    while another might use:

    250 MB

    depending on:

    plugins
    theme
    queries
    image processing
    API calls
    application state

    Therefore average and peak behavior matter.


    51. PHP-FPM Slow Requests

    PHP-FPM can be configured with a:

    Slowlog

    This helps identify requests that take too long.

    A slowlog can help you discover:

    slow plugin
    slow WordPress operation
    slow PHP script
    database-related delay

    52. Request Timeout

    Nginx also has upstream timeout settings.

    Conceptually:

    Nginx
     ↓
    waiting for PHP-FPM
     ↓
    too long
     ↓
    timeout

    This can produce:

    504 Gateway Timeout

    53. 502 vs 504

    Remember:

    502

    Often:

    Nginx
     ↓
    can't properly communicate with upstream

    504

    Often:

    Nginx
     ↓
    upstream didn't respond in time

    These are clues, not absolute diagnoses.


    54. Check PHP-FPM Logs

    Depending on your installation:

    sudo journalctl -u php8.3-fpm

    or:

    sudo journalctl -u php8.3-fpm --since "30 minutes ago"

    Replace the version with your installed PHP-FPM service.


    55. Check Nginx Errors

    sudo tail -f /var/log/nginx/error.log

    Then load the website.

    Watch what appears.

    This is an excellent troubleshooting technique.


    56. Real-Time Debugging

    Open terminal 1:

    sudo tail -f /var/log/nginx/error.log

    Open terminal 2:

    curl -I https://learn.cresignsys.com

    Now observe whether Nginx reports an error.


    57. PHP-FPM Status

    You can also inspect:

    systemctl status php8.3-fpm

    Then:

    ps aux | grep php-fpm

    You may see:

    master process
    pool site1
    pool site2

    58. One Pool Per Website

    Your future CresignSys architecture could look like:

    PHP-FPM
    │
    ├── site1.com
    │    ├── user = site1
    │    └── socket = site1.sock
    │
    ├── site2.com
    │    ├── user = site2
    │    └── socket = site2.sock
    │
    └── site3.com
         ├── user = site3
         └── socket = site3.sock

    59. Nginx Mapping

    Then:

    site1.com
     ↓
    Nginx server block
     ↓
    site1.sock
     ↓
    site1 PHP-FPM pool

    and:

    site2.com
     ↓
    Nginx server block
     ↓
    site2.sock
     ↓
    site2 PHP-FPM pool

    60. Stronger Isolation

    Now imagine:

    site1

    is compromised through a vulnerable plugin.

    If its PHP processes run as:

    site1

    rather than a shared hosting user, access to other sites can be more strongly restricted by filesystem permissions.

    This is one reason shared-hosting systems isolate accounts.


    61. Important Security Rule

    Do not assume:

    different directories
    =
    security isolation

    If all applications run under the same powerful user:

    www-data

    one compromised application may potentially access other files that user can read.

    User/process isolation is therefore important in multi-tenant hosting.


    62. Database Isolation Too

    The same principle applies to MySQL.

    Instead of:

    all websites
     ↓
    one database
     ↓
    one powerful database user

    prefer:

    site1
     ↓
    database1
     ↓
    dbuser1
    
    site2
     ↓
    database2
     ↓
    dbuser2

    with only the required privileges.


    63. Complete Per-Site Isolation Model

    A strong hosting model looks like:

    SITE 1
    │
    ├── Linux user
    ├── filesystem
    ├── Nginx server block
    ├── PHP-FPM pool
    ├── PHP socket
    ├── database
    └── database user
    
    
    SITE 2
    │
    ├── Linux user
    ├── filesystem
    ├── Nginx server block
    ├── PHP-FPM pool
    ├── PHP socket
    ├── database
    └── database user

    64. Your Hosting Automation

    When you create a new domain:

    create-site example.com

    your automation can eventually perform:

    1. Create Linux user
    2. Create website directories
    3. Set ownership
    4. Create PHP-FPM pool
    5. Create PHP socket
    6. Create Nginx configuration
    7. Validate Nginx
    8. Reload Nginx
    9. Create MySQL database
    10. Create database user
    11. Install WordPress
    12. Configure SSL

    65. The Most Important PHP-FPM Settings

    At your current level, memorize:

    user
    group
    listen
    pm
    pm.max_children
    pm.start_servers
    pm.min_spare_servers
    pm.max_spare_servers
    pm.max_requests

    66. Their Meaning

    user
    → Which Linux user executes PHP?
    
    group
    → Which Linux group?
    
    listen
    → Where does Nginx connect?
    
    pm
    → How are PHP workers managed?
    
    pm.max_children
    → Maximum simultaneous PHP workers
    
    pm.start_servers
    → Initial workers
    
    pm.min_spare_servers
    → Minimum idle workers
    
    pm.max_spare_servers
    → Maximum idle workers
    
    pm.max_requests
    → Requests before recycling a worker

    67. The Complete PHP Request

    Now combine everything:

    Browser
       ↓
    HTTPS
       ↓
    Nginx
       ↓
    location /
       ↓
    try_files
       ↓
    index.php
       ↓
    FastCGI
       ↓
    PHP-FPM socket
       ↓
    PHP-FPM pool
       ↓
    PHP worker
       ↓
    WordPress
       ↓
    MySQL

    68. Where 502 Happens

    Nginx
       ↓
    PHP-FPM

    If this communication fails:

    502 Bad Gateway

    Investigate:

    PHP-FPM running?
     ↓
    socket exists?
     ↓
    socket permissions?
     ↓
    correct socket path?
     ↓
    correct PHP-FPM pool?

    69. Where 504 Happens

    Usually:

    Nginx
       ↓
    PHP-FPM
       ↓
    long-running request

    If the upstream takes too long:

    504 Gateway Timeout

    Investigate:

    slow PHP
    slow WordPress
    slow plugin
    slow MySQL
    external API
    resource exhaustion

    70. Lesson 060 — Core Principle

    Remember this:

    Nginx receives the web request; PHP-FPM provides the PHP execution environment.

    The architecture is:

                      INTERNET
                         │
                         ▼
                       NGINX
                         │
                   FastCGI │
                         ▼
                     PHP-FPM
                         │
                  ┌──────┴──────┐
                  ▼             ▼
               Site 1        Site 2
               Pool 1        Pool 2
                  │             │
                  ▼             ▼
              WordPress      WordPress
                  │             │
                  ▼             ▼
               MySQL 1        MySQL 2

    This is the foundation for turning your Ubuntu VPS into a proper multi-website hosting server.


    Next Lesson — 061

    MySQL for Hosting — Databases, Users, Privileges & WordPress

    We will next learn:

    MySQL
     ↓
    Database
     ↓
    Table
     ↓
    Row
     ↓
    Column
     ↓
    Database user
     ↓
    Privileges
     ↓
    WordPress wp-config.php
     ↓
    PHP → MySQL

    Then we will design the correct one-database + one-database-user-per-website model for your CresignSys hosting platform and learn how to create it safely from the command line.

  • CresignSys Learn — Lesson 059

    Nginx Deep Dive — How One Server Hosts Many Websites

    We now reach the web-server layer.

    You already understand:

    Domain
     ↓
    DNS
     ↓
    IP
     ↓
    Network
     ↓
    TCP 443
     ↓
    TLS
     ↓
    HTTP

    Now we need to understand what happens when that request reaches Nginx.


    1. What Is Nginx?

    Nginx is a high-performance web server and reverse proxy.

    It can:

    serve static files
    handle HTTP/HTTPS
    route domains
    forward PHP requests
    act as reverse proxy
    handle redirects
    serve cached content

    For your hosting platform:

    Internet
       ↓
    Nginx
       ↓
    PHP-FPM
       ↓
    WordPress
       ↓
    MySQL

    2. Nginx Is Not WordPress

    This distinction is important.

    Nginx
    =
    web server

    while:

    WordPress
    =
    web application

    Nginx receives the network request.

    WordPress generates the application response.


    3. Static vs Dynamic

    Suppose the browser requests:

    /logo.png

    Nginx may directly return the file:

    Browser
     ↓
    Nginx
     ↓
    logo.png

    No PHP required.


    4. Dynamic Request

    Now:

    /about/

    may require WordPress.

    The flow becomes:

    Browser
     ↓
    Nginx
     ↓
    PHP-FPM
     ↓
    WordPress
     ↓
    MySQL
     ↓
    PHP-FPM
     ↓
    Nginx
     ↓
    Browser

    5. Nginx Master Process

    When Nginx starts, there is normally a:

    Master process

    Its responsibilities include things such as:

    read configuration
    manage worker processes
    handle signals
    reload configuration

    6. Worker Processes

    Nginx also uses:

    Worker processes

    Workers handle network requests.

    Conceptually:

    Nginx
    │
    ├── Master
    │
    ├── Worker
    ├── Worker
    ├── Worker
    └── Worker

    The exact number depends on configuration and workload.


    7. Check Nginx Processes

    Run:

    ps aux | grep nginx

    You may see:

    root      nginx: master process
    www-data  nginx: worker process
    www-data  nginx: worker process

    The exact user and process details depend on your configuration.


    8. Why Master Can Be Root

    Nginx may start with elevated privileges so it can perform privileged operations such as binding to low-numbered ports.

    Then worker processes can run with a less-privileged user.

    This follows the same principle we studied earlier:

    root
     ↓
    privileged setup
     ↓
    lower privilege workers

    9. Low Ports

    Ports below 1024 traditionally require elevated privileges to bind on Linux.

    For example:

    80
    443

    Therefore the master process may start with sufficient privilege to bind them.

    Worker processes then handle requests with reduced privileges.


    10. Configuration

    Nginx’s main configuration is commonly:

    /etc/nginx/nginx.conf

    But your installation may include additional configuration directories.

    Common structure:

    /etc/nginx/
    ├── nginx.conf
    ├── sites-available/
    ├── sites-enabled/
    ├── conf.d/
    └── ...

    The exact layout depends on the distribution and installation.


    11. Main Configuration

    Check:

    sudo nginx -t

    This tests configuration syntax.

    You can inspect the main file:

    sudo nano /etc/nginx/nginx.conf

    or:

    sudo less /etc/nginx/nginx.conf

    12. http Block

    Nginx configuration has hierarchical blocks.

    Conceptually:

    http {
        server {
            ...
        }
    
        server {
            ...
        }
    }

    The http block contains HTTP configuration.


    13. Server Block

    A:

    server

    block represents a virtual server configuration.

    For example:

    server {
        listen 80;
        server_name example.com;
    }

    This is how Nginx can host multiple websites on one IP.


    14. Multiple Websites

    Suppose your server has:

    203.0.113.25

    and:

    site1.com
    site2.com
    site3.com

    All point to that IP.

    Nginx can have:

    server block 1
    → site1.com
    
    server block 2
    → site2.com
    
    server block 3
    → site3.com

    15. server_name

    The most important directive for virtual hosting is:

    server_name site1.com www.site1.com;

    This tells Nginx which hostnames the server block is intended to handle.


    16. Example

    server {
        listen 80;
        server_name learn.cresignsys.com;
    
        root /storage/websites/learn.cresignsys.com/public;
    }

    Now:

    Host:
    learn.cresignsys.com

    can select this server block.


    17. listen

    This directive tells Nginx which address/port the server block listens on.

    Example:

    listen 80;

    or HTTPS:

    listen 443 ssl;

    Modern configurations can also use additional directives for HTTP/2/HTTP/3 depending on Nginx version and configuration.


    18. One Server, Many server Blocks

    Example:

    server {
        listen 80;
        server_name site1.com;
    
        root /storage/websites/site1.com/public;
    }
    
    server {
        listen 80;
        server_name site2.com;
    
        root /storage/websites/site2.com/public;
    }

    Both can use:

    203.0.113.25:80

    19. How Nginx Knows Which One?

    The request contains the hostname.

    For example:

    Host: site2.com

    Nginx searches its matching server configuration.

    Conceptually:

    Host: site2.com
            ↓
    server_name site2.com
            ↓
    site2 configuration

    20. Default Server

    What happens if no hostname matches?

    Nginx uses the appropriate default server for that listen address/port.

    Therefore, a request can sometimes display:

    wrong website

    even though DNS is correct.

    This is a common hosting issue.


    21. Example Problem

    You configured:

    siteA.com
    siteB.com

    But accidentally omitted:

    server_name siteB.com;

    Then:

    siteB.com

    may fall into another server block, potentially the default one.


    22. root

    The:

    root

    directive specifies the filesystem root for serving files.

    Example:

    root /storage/websites/site1.com/public;

    Therefore:

    URL:
    /logo.png
    
    Filesystem:
    /storage/websites/site1.com/public/logo.png

    for a direct static-file request, subject to Nginx location and rewrite rules.


    23. Your Hosting Structure

    Your current architecture is similar to:

    /storage/websites/
    │
    ├── learn.cresignsys.com/
    │   └── public/
    │
    ├── shop.cresignsys.com/
    │   └── public/
    │
    ├── manage.cresignsys.com/
    │   └── public/
    │
    └── ...

    This is a good foundation for a hosting platform.


    24. Why public?

    Keeping the web-accessible files inside:

    public/

    is useful.

    For example:

    site/
    ├── public/
    │   ├── index.php
    │   ├── wp-content/
    │   └── ...
    │
    └── private/

    Only:

    public/

    is exposed as the web root.


    25. Security Benefit

    Suppose your site has:

    site/
    ├── public/
    └── backups/

    If Nginx root is:

    site/public

    then:

    /backups/

    is not automatically web-accessible.

    This is much safer than making the entire site directory the document root.


    26. location

    Nginx uses:

    location

    blocks to control different URL paths.

    Example:

    location / {
        ...
    }

    means the general URL space.


    27. Example

    location /images/ {
        ...
    }

    can apply special behavior to:

    /images/logo.png
    /images/banner.jpg

    28. Location Matching

    Nginx has specific rules for choosing among multiple location blocks.

    For example:

    location / {
    }
    
    location /images/ {
    }
    
    location = /login {
    }

    The exact matching algorithm is important later.

    For now remember:

    location
    =
    URL-path processing rule

    29. try_files

    One of the most important directives for WordPress:

    try_files

    A common pattern is:

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

    30. What Does It Mean?

    Conceptually:

    Request
     ↓
    Does the requested file exist?
     ↓
    yes → serve it
     ↓
    no
     ↓
    Does the directory exist?
     ↓
    yes → use it
     ↓
    no
     ↓
    send to index.php

    This allows WordPress’s pretty URLs to work.


    31. WordPress Pretty URL

    Browser requests:

    /about/

    There may be no physical:

    /about/index.html

    Instead:

    /about/
     ↓
    index.php
     ↓
    WordPress
     ↓
    About page

    32. Front Controller

    This architecture is called a:

    Front Controller

    WordPress commonly uses:

    index.php

    as the central entry point.

    So many URLs eventually reach:

    index.php

    33. PHP Location

    Nginx needs a rule for PHP.

    Conceptually:

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php-fpm.sock;
    }

    The exact socket path depends on your PHP-FPM installation.


    34. FastCGI

    Nginx does not execute PHP itself.

    Instead:

    Nginx
     ↓
    FastCGI
     ↓
    PHP-FPM

    FastCGI is a protocol/interface for communicating with application processes such as PHP-FPM.


    35. PHP-FPM

    PHP-FPM means:

    PHP FastCGI Process Manager

    It manages PHP worker processes.

    Conceptually:

    Nginx
       │
       ▼
    PHP-FPM
       │
       ├── PHP worker
       ├── PHP worker
       ├── PHP worker
       └── PHP worker

    36. Nginx Doesn’t Run PHP

    This is worth memorizing:

    Nginx
    ≠
    PHP

    Nginx handles:

    HTTP
    static files
    proxying
    routing

    PHP-FPM handles:

    PHP execution

    37. Static Request

    For:

    /logo.png

    the flow can be:

    Browser
     ↓
    Nginx
     ↓
    /public/logo.png
     ↓
    Browser

    38. PHP Request

    For:

    /index.php

    the flow can be:

    Browser
     ↓
    Nginx
     ↓
    PHP-FPM
     ↓
    PHP
     ↓
    Nginx
     ↓
    Browser

    39. WordPress Request

    For:

    /about/

    the flow is often:

    Browser
     ↓
    Nginx
     ↓
    try_files
     ↓
    index.php
     ↓
    PHP-FPM
     ↓
    WordPress
     ↓
    MySQL
     ↓
    PHP
     ↓
    Nginx
     ↓
    Browser

    40. One Server, Multiple PHP-FPM Pools

    For professional hosting, you can eventually configure:

    PHP-FPM
    │
    ├── site1 pool → user1
    ├── site2 pool → user2
    ├── site3 pool → user3
    └── ...

    This provides better isolation than having every site share one PHP execution identity.


    41. Site-Specific Socket

    Each PHP-FPM pool can have its own socket.

    Conceptually:

    site1
     ↓
    /run/php/site1.sock
    
    site2
     ↓
    /run/php/site2.sock

    Nginx can then route each site’s PHP requests to its own pool.


    42. Why This Is Powerful

    Suppose:

    site1

    gets heavy traffic.

    You can configure its PHP-FPM pool separately from:

    site2

    You can control things such as:

    worker limits
    process management
    user
    group
    socket

    43. Resource Isolation

    This leads to a professional architecture:

    siteA
     ↓
    userA
     ↓
    PHP pool A
     ↓
    socket A
    
    siteB
     ↓
    userB
     ↓
    PHP pool B
     ↓
    socket B

    Now sites are more strongly separated.


    44. Your CresignSys Hosting Platform

    Your automation can eventually create:

    CREATE WEBSITE
           │
           ├── domain
           ├── directory
           ├── user
           ├── group
           ├── PHP-FPM pool
           ├── socket
           ├── Nginx server block
           ├── database
           ├── database user
           ├── DNS
           └── SSL

    This is the architecture you are gradually building toward.


    45. Nginx Configuration Generation

    For:

    learn.cresignsys.com

    your automation could generate a configuration conceptually like:

    server {
        listen 80;
        server_name learn.cresignsys.com;
    
        root /storage/websites/learn.cresignsys.com/public;
    
        index index.php index.html;
    
        location / {
            try_files $uri $uri/ /index.php?$args;
        }
    
        location ~ \.php$ {
            include fastcgi_params;
            fastcgi_pass unix:/run/php/learn.cresignsys.com.sock;
        }
    }

    This is a simplified teaching example; production configurations need additional security and PHP-FPM parameters.


    46. Why Configuration Templates Matter

    Imagine manually configuring:

    1 website

    Not too difficult.

    But:

    10 websites

    becomes repetitive.

    At:

    100 websites

    manual configuration becomes error-prone.

    Therefore:

    Template
    +
    Automation

    becomes essential.


    47. Your Hosting Script

    Your hosting creation system can receive:

    DOMAIN=example.com

    and generate:

    /storage/websites/example.com/public

    then:

    Nginx configuration
    PHP-FPM pool
    database
    permissions
    SSL

    48. The Hosting Control Plane

    This introduces an important concept:

    Control Plane

    Your management system decides:

    What websites exist?
    Who owns them?
    Where are they stored?
    Which PHP version?
    Which database?
    Which domain?
    Which SSL certificate?

    49. Data Plane

    The actual traffic path is the:

    Data Plane

    Internet
     ↓
    Nginx
     ↓
    PHP-FPM
     ↓
    WordPress
     ↓
    MySQL

    Your control panel manages the configuration.

    The web stack serves the traffic.


    50. Example

    Your hosting platform might have:

    Control Plane
           │
           ▼
    Create Website
           │
           ├── Nginx config
           ├── PHP-FPM config
           ├── database
           └── SSL
           
    Data Plane
           │
           ▼
    Internet
           ↓
    Nginx
           ↓
    PHP
           ↓
    WordPress

    This distinction becomes very important when designing a real hosting service.


    51. Nginx Reload

    After generating configuration:

    sudo nginx -t

    First.

    If successful:

    sudo systemctl reload nginx

    Never make blind configuration changes and immediately restart the server without testing the configuration.


    52. Why nginx -t Is Important

    Suppose your script generates:

    server_name example.com

    but forgets:

    ;

    Nginx configuration becomes invalid.

    If you reload blindly:

    reload failure

    could affect your hosting service.

    Therefore:

    Generate
     ↓
    Validate
     ↓
    Reload

    53. Safe Automation Pattern

    Your hosting script should conceptually do:

    1. Validate domain
            ↓
    2. Create directories
            ↓
    3. Create user
            ↓
    4. Set permissions
            ↓
    5. Create PHP-FPM configuration
            ↓
    6. Create Nginx configuration
            ↓
    7. nginx -t
            ↓
    8. Reload Nginx
            ↓
    9. Configure database
            ↓
    10. Configure SSL

    Error handling becomes critical.


    54. Nginx Logs

    Common log directory:

    /var/log/nginx/

    You may find:

    access.log
    error.log

    or per-site logs if your configuration defines them.


    55. Access Log

    An access log answers:

    Did Nginx receive the request?

    You may see:

    GET /about/ HTTP/2
    200

    56. Error Log

    The error log answers:

    Did Nginx encounter a problem?

    Examples:

    permission denied
    connect() failed
    upstream timed out
    no such file

    57. Nginx + Permissions

    Remember the previous lesson.

    Nginx needs filesystem access.

    If:

    /storage/websites/example.com/public

    cannot be traversed by the Nginx worker user, you may get:

    403 Forbidden

    58. Nginx + PHP-FPM

    If:

    Nginx
     ↓
    PHP-FPM socket

    is inaccessible:

    502 Bad Gateway

    may occur.

    So permissions also apply to:

    /run/php/

    and the PHP-FPM socket.


    59. Socket Permissions

    Suppose:

    /run/php/site.sock

    belongs to:

    siteuser:www-data

    and has restrictive permissions.

    Nginx must be able to access the socket.

    Otherwise:

    Nginx
     ↓
    cannot connect
     ↓
    502

    60. This Connects Three Lessons

    We now have:

    Networking

    TCP 443

    Nginx

    server_name
    root
    location

    Linux permissions

    user
    group
    socket/file permissions

    These aren’t separate topics.

    They interact.


    61. Example Failure

    Suppose:

    DNS ✓
    TCP 443 ✓
    Nginx ✓

    but:

    Nginx → PHP-FPM socket ✗

    Result:

    502 Bad Gateway

    The problem isn’t DNS.

    It isn’t the domain.

    It isn’t WordPress.

    It is the Nginx-to-PHP-FPM layer.


    62. Another Failure

    Suppose:

    DNS ✓
    TCP ✓
    Nginx ✓
    PHP-FPM ✓

    but:

    WordPress directory
    permissions ✗

    Result may be:

    403
    500
    file access errors

    depending on exactly what operation failed.


    63. Another Failure

    Suppose everything works except:

    MySQL

    Then PHP may produce:

    database connection error

    The HTTP server is functioning.

    The application backend isn’t.


    64. Layered Architecture

    Your complete website is now:

    ┌─────────────────────────────┐
    │          INTERNET           │
    └──────────────┬──────────────┘
                   ↓
                 DNS
                   ↓
              Public IP
                   ↓
            OCI Networking
                   ↓
                TCP 443
                   ↓
                 Nginx
                   ↓
            ┌──────┴──────┐
            ↓             ↓
       Static files     PHP-FPM
                          ↓
                      WordPress
                          ↓
                        MySQL

    And:

    Users
    Groups
    Permissions

    control filesystem/process access underneath.


    65. The Most Important Nginx Directives

    For your current level, memorize these:

    listen
    server_name
    root
    index
    location
    try_files
    include
    fastcgi_pass

    66. Their Meaning

    listen
    → Which network endpoint?
    
    server_name
    → Which domain?
    
    root
    → Which filesystem directory?
    
    index
    → Which default files?
    
    location
    → Which URL rules?
    
    try_files
    → Does the requested resource exist?
    
    include
    → Load reusable configuration
    
    fastcgi_pass
    → Where should PHP requests go?

    67. One Website

    learn.cresignsys.com
            ↓
    Nginx
            ↓
    /storage/websites/learn.cresignsys.com/public
            ↓
    PHP-FPM
            ↓
    WordPress

    68. Ten Websites

    Nginx
    │
    ├── site1.com → PHP-FPM 1
    ├── site2.com → PHP-FPM 2
    ├── site3.com → PHP-FPM 3
    ├── site4.com → PHP-FPM 4
    ├── site5.com → PHP-FPM 5
    └── ...

    This is the foundation of a hosting server.


    69. Hundreds of Websites

    At larger scale:

    Internet
        ↓
    Load Balancer / Edge
        ↓
    Web Servers
        ↓
    PHP/Application Layer
        ↓
    Database/Cache/Storage

    A single VPS can host multiple sites, but at larger scale you start separating services and workloads.


    70. Lesson 059 — Core Principle

    The central idea is:

    Nginx is the traffic director at the web-server layer.

    It receives:

    IP
     ↓
    Port
     ↓
    HTTP request

    and determines:

    Which domain?
     ↓
    Which server block?
     ↓
    Which URL rule?
     ↓
    Static file or PHP?
     ↓
    Which PHP-FPM backend?

    That is the foundation of multi-domain hosting.


    Next Lesson — 060

    PHP-FPM Deep Dive — How Nginx Runs WordPress PHP

    Next we go one level deeper:

    Nginx
     ↓
    FastCGI
     ↓
    PHP-FPM
     ↓
    Master process
     ↓
    Worker pool
     ↓
    PHP execution
     ↓
    WordPress

    We will learn:

    PHP-FPM pools
    users
    groups
    Unix sockets
    TCP sockets
    pm.max_children
    pm.start_servers
    pm.min_spare_servers
    pm.max_spare_servers
    pm.max_requests
    memory usage
    slow requests
    502 errors

    and how to design one PHP-FPM pool per website for your CresignSys hosting platform.

  • CresignSys Learn — Lesson 058

    HTTP Deep Dive — How a Web Request Actually Works

    We now know:

    Domain
     ↓
    DNS
     ↓
    IP
     ↓
    Routing
     ↓
    TCP
     ↓
    Port 443
     ↓
    Nginx

    Now we need to understand what happens after the browser reaches Nginx.

    That is the job of:

    HTTP


    1. What Is HTTP?

    HTTP means:

    Hypertext Transfer Protocol

    It is the protocol used for communication between a web client and a web server.

    Simplified:

    Browser
       ↓
    HTTP Request
       ↓
    Web Server
       ↓
    HTTP Response
       ↓
    Browser

    2. HTTPS

    When HTTP is protected by TLS:

    HTTP
     +
    TLS
     =
    HTTPS

    So:

    http://example.com

    normally uses:

    TCP 80

    while:

    https://example.com

    normally uses:

    TCP 443

    3. The First Request

    Suppose you open:

    https://learn.cresignsys.com/about/

    After DNS and the network connection are established, the browser sends an HTTP request.

    Conceptually:

    GET /about/ HTTP/1.1
    Host: learn.cresignsys.com

    There are additional headers in a real browser request.


    4. HTTP Request

    An HTTP request contains several important parts:

    Request
    ├── Method
    ├── URL/path
    ├── Headers
    └── Body

    For example:

    GET /about/

    is the main request line.


    5. HTTP Methods

    The most important HTTP methods are:

    GET
    POST
    PUT
    PATCH
    DELETE
    HEAD
    OPTIONS

    For basic WordPress hosting, start with:

    GET
    POST

    6. GET

    GET generally means:

    Give me this resource.

    Example:

    GET /about/

    The browser is asking the server for the About page.


    7. Another GET

    For:

    https://learn.cresignsys.com/contact/

    the request may be:

    GET /contact/ HTTP/1.1
    Host: learn.cresignsys.com

    8. POST

    POST is commonly used to send data to the server.

    For example:

    Login form
    Contact form
    WordPress admin login
    Comment submission

    A simplified request:

    POST /wp-login.php HTTP/1.1

    The submitted data is normally in the request body.


    9. Request Body

    For example, a form submission might contain data such as:

    username=admin
    password=...

    The actual request encoding and security depend on the application.

    With HTTPS, the network transport is encrypted.


    10. HTTP Headers

    Headers provide additional information.

    Example:

    Host: learn.cresignsys.com
    User-Agent: ...
    Accept: text/html
    Accept-Encoding: gzip, br

    Headers tell the server about the request and tell the client how to interpret the response.


    11. Host Header

    This is extremely important for hosting.

    Suppose the same VPS hosts:

    siteA.com
    siteB.com
    siteC.com

    All have:

    203.0.113.25

    The browser sends:

    Host: siteB.com

    Nginx can then choose the appropriate website.


    12. Virtual Hosting

    Therefore:

    203.0.113.25
          │
          ├── siteA.com
          ├── siteB.com
          └── siteC.com

    is possible.

    Nginx uses hostname information to route the request to the correct server configuration.


    13. Nginx Server Block

    A simplified configuration:

    server {
        listen 443 ssl;
        server_name siteB.com www.siteB.com;
    
        root /storage/websites/siteB.com/public;
    }

    The important relationship is:

    Host: siteB.com
            ↓
    server_name siteB.com
            ↓
    document root

    14. URL Structure

    Consider:

    https://learn.cresignsys.com/blog/post-1/?page=2

    Break it down:

    https://
    learn.cresignsys.com
    /blog/post-1/
    ?page=2

    These components have different purposes.


    15. Scheme

    https://

    is the scheme.

    It tells the client to use HTTPS.


    16. Host

    learn.cresignsys.com

    is the hostname.

    DNS resolves this hostname.


    17. Path

    /blog/post-1/

    is the path.

    It identifies the requested resource within the website.


    18. Query String

    ?page=2

    is the query string.

    It passes additional parameters.

    Example:

    /search/?q=wordpress

    Here:

    q=wordpress

    is a query parameter.


    19. Fragment

    You might see:

    /about/#services

    The:

    #services

    is a URL fragment.

    Normally, the fragment is handled by the browser and is not sent to the server as part of the HTTP request.

    This distinction is important.


    20. Complete URL

    https://learn.cresignsys.com/about/?lang=en#history

    Breakdown:

    Scheme:
    https
    
    Host:
    learn.cresignsys.com
    
    Path:
    /about/
    
    Query:
    lang=en
    
    Fragment:
    history

    21. HTTP Response

    After receiving the request, the server responds.

    Example:

    HTTP/1.1 200 OK
    Content-Type: text/html
    Content-Length: ...

    Then comes the response body:

    <html>
    ...
    </html>

    22. Response Structure

    An HTTP response contains:

    Response
    ├── Status code
    ├── Headers
    └── Body

    23. Status Codes

    HTTP status codes are grouped into categories:

    1xx
    2xx
    3xx
    4xx
    5xx

    You should memorize the most important ones.


    24. 200

    200 OK

    means the request was successfully handled.

    Example:

    GET /
     ↓
    200 OK

    25. 201

    201 Created

    means a resource was successfully created.

    This is common in APIs.


    26. 204

    204 No Content

    means the request succeeded but there is no response body to return.


    27. 301

    301 Moved Permanently

    indicates a permanent redirect.

    Example:

    http://example.com
            ↓
    301
            ↓
    https://example.com

    28. 302

    302 Found

    is commonly used for temporary redirects.

    Redirect behavior is more nuanced across HTTP versions and applications, but the key idea is:

    server
     ↓
    redirect
     ↓
    another URL

    29. 304

    304 Not Modified

    is used with caching.

    It tells the browser that the cached representation can still be used when the request conditions allow it.


    30. 400

    400 Bad Request

    means the server considers the request malformed or invalid.


    31. 401

    401 Unauthorized

    means authentication is required or failed.

    Despite the name, this generally means:

    Authentication is needed.


    32. 403

    403 Forbidden

    means the server understood the request but refuses to authorize access.

    Common causes:

    permission
    access rules
    directory restrictions
    application authorization

    33. 404

    404 Not Found

    means the requested resource could not be found.

    For example:

    GET /does-not-exist/

    may return:

    404 Not Found

    34. 405

    405 Method Not Allowed

    means the resource exists but does not allow the HTTP method used.


    35. 408

    408 Request Timeout

    indicates the server timed out waiting for the request.


    36. 429

    429 Too Many Requests

    usually means rate limiting has been triggered.

    This can be generated by:

    Nginx
    application
    CDN
    API gateway
    security layer

    37. 500

    500 Internal Server Error

    means the server encountered an unexpected error.

    For WordPress, possible causes include:

    PHP error
    plugin error
    theme error
    configuration error

    38. 502

    502 Bad Gateway

    is particularly important in your hosting environment.

    It often means a proxy such as Nginx could not obtain a valid response from its upstream service.

    For WordPress:

    Nginx
     ↓
    PHP-FPM

    If PHP-FPM is unavailable or misconfigured, you may get:

    502

    39. 503

    503 Service Unavailable

    means the server is currently unable to handle the request.

    Possible reasons include:

    overload
    maintenance
    upstream unavailable
    application limits

    40. 504

    504 Gateway Timeout

    means a gateway/proxy waited too long for an upstream response.

    Example:

    Nginx
     ↓
    PHP-FPM
     ↓
    MySQL

    If the upstream operation takes too long, a timeout can occur.


    41. Status Code Troubleshooting

    Memorize this table:

    CodeMeaningHosting clue
    200OKWorking
    301Permanent redirectURL redirect
    302Temporary redirectRedirect
    304Not modifiedCache
    400Bad requestInvalid request
    401Authentication requiredLogin/auth
    403ForbiddenAccess/permissions
    404Not foundURL/resource
    429Too many requestsRate limit
    500Server errorPHP/application
    502Bad gatewayPHP-FPM/upstream
    503UnavailableService/load
    504Gateway timeoutSlow upstream

    42. curl

    For web hosting, curl is one of your most important tools.

    Test:

    curl -I https://learn.cresignsys.com

    The -I option requests headers without downloading the full body in the usual way.


    43. Example

    You may see:

    HTTP/2 200
    server: nginx
    content-type: text/html

    Now you know:

    DNS ✓
    network ✓
    TLS ✓
    Nginx ✓
    HTTP ✓

    at least at a basic level.


    44. Follow Redirects

    Use:

    curl -IL https://learn.cresignsys.com

    The:

    -L

    option follows redirects.

    You may see:

    301
     ↓
    https://...
     ↓
    200

    45. See More Details

    Use:

    curl -v https://learn.cresignsys.com

    This can show details about:

    DNS connection
    TCP connection
    TLS
    HTTP request
    HTTP response

    It is extremely useful for troubleshooting.


    46. TLS + HTTP

    When you run:

    curl -v https://learn.cresignsys.com

    you can see the stages:

    DNS
     ↓
    TCP connection
     ↓
    TLS handshake
     ↓
    HTTP request
     ↓
    HTTP response

    This connects our previous lessons together.


    47. HTTP Headers

    Some important response headers include:

    Content-Type
    Content-Length
    Cache-Control
    Location
    Set-Cookie
    Server
    ETag
    Last-Modified

    48. Content-Type

    Example:

    Content-Type: text/html

    means the body is HTML.

    Other examples:

    text/css
    application/javascript
    application/json
    image/jpeg
    image/png

    49. Why Content-Type Matters

    The browser uses the content type to determine how to interpret the response.

    For example:

    text/html

    → render as HTML.

    image/png

    → interpret as PNG image.


    50. Content-Length

    Example:

    Content-Length: 48291

    This indicates the size of the response body in bytes in contexts where this header is used.


    51. Cache-Control

    Example:

    Cache-Control: max-age=3600

    This provides caching instructions.

    Caching is extremely important for hosting performance.


    52. Browser Cache

    Suppose your website contains:

    style.css
    logo.png
    script.js

    Downloading them repeatedly wastes resources.

    The browser can cache them.

    Therefore:

    First visit
     ↓
    download
     ↓
    cache

    Later:

    visit
     ↓
    use cache

    when the caching rules permit.


    53. Server Cache

    You can also cache on the server side.

    For WordPress:

    Browser
     ↓
    Nginx
     ↓
    cache
     ↓
    HTML

    can avoid invoking PHP for every request.


    54. WordPress Without Cache

    A request may look like:

    Browser
     ↓
    Nginx
     ↓
    PHP-FPM
     ↓
    WordPress
     ↓
    MySQL
     ↓
    WordPress
     ↓
    PHP
     ↓
    Nginx
     ↓
    Browser

    This involves significant processing.


    55. WordPress With Page Cache

    With an effective page cache:

    Browser
     ↓
    Nginx
     ↓
    cached HTML
     ↓
    Browser

    The PHP/MySQL path can sometimes be avoided for cacheable requests.


    56. Why This Matters for Hosting

    Suppose you host:

    100 websites

    and each receives many requests.

    If every request reaches:

    PHP
    +
    MySQL

    resource consumption can become substantial.

    Caching can dramatically reduce backend work.


    57. Cookies

    HTTP can use:

    Cookies

    A server can send:

    Set-Cookie: session=...

    The browser stores the cookie according to its attributes and policies.

    Later requests can include:

    Cookie: session=...

    58. Why WordPress Uses Cookies

    WordPress uses cookies for functionality such as:

    login
    authentication
    preferences
    sessions

    59. Login Example

    Simplified:

    Browser
     ↓
    POST /wp-login.php
     ↓
    WordPress
     ↓
    authentication
     ↓
    Set-Cookie
     ↓
    Browser

    Then:

    Browser
     ↓
    Cookie
     ↓
    WordPress

    allows WordPress to recognize the authenticated session.


    60. HTTP Is Stateless

    HTTP itself is fundamentally stateless.

    That means each request can be processed independently.

    Cookies and application-level session mechanisms allow applications to maintain continuity between requests.


    61. Example

    Without session information:

    Request 1
    Who are you?
    
    Request 2
    Who are you?
    
    Request 3
    Who are you?

    With authentication cookies:

    Request
     ↓
    Cookie
     ↓
    User identified

    62. Security Attributes of Cookies

    Important cookie attributes include:

    Secure
    HttpOnly
    SameSite

    Secure

    Cookie should be sent over secure connections.

    HttpOnly

    Helps prevent client-side JavaScript from directly reading the cookie.

    SameSite

    Controls cross-site cookie sending behavior.


    63. HTTP Compression

    Web servers can compress responses.

    Common compression mechanisms include:

    gzip
    Brotli

    Example:

    HTML
     ↓
    compression
     ↓
    smaller transfer
     ↓
    browser
     ↓
    decompression

    64. Why Compression Helps

    Suppose:

    HTML = 500 KB

    Compression might reduce the transferred size significantly.

    Less data means:

    less bandwidth
    faster transfer

    depending on network conditions and content.


    65. HTTP/1.1

    Traditional HTTP/1.1 uses textual requests and responses.

    Example:

    GET / HTTP/1.1
    Host: example.com

    It is still widely supported.


    66. HTTP/2

    HTTP/2 improves how multiple requests can be transported over a connection.

    It supports concepts such as:

    multiplexing
    header compression
    binary framing

    67. HTTP/2 Multiplexing

    Instead of treating requests as completely independent serial transfers at the HTTP layer, HTTP/2 can multiplex multiple streams over one connection.

    Conceptually:

    TCP connection
    │
    ├── HTML stream
    ├── CSS stream
    ├── JS stream
    ├── image stream
    └── API stream

    This can improve efficiency.


    68. HTTP/3

    HTTP/3 uses:

    HTTP/3
     ↓
    QUIC
     ↓
    UDP

    rather than the traditional:

    HTTP/2
     ↓
    TLS
     ↓
    TCP

    HTTP/3 is an advanced topic, but it is useful to know that modern web hosting can involve it.


    69. Your Nginx Server

    Nginx can be configured to support modern HTTP versions depending on the build and configuration.

    You don’t need to enable every feature immediately.

    For your hosting platform, first make:

    HTTP/1.1 or HTTP/2
    +
    HTTPS
    +
    PHP-FPM
    +
    WordPress

    reliable.


    70. HTTP Request to WordPress

    Now let’s follow:

    https://learn.cresignsys.com/about/

    71. Step 1

    Browser performs DNS:

    learn.cresignsys.com
            ↓
    IP

    72. Step 2

    Browser establishes network connectivity:

    TCP
     ↓
    443

    73. Step 3

    TLS handshake:

    Browser
     ↕
    Nginx

    Certificate is validated according to the browser’s trust rules.


    74. Step 4

    Browser sends:

    GET /about/ HTTP/2
    Host: learn.cresignsys.com

    The exact wire representation differs with HTTP/2, but conceptually this is the request.


    75. Step 5

    Nginx receives it.

    Nginx examines:

    Host
    Path
    Method
    Headers

    76. Step 6

    Nginx determines:

    server_name

    matches:

    learn.cresignsys.com

    77. Step 7

    Nginx determines the requested resource.

    For a typical WordPress setup, a pretty URL such as:

    /about/

    may not correspond to a physical directory named:

    /about/

    78. WordPress Front Controller

    WordPress commonly uses:

    index.php

    as its front controller.

    Conceptually:

    /about/
       ↓
    Nginx rewrite
       ↓
    index.php
       ↓
    WordPress

    79. Typical Nginx Concept

    A WordPress configuration often contains logic conceptually similar to:

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

    Meaning:

    Does the file exist?
            │
         yes│no
            ▼
    serve file
            │
            └────→ index.php

    The exact configuration should be adapted to your PHP-FPM and site architecture.


    80. PHP-FPM

    If Nginx determines the request needs PHP:

    Nginx
     ↓
    PHP-FPM

    Nginx communicates with PHP-FPM through a configured FastCGI interface.

    Commonly this is:

    Unix socket

    or:

    TCP socket

    81. Unix Socket

    You may see something like:

    /run/php/php8.x-fpm.sock

    The exact PHP version and socket path depend on your installation.

    Nginx uses the configured socket to communicate with PHP-FPM.


    82. PHP-FPM Executes WordPress

    PHP-FPM receives:

    index.php

    and executes PHP.

    WordPress loads:

    core
    themes
    plugins
    configuration

    and eventually queries MySQL where required.


    83. MySQL

    WordPress might execute database queries such as:

    SELECT ...

    The database returns:

    posts
    pages
    users
    settings
    metadata

    84. WordPress Generates HTML

    PHP combines:

    WordPress core
    +
    theme
    +
    plugins
    +
    database data

    and produces an HTML response.


    85. Response Returns

    The flow reverses:

    MySQL
     ↓
    WordPress
     ↓
    PHP-FPM
     ↓
    Nginx
     ↓
    TLS
     ↓
    Internet
     ↓
    Browser

    86. Browser Receives HTML

    The browser parses:

    <html>
    <head>
    ...
    </head>
    <body>
    ...
    </body>
    </html>

    But the page usually contains references to additional resources.

    For example:

    CSS
    JavaScript
    images
    fonts

    87. Additional Requests

    The browser may then request:

    /style.css
    /script.js
    /logo.png
    /font.woff2

    So one page load can create many HTTP requests.

    Conceptually:

    HTML
     ├── CSS request
     ├── JS request
     ├── image request
     ├── font request
     └── API request

    88. Why Websites Can Be Slow

    A page may require:

    1 HTML request
    +
    10 CSS/JS requests
    +
    50 images
    +
    5 fonts
    +
    API calls

    Now the server handles many operations.

    This is why:

    caching
    compression
    CDN
    image optimization
    HTTP/2

    matter.


    89. Inspect Your Website

    Run:

    curl -I https://learn.cresignsys.com

    Then:

    curl -v https://learn.cresignsys.com

    You are now capable of understanding much more of the output.


    90. Check the Status

    For example:

    HTTP/2 200

    means the HTTP exchange succeeded.

    If you see:

    HTTP/2 301

    you know a redirect occurred.

    If:

    HTTP/2 502

    look toward the Nginx → PHP-FPM/upstream layer.


    91. Check Headers

    Look for:

    server:
    content-type:
    cache-control:
    location:
    set-cookie:

    These give clues about how your site is operating.


    92. Browser Developer Tools

    Open your browser’s Developer Tools:

    F12

    Then:

    Network

    Reload the website.

    You will see requests such as:

    /
    about/
    style.css
    script.js
    logo.png

    93. Network Tab

    For each request you can inspect:

    Status
    Method
    Domain
    Path
    Size
    Time
    Response headers
    Request headers

    This is one of the most useful tools for web hosting troubleshooting.


    94. Example

    Suppose:

    /about/
    200

    but:

    /style.css
    404

    The WordPress page itself works, but the CSS path is wrong.


    95. Another Example

    Suppose:

    /about/
    200

    but:

    /wp-content/uploads/image.jpg
    403

    Now investigate:

    file permissions
    directory permissions
    Nginx rules
    security rules

    96. Another Example

    Suppose:

    /about/
    502

    Then investigate:

    Nginx
     ↓
    PHP-FPM

    Check:

    sudo systemctl status php*-fpm

    and inspect relevant logs.


    97. Logs

    Your hosting platform must eventually teach you:

    access logs
    error logs
    PHP logs
    MySQL logs
    system logs

    For Nginx, common locations include:

    /var/log/nginx/

    The exact log configuration can differ.


    98. Access Log

    An access log records requests.

    Conceptually:

    client IP
    timestamp
    request
    status
    bytes
    user agent

    Example:

    GET /about/ HTTP/2
    200

    This answers:

    Did the request actually reach Nginx?


    99. Error Log

    The error log can show:

    permission problems
    upstream failures
    configuration errors
    connection errors

    This answers:

    What went wrong while processing the request?


    100. The Hosting Troubleshooting Map

    At this point you can diagnose:

    Domain doesn't resolve
     ↓
    DNS
    
    Domain resolves but connection times out
     ↓
    network/security
    
    Connection refused
     ↓
    listener/firewall/service
    
    Nginx returns 404
     ↓
    routing/document root/rewrite
    
    Nginx returns 403
     ↓
    permissions/access rules
    
    Nginx returns 502
     ↓
    PHP-FPM/upstream
    
    WordPress returns 500
     ↓
    PHP/plugin/theme/application
    
    Database errors
     ↓
    MySQL/WordPress database layer

    101. Lesson 058 — Core Principle

    The key idea is:

    HTTP is the conversation between the browser and your web server.

    The complete request path is now:

    Domain
     ↓
    DNS
     ↓
    IP
     ↓
    Routing
     ↓
    TCP
     ↓
    TLS
     ↓
    HTTP Request
     ↓
    Nginx
     ↓
    PHP-FPM
     ↓
    WordPress
     ↓
    MySQL
     ↓
    HTTP Response
     ↓
    Browser

    You are now moving from server administration into actual web-server engineering.


    Next Lesson — 059

    Nginx Deep Dive — How One Server Hosts Hundreds of Websites

    We will build the next layer:

    Nginx
     ↓
    Master process
     ↓
    Worker processes
     ↓
    server blocks
     ↓
    server_name
     ↓
    listen
     ↓
    root
     ↓
    location
     ↓
    try_files
     ↓
    FastCGI
     ↓
    PHP-FPM

    Then we will connect it directly to your structure:

    /storage/websites/
    ├── domain1.com/
    ├── domain2.com/
    ├── domain3.com/
    └── ...

    and design the architecture needed to turn your current server into a multi-domain hosting platform.

  • CresignSys Learn — Lesson 057

    DNS Deep Dive — From Domain Name to Your VPS

    We now go one layer deeper.

    You already understand:

    Browser
     ↓
    Domain
     ↓
    DNS
     ↓
    IP
     ↓
    Network
     ↓
    Port 443
     ↓
    Nginx
     ↓
    WordPress

    The question now is:

    How does DNS actually turn learn.cresignsys.com into an IP address?


    1. Domain Name Is Not the Server

    When you type:

    learn.cresignsys.com

    your computer does not initially know where that server is.

    It needs DNS.

    Think:

    learn.cresignsys.com
            ↓
          DNS
            ↓
       IP address
            ↓
          server

    2. DNS Means Domain Name System

    DNS is essentially a distributed naming system.

    It maps names to information such as:

    domain → IPv4 address
    domain → IPv6 address
    domain → mail server
    domain → another domain

    and more.


    3. Why DNS Exists

    Humans prefer:

    learn.cresignsys.com

    Computers ultimately need network addresses such as:

    203.0.113.25

    So DNS provides the translation mechanism.


    4. Domain Hierarchy

    Look at:

    learn.cresignsys.com

    Break it apart:

    learn
       .
    cresignsys
       .
    com

    There is also an invisible final dot:

    learn.cresignsys.com.

    That final dot represents the DNS root.


    5. DNS Root

    At the top is:

    .

    called the:

    Root

    Below the root are:

    com
    org
    net
    in
    ...

    These are:

    TLDs

    Top-Level Domains.


    6. TLD

    For:

    cresignsys.com

    the TLD is:

    com

    For:

    example.in

    the TLD is:

    in

    7. Domain

    In:

    learn.cresignsys.com

    the registered domain is:

    cresignsys.com

    and:

    learn

    is a subdomain label.


    8. Subdomain

    Therefore:

    learn.cresignsys.com

    means approximately:

    learn
     ↓
    cresignsys.com
     ↓
    com
     ↓
    root

    The DNS hierarchy works from right to left.


    9. Example

    Consider:

    shop.cresignsys.com

    Hierarchy:

    .
    └── com
        └── cresignsys
            └── shop

    10. Root Servers

    The DNS root system points resolvers toward the appropriate TLD name servers.

    Conceptually:

    Resolver
       ↓
    Root
       ↓
    .com servers
       ↓
    cresignsys.com authoritative servers
       ↓
    shop.cresignsys.com

    11. TLD Servers

    The .com infrastructure knows which authoritative nameservers are responsible for:

    cresignsys.com

    It doesn’t necessarily contain the final IP address for every subdomain.

    It directs the resolver to the authoritative DNS service for the domain.


    12. Authoritative Nameserver

    The authoritative DNS server is the source of truth for the DNS zone.

    For example:

    cresignsys.com
          ↓
    authoritative nameserver
          ↓
    DNS records

    13. DNS Zone

    A DNS zone contains records such as:

    A
    AAAA
    CNAME
    MX
    TXT
    NS
    CAA

    and others.


    14. A Record

    The most important record for basic web hosting:

    A

    It maps a hostname to an IPv4 address.

    Conceptually:

    learn.cresignsys.com
            ↓
    A
            ↓
    203.0.113.25

    15. Example

    A DNS zone might contain:

    learn     A     203.0.113.25

    This means:

    learn.cresignsys.com
            ↓
    203.0.113.25

    assuming learn is within the cresignsys.com zone.


    16. AAAA Record

    For IPv6:

    AAAA

    Example:

    learn.cresignsys.com
            ↓
    AAAA
            ↓
    2001:db8::25

    17. A vs AAAA

    Remember:

    A
    =
    IPv4
    AAAA
    =
    IPv6

    18. Why IPv6 Can Cause Confusion

    Suppose you configure:

    A
    ↓
    correct IPv4

    but also have:

    AAAA
    ↓
    incorrect IPv6

    Some clients may attempt IPv6 connectivity and encounter problems.

    Then you might see:

    Website works on one network
    Website fails on another

    even though the IPv4 configuration is correct.


    19. CNAME

    Another important record:

    CNAME

    It maps one hostname to another hostname.

    Example:

    www.cresignsys.com
            ↓
    CNAME
            ↓
    cresignsys.com

    Conceptually:

    www
     ↓
    cresignsys.com
     ↓
    A/AAAA
     ↓
    IP

    20. CNAME Is Not an IP Address

    An A record contains:

    hostname → IPv4

    A CNAME contains:

    hostname → hostname

    This distinction matters.


    21. Example

    You might configure:

    shop.cresignsys.com
    A
    203.0.113.25

    and:

    www.shop.cresignsys.com
    CNAME
    shop.cresignsys.com

    Then:

    www.shop.cresignsys.com
     ↓
    shop.cresignsys.com
     ↓
    203.0.113.25

    22. MX Record

    MX means:

    Mail Exchange

    It tells mail systems where email for a domain should be delivered.

    Example concept:

    cresignsys.com
     ↓
    MX
     ↓
    mail.example.com

    This is for email, not normal website traffic.


    23. TXT Record

    TXT records store text-based DNS information.

    They are commonly used for:

    domain verification
    SPF
    DKIM-related records
    DMARC-related records
    other verification/configuration

    24. NS Record

    NS means:

    Name Server

    It identifies authoritative nameservers for a DNS zone.

    Conceptually:

    cresignsys.com
     ↓
    NS
     ↓
    ns1.example-dns.com
    ns2.example-dns.com

    25. CAA Record

    CAA records can specify which certificate authorities are authorized to issue certificates for a domain.

    This is useful for controlling certificate issuance.


    26. TTL

    TTL means:

    Time To Live

    It tells DNS resolvers how long a record may be cached.

    Example:

    A record
    TTL = 3600

    means roughly:

    3600 seconds
    =
    1 hour

    for caching purposes.


    27. Why DNS Changes Don’t Always Appear Immediately

    Suppose you change:

    A record
    old IP
     ↓
    new IP

    Some DNS resolvers may still have the old value cached until its TTL expires.

    Therefore:

    Your computer
     ↓
    old cached DNS

    while:

    another user
     ↓
    new DNS

    can temporarily happen.


    28. DNS Is Distributed

    There isn’t one single DNS server containing everything.

    Instead:

    Browser
     ↓
    Recursive resolver
     ↓
    DNS hierarchy
     ↓
    Authoritative server

    and cached answers are used where appropriate.


    29. Recursive Resolver

    Your computer usually asks a:

    Recursive DNS Resolver

    For example, a resolver operated by:

    ISP
    public DNS provider
    enterprise network
    local network

    The resolver does the work of finding the answer.


    30. Typical Query

    Your computer asks:

    What is the IP of learn.cresignsys.com?

    The recursive resolver checks its cache.

    If it doesn’t have a valid cached answer, it resolves the name.


    31. Simplified Resolution

    Conceptually:

    Client
     ↓
    Recursive Resolver
     ↓
    Root
     ↓
    .com
     ↓
    cresignsys.com authoritative DNS
     ↓
    A record
     ↓
    IP

    The resolver then returns the answer to the client.


    32. Caching

    Suppose:

    learn.cresignsys.com
    A
    203.0.113.25
    TTL 3600

    A recursive resolver can cache that result.

    The next user asking the same resolver may receive the cached answer without the resolver querying the authoritative server again.


    33. Why Caching Is Useful

    Without caching:

    every request
     ↓
    DNS hierarchy

    With caching:

    request
     ↓
    local resolver cache
     ↓
    answer

    This greatly reduces DNS traffic and improves speed.


    34. Local DNS Cache

    Your own computer, browser, operating system, router, or network resolver may also cache DNS responses.

    So sometimes:

    DNS changed

    but:

    your computer

    still has an older answer cached.


    35. dig

    One of the best DNS troubleshooting tools is:

    dig

    Example:

    dig learn.cresignsys.com

    36. Short Answer

    Use:

    dig +short learn.cresignsys.com

    Example:

    203.0.113.25

    This gives you the returned IP address directly.


    37. Query A Specifically

    dig A learn.cresignsys.com

    38. Query AAAA

    dig AAAA learn.cresignsys.com

    This checks IPv6.


    39. Query CNAME

    dig CNAME www.cresignsys.com

    40. Query MX

    dig MX cresignsys.com

    41. Query NS

    dig NS cresignsys.com

    42. Query TXT

    dig TXT cresignsys.com

    43. Different DNS Resolvers

    You can ask a specific DNS resolver.

    For example:

    dig @8.8.8.8 learn.cresignsys.com

    This asks Google’s public resolver.

    You can also use another resolver such as:

    dig @1.1.1.1 learn.cresignsys.com

    The returned results can sometimes differ temporarily because of caching or propagation.


    44. Authoritative Server Directly

    You can investigate authoritative DNS using:

    dig NS cresignsys.com

    Then query an authoritative server directly:

    dig @AUTHORITATIVE_SERVER learn.cresignsys.com

    This helps distinguish:

    authoritative DNS

    from:

    cached recursive DNS

    45. +trace

    A very useful advanced command:

    dig +trace learn.cresignsys.com

    This walks through DNS delegation.

    Conceptually:

    root
     ↓
    .com
     ↓
    cresignsys.com
     ↓
    learn.cresignsys.com

    This is excellent for understanding DNS deeply.


    46. DNS Delegation

    Suppose you register:

    cresignsys.com

    with a registrar.

    The registrar records which nameservers are authoritative for your domain.

    For example:

    cresignsys.com
     ↓
    NS
     ↓
    DNS provider

    47. Registrar vs DNS Provider

    These are different concepts.

    Registrar

    Manages your domain registration.

    DNS provider

    Hosts/manages the DNS zone.

    They can be:

    same company

    or:

    different companies

    48. Example

    You might:

    buy domain
     ↓
    registrar

    but use:

    DNS
     ↓
    Cloudflare

    or another DNS provider.

    The registrar points the domain delegation to the DNS provider’s nameservers.


    49. Nameserver Change

    Suppose your domain currently uses:

    DNS Provider A

    and you change nameservers to:

    DNS Provider B

    Then the authoritative source changes.

    The DNS records you configured at Provider A may no longer control the domain.

    This is a common source of confusion.


    50. Important Hosting Principle

    Before editing DNS, determine:

    Who is authoritative for the domain?

    Run:

    dig NS cresignsys.com

    51. Domain vs Subdomain

    If you have:

    cresignsys.com

    you can create:

    learn.cresignsys.com
    shop.cresignsys.com
    manage.cresignsys.com

    These are different DNS names.


    52. Wildcard DNS

    You can also use a wildcard record:

    *.cresignsys.com

    For example:

    *.cresignsys.com
    A
    203.0.113.25

    This can cause many otherwise-unconfigured subdomains to resolve to the same IP, subject to DNS rules and any more-specific records.


    53. Why Wildcard DNS Can Be Useful for Hosting

    Imagine your hosting platform creates:

    site1.cresignsys.com
    site2.cresignsys.com
    site3.cresignsys.com

    A wildcard can reduce the need to create an individual DNS A record for every subdomain under a controlled zone.

    However, for customer-owned domains such as:

    customer.com

    the customer still needs appropriate DNS configuration at their domain.


    54. DNS Doesn’t Configure Nginx

    This is extremely important.

    Suppose DNS says:

    shop.cresignsys.com
     ↓
    203.0.113.25

    That only means:

    Send traffic toward this IP.

    It does not tell Nginx which website to serve.


    55. Nginx Has Its Own Configuration

    For example:

    server {
        server_name shop.cresignsys.com;
    
        root /storage/websites/shop.cresignsys.com/public;
    }

    Now the two systems connect:

    DNS
     ↓
    203.0.113.25
    
    Nginx
     ↓
    shop.cresignsys.com
     ↓
    /storage/websites/shop.cresignsys.com/public

    56. DNS + Nginx

    Both must be correct.

    DNS

    shop.cresignsys.com
            ↓
    correct IP

    Nginx

    shop.cresignsys.com
            ↓
    correct document root

    If either is wrong, the website can fail.


    57. Same IP, Multiple Websites

    This is one of the most important hosting concepts.

    Suppose:

    siteA.com
    siteB.com
    siteC.com

    all point to:

    203.0.113.25

    How does Nginx know which website to serve?

    The HTTP request contains the hostname.


    58. HTTP Host Header

    A request may contain:

    GET /
    Host: siteB.com

    Nginx sees:

    Host = siteB.com

    and selects the corresponding server configuration.


    59. HTTPS SNI

    HTTPS adds another important mechanism:

    SNI

    Server Name Indication.

    During TLS setup, the client indicates the hostname it wants.

    This allows one IP address to serve certificates for many domains.

    Conceptually:

    203.0.113.25:443
            │
            ├── siteA.com
            ├── siteB.com
            └── siteC.com

    60. One IP, Many Domains

    This is the foundation of:

    Virtual Hosting

    Example:

    siteA.com
         ↓
    203.0.113.25
    
    siteB.com
         ↓
    203.0.113.25
    
    siteC.com
         ↓
    203.0.113.25

    Nginx separates them using hostname information.


    61. This Is Exactly What Your Hosting Platform Does

    Your CresignSys Hosting Platform can create:

    Domain
     ↓
    DNS configuration
     ↓
    Nginx server block
     ↓
    Document root
     ↓
    PHP-FPM pool
     ↓
    Database

    That is the basic architecture of automated hosting.


    62. www Problem

    Suppose:

    cresignsys.com

    works.

    But:

    www.cresignsys.com

    doesn’t.

    Possible reason:

    root domain DNS configured
    www DNS missing

    For example:

    cresignsys.com
    A
    203.0.113.25

    but:

    www.cresignsys.com

    has no A/CNAME record.


    63. Another www Problem

    DNS may be correct:

    www
     ↓
    203.0.113.25

    but Nginx may only have:

    server_name cresignsys.com;

    instead of:

    server_name cresignsys.com www.cresignsys.com;

    Then Nginx configuration can still cause unexpected behavior.


    64. DNS and SSL Are Different

    Suppose:

    DNS ✓

    but:

    SSL certificate ✗

    The domain can resolve correctly while HTTPS still produces certificate errors.


    65. DNS and WordPress Are Different

    Suppose:

    DNS ✓
    Nginx ✓
    SSL ✓

    but:

    WordPress

    has:

    home = wrong URL
    siteurl = wrong URL

    The site can still behave incorrectly.


    66. DNS Is Only One Layer

    Memorize:

    DNS
    ≠
    Website

    DNS only answers:

    Where should traffic go?

    Nginx answers:

    Which website should this request receive?

    PHP answers:

    How should the dynamic request be processed?

    WordPress answers:

    What content should be generated?

    MySQL answers:

    What stored data is needed?


    67. DNS Troubleshooting Workflow

    When a new domain doesn’t work:

    Step 1

    dig +short domain.com

    Check the IP.

    Step 2

    dig A domain.com

    Check the A record.

    Step 3

    dig AAAA domain.com

    Check for unexpected IPv6.

    Step 4

    dig NS domain.com

    Find authoritative nameservers.

    Step 5

    Check Nginx:

    sudo nginx -t

    Step 6

    Check listener:

    sudo ss -ltnp | grep ':443'

    68. nginx -t

    This is extremely important.

    Run:

    sudo nginx -t

    It checks the Nginx configuration syntax.

    You want something like:

    syntax is ok
    test is successful

    before reloading Nginx.


    69. Reload Nginx

    After a valid configuration change:

    sudo systemctl reload nginx

    Reload is generally preferable to a full restart for configuration changes because it allows existing connections to be handled more gracefully.


    70. DNS + Nginx + SSL

    A new website generally needs:

    1. DNS
       ↓
    2. Nginx
       ↓
    3. Port 80/443
       ↓
    4. SSL certificate
       ↓
    5. PHP-FPM
       ↓
    6. WordPress

    If any layer is missing, the site may not work.


    71. Why Let’s Encrypt Needs DNS/HTTP Reachability

    When obtaining a certificate, the certificate authority must verify control of the domain using an ACME challenge.

    Common challenge methods include:

    HTTP-01
    DNS-01
    TLS-ALPN-01

    The exact method depends on your setup.


    72. HTTP-01

    For HTTP-01, a challenge is served through HTTP.

    Conceptually:

    Certificate Authority
            ↓
    http://domain/.well-known/acme-challenge/...
            ↓
    your server

    Therefore port 80 and the domain’s DNS/reachability can matter.


    73. DNS-01

    DNS-01 proves control through a special TXT record.

    Conceptually:

    Certificate Authority
            ↓
    DNS
            ↓
    TXT challenge

    This can be useful when HTTP exposure isn’t suitable.


    74. Why DNS Knowledge Helps SSL

    If:

    DNS

    is wrong, certificate issuance may fail.

    Therefore:

     ↓
    SSL

    are connected.


    75. DNS Propagation

    The phrase:

    DNS propagation

    is often used loosely.

    Technically, changes become visible through a combination of:

    authoritative DNS updates
    +
    resolver caching
    +
    TTL expiration

    It’s not simply a single global switch that takes exactly a certain number of hours.


    76. Check Multiple Resolvers

    You can compare:

    dig @8.8.8.8 +short learn.cresignsys.com

    and:

    dig @1.1.1.1 +short learn.cresignsys.com

    If they differ, caching or delegation issues may be involved.


    77. Check Authoritative DNS

    First:

    dig NS cresignsys.com

    Then:

    dig @authoritative-server +short learn.cresignsys.com

    Now you can determine whether the authoritative server itself has the expected record.


    78. The Most Important DNS Commands

    Memorize:

    dig +short domain.com
    dig A domain.com
    dig AAAA domain.com
    dig CNAME www.domain.com
    dig NS domain.com
    dig MX domain.com
    dig +trace domain.com

    79. Your Domain Hosting Mental Model

    For:

    learn.cresignsys.com

    think:

                        DOMAIN
                           │
                           ▼
                          DNS
                           │
                      A / AAAA
                           │
                           ▼
                      PUBLIC IP
                           │
                           ▼
                    OCI NETWORK
                           │
                           ▼
                         VNIC
                           │
                           ▼
                        UBUNTU
                           │
                           ▼
                      TCP :443
                           │
                           ▼
                        NGINX
                           │
                     server_name
                           │
                           ▼
            /storage/websites/learn.../public
                           │
                           ▼
                       PHP-FPM
                           │
                           ▼
                      WORDPRESS
                           │
                           ▼
                        MYSQL

    80. Lesson 057 — Core Principle

    The most important idea:

    DNS does not deliver the website. DNS tells the client where to find the network endpoint for the hostname.

    Then the rest of the stack takes over:

    DNS
     ↓
    IP
     ↓
    Routing
     ↓
    Port
     ↓
    Nginx
     ↓
    TLS
     ↓
    PHP
     ↓
    WordPress
     ↓
    MySQL

    Once you understand this, a domain name stops being mysterious. It becomes the first lookup in a long, measurable chain.


    Next Lesson — 058

    HTTP Deep Dive — What Actually Happens After DNS

    We will now go deeper into the protocol that carries your WordPress website:

    HTTP
     ↓
    Request
     ↓
    Response
     ↓
    Headers
     ↓
    Status codes
     ↓
    Methods
     ↓
    GET
     ↓
    POST
     ↓
    Cookies
     ↓
    Sessions
     ↓
    Cache-Control
     ↓
    Compression
     ↓
    HTTP/1.1
     ↓
    HTTP/2
     ↓
    HTTP/3

    Then we will follow an actual WordPress request:

    GET /about/
            ↓
    Nginx
            ↓
    PHP-FPM
            ↓
    WordPress
            ↓
    MySQL
            ↓
    HTML
            ↓
    Browser

    and explain exactly what each layer does.

  • CresignSys Learn — Lesson 056

    IP Addressing, Subnets, Gateway, NAT & Routing

    This lesson goes one level deeper into networking.

    We already know:

    Browser
     ↓
    DNS
     ↓
    Public IP
     ↓
    Internet
     ↓
    VPS
     ↓
    Port 443
     ↓
    Nginx

    Now we need to understand:

    How does the packet know where to go?


    1. IP Address = Address

    Think of an IP address like an address used for network delivery.

    Example:

    192.168.1.20

    But an IP address has two conceptual parts:

    Network portion
    +
    Host portion

    2. Example

    Consider:

    192.168.1.20/24

    The /24 tells us that the first 24 bits are the network prefix.

    Conceptually:

    192.168.1 | 20
     network  | host

    3. Why Do We Need a Network Portion?

    Suppose a computer wants to communicate with:

    192.168.1.30

    and its own address is:

    192.168.1.20/24

    They belong to the same /24 network.

    The computer can communicate with the destination through the local network rather than sending the traffic to its default gateway.


    4. Different Network

    Now suppose the destination is:

    10.0.0.20

    The source:

    192.168.1.20/24

    and destination:

    10.0.0.20

    are on different networks.

    The computer needs a router.

    Usually that means:

    Computer
     ↓
    Default Gateway
     ↓
    Router
     ↓
    Destination network

    5. Subnet

    A subnet is a defined IP network.

    Example:

    192.168.1.0/24

    This represents the network.

    Hosts can use addresses within the usable host range, depending on the addressing model.


    6. /24 in Binary

    IPv4 has:

    32 bits

    A /24 means:

    11111111.11111111.11111111.00000000

    The first:

    24 bits

    are the network prefix.

    The remaining:

    8 bits

    are host bits.


    7. Why 256 Addresses?

    With 8 host bits:

    2⁸ = 256

    possible bit combinations exist.

    So:

    192.168.1.0/24

    contains:

    256 IPv4 addresses

    Some addresses have special roles in traditional IPv4 subnetting, so the number of ordinary assignable host addresses is lower.


    8. Network Address

    For:

    192.168.1.0/24

    the network address is:

    192.168.1.0

    It identifies the subnet itself.


    9. Broadcast Address

    Traditionally, the /24 broadcast address is:

    192.168.1.255

    It is used for IPv4 broadcast within that subnet.

    Cloud networking environments can impose their own rules around which addresses are usable.


    10. Host Addresses

    The traditional usable host range for:

    192.168.1.0/24

    is:

    192.168.1.1
    –
    192.168.1.254

    Again:

    network address

    and:

    broadcast address

    are not ordinary host assignments.


    11. CIDR

    CIDR means:

    Classless Inter-Domain Routing

    Instead of only using old fixed classes such as:

    Class A
    Class B
    Class C

    CIDR allows flexible prefix lengths.

    Examples:

    /8
    /16
    /24
    /25
    /26
    /27

    and many others.


    12. Smaller Prefix = Larger Network

    Compare:

    10.0.0.0/24

    with:

    10.0.0.0/16

    A /16 has more host bits:

    32 - 16 = 16 host bits

    Therefore:

    2^16 = 65,536

    addresses.


    13. /24

    32 - 24 = 8

    host bits.

    Therefore:

    2^8 = 256

    addresses.


    14. /25

    32 - 25 = 7

    host bits.

    Therefore:

    2^7 = 128

    addresses.


    15. /26

    32 - 26 = 6

    host bits.

    Therefore:

    2^6 = 64

    addresses.


    16. Subnetting

    Suppose you have:

    10.0.0.0/24

    You can divide it into smaller networks.

    For example:

    10.0.0.0/26
    10.0.0.64/26
    10.0.0.128/26
    10.0.0.192/26

    Each /26 contains:

    64 addresses

    17. Why Subnet?

    Cloud networks use subnets to organize systems.

    For example:

    VCN
    │
    ├── Public subnet
    │     └── Web server
    │
    └── Private subnet
          └── Database

    This creates logical network separation.


    18. Your Oracle Cloud Example

    Conceptually:

    Oracle Cloud
          │
          ▼
    VCN
          │
          ▼
    Subnet
          │
          ▼
    VNIC
          │
          ▼
    Ubuntu VM

    The subnet determines the VM’s private IP network.


    19. Private IP

    Your VM may have a private IP such as:

    10.0.0.10

    This address is used inside the VCN.

    It is not normally directly reachable from the public Internet.


    20. Public IP

    Your VM can also have a public IP.

    For example:

    203.0.113.25

    The public Internet uses that address to reach your Internet-facing endpoint when the cloud networking configuration permits it.


    21. Public-to-Private Mapping

    Conceptually:

    Internet
         │
         ▼
    Public IP
         │
         ▼
    Cloud networking
         │
         ▼
    Private IP
         │
         ▼
    VNIC
         │
         ▼
    VM

    The exact implementation is controlled by the cloud platform.


    22. NAT

    NAT means:

    Network Address Translation

    It changes network addressing information as traffic crosses a boundary.

    A common concept:

    Private IP
         ↓
    NAT
         ↓
    Public IP

    23. Why Private IPs Exist

    Private address ranges are designed for internal networks.

    Common IPv4 private ranges include:

    10.0.0.0/8
    172.16.0.0/12
    192.168.0.0/16

    These are not globally routable Internet addresses.


    24. Home Network Example

    Your home network may look like:

    Laptop
    192.168.1.20
         │
         ▼
    Wi-Fi Router
    192.168.1.1
         │
         ▼
    Public Internet

    The router performs NAT for outbound traffic in the common home-network setup.


    25. Hosting Example

    Your cloud VM can have:

    Private IP
    10.x.x.x

    and a public Internet-facing address.

    The cloud networking infrastructure handles the relationship between the public endpoint and the VNIC/private address according to its configuration.


    26. Routing

    Now we reach:

    Routing

    Routing answers:

    Where should this packet go next?

    Linux has a routing table.

    Run:

    ip route

    27. Example Routing Table

    You might see:

    10.0.0.0/24 dev ens3
    default via 10.0.0.1 dev ens3

    Interpretation:

    10.0.0.0/24
     ↓
    directly reachable through ens3

    and:

    everything else
     ↓
    10.0.0.1

    28. Default Gateway

    The:

    10.0.0.1

    in this example is the:

    Default Gateway

    Traffic for destinations that don’t match a more specific route goes there.


    29. Routing Decision

    Suppose the server wants to reach:

    10.0.0.50

    and has:

    10.0.0.0/24

    The route matches.

    Therefore:

    server
     ↓
    ens3
     ↓
    local network

    30. Another Destination

    Suppose the server wants:

    8.8.8.8

    That doesn’t belong to:

    10.0.0.0/24

    So:

    server
     ↓
    default route
     ↓
    gateway
     ↓
    Internet

    31. Longest Prefix Match

    When multiple routes match, the router generally chooses the:

    Most specific route

    Example:

    10.0.0.0/8

    and:

    10.1.0.0/16

    Destination:

    10.1.5.20

    The /16 is more specific than /8.

    Therefore it wins.


    32. Why This Matters

    Routing can become complicated when your server has:

    multiple interfaces
    multiple subnets
    VPN
    private networks
    public networks

    But the basic principle remains:

    destination
     ↓
    routing table
     ↓
    best matching route
     ↓
    next hop/interface

    33. ARP

    Now we go one level deeper.

    On an IPv4 Ethernet-style network, a machine needs to discover the hardware-layer address associated with a local IP.

    That mechanism is:

    ARP

    Address Resolution Protocol.


    34. IP vs MAC

    An IP address is a network-layer address.

    A MAC address identifies a network interface at the link layer.

    Example:

    IP:
    192.168.1.20

    and:

    MAC:
    aa:bb:cc:dd:ee:ff

    35. ARP Question

    Suppose:

    Computer A
    192.168.1.20

    needs to send to:

    192.168.1.30

    It may need to discover:

    Which MAC address owns 192.168.1.30?

    ARP performs this mapping.


    36. ARP Cache

    Linux keeps recently learned mappings.

    Check:

    ip neigh

    You may see:

    192.168.1.1 dev ens3 lladdr aa:bb:cc:dd:ee:ff REACHABLE

    37. Important Cloud Difference

    In cloud networks, you should not assume everything works exactly like a physical Ethernet LAN.

    The cloud provider virtualizes and controls the underlying networking.

    So:

    ARP concepts

    remain useful for understanding networking, but the cloud platform may implement virtual networking behavior differently from a traditional physical LAN.


    38. Packet Journey to Your VPS

    Let’s imagine a user opens:

    https://learn.cresignsys.com

    39. Step 1 — DNS

    Browser needs the IP address.

    learn.cresignsys.com
            ↓
    DNS
            ↓
    Public IP

    40. Step 2 — TCP

    Browser connects to:

    Public-IP:443

    using TCP.


    41. Step 3 — Internet Routing

    The packet travels through multiple networks:

    User
     ↓
    ISP
     ↓
    Internet routers
     ↓
    Oracle Cloud

    You don’t normally control the intermediate Internet routers.


    42. Step 4 — OCI Network

    Inside OCI:

    Internet
     ↓
    Internet Gateway / appropriate path
     ↓
    VCN
     ↓
    Subnet
     ↓
    VNIC

    The exact route depends on your OCI configuration.


    43. Step 5 — Security

    Security rules determine whether the connection is permitted.

    Conceptually:

    TCP
    443
     ↓
    OCI security rules
     ↓
    ALLOW?

    If not:

    connection blocked

    44. Step 6 — Ubuntu

    If the packet reaches the VM:

    VNIC
     ↓
    Linux network interface

    Linux then processes the packet.


    45. Step 7 — TCP Port 443

    Linux checks whether a process is listening on:

    TCP 443

    If Nginx is listening:

    TCP
     ↓
    Nginx

    46. Step 8 — TLS

    Nginx performs the TLS handshake.

    It presents the appropriate certificate.

    Then:

    encrypted HTTPS connection

    is established.


    47. Step 9 — HTTP

    The browser sends an HTTP request such as:

    GET /
    Host: learn.cresignsys.com

    Nginx uses:

    Host

    to select the appropriate virtual server configuration.


    48. Step 10 — Website

    Nginx maps the request to:

    /storage/websites/learn.cresignsys.com/public

    Then:

    static file

    may be served directly.

    Or:

    PHP request
     ↓
    PHP-FPM
     ↓
    WordPress

    49. Step 11 — Database

    WordPress may request:

    MySQL

    The database responds.

    Then:

    PHP
     ↓
    Nginx
     ↓
    TLS
     ↓
    Browser

    50. The Full Journey

    Browser
      │
      ▼
    DNS
      │
      ▼
    Public IP
      │
      ▼
    Internet routers
      │
      ▼
    OCI Internet connectivity
      │
      ▼
    VCN
      │
      ▼
    Subnet
      │
      ▼
    VNIC
      │
      ▼
    Linux interface
      │
      ▼
    TCP 443
      │
      ▼
    Nginx
      │
      ▼
    TLS
      │
      ▼
    HTTP
      │
      ▼
    PHP-FPM
      │
      ▼
    WordPress
      │
      ▼
    MySQL

    51. How to Troubleshoot Each Layer

    This is where your learning becomes practical.

    DNS

    dig +short learn.cresignsys.com

    Interface

    ip addr

    Route

    ip route

    Port

    sudo ss -ltnp | grep ':443'

    Nginx

    sudo systemctl status nginx

    Firewall

    sudo ufw status

    HTTP

    curl -I https://learn.cresignsys.com

    52. ip route get

    One especially useful command is:

    ip route get 8.8.8.8

    Linux tells you which route it would use to reach that destination.

    For example:

    8.8.8.8 via 10.0.0.1 dev ens3

    Conceptually:

    8.8.8.8
     ↓
    gateway 10.0.0.1
     ↓
    interface ens3

    53. ip neigh

    You can inspect neighbor information:

    ip neigh

    This is useful when investigating local network connectivity.


    54. ss

    Use:

    sudo ss -lntup

    You can inspect:

    TCP listeners
    UDP listeners
    ports
    processes

    55. TCP vs UDP

    You should now distinguish:

    TCP

    connection-oriented
    reliable
    ordered

    UDP

    connectionless
    no built-in delivery guarantee
    low protocol overhead

    56. Why Websites Use TCP

    Traditional HTTP/1.1 and HTTP/2 over TLS commonly use:

    TCP

    HTTP/3 instead uses:

    QUIC
     ↓
    UDP

    This is a more advanced topic.

    For your current Nginx/WordPress stack, TCP is the primary concept to understand first.


    57. Port 443 Doesn’t Mean HTTPS Automatically

    This is important.

    A port is just a number.

    You can configure:

    some application
     ↓
    TCP 443

    But that doesn’t automatically make it HTTPS.

    HTTPS requires:

    TLS
    +
    HTTP

    58. Port 80 Doesn’t Force HTTP Either

    Likewise:

    port 80

    is conventional for HTTP, but software can listen there using other protocols.

    The port number is a convention.


    59. IP + Port

    Think of:

    IP

    as identifying the machine/network endpoint.

    And:

    Port

    as identifying a service endpoint on that host.

    Together:

    203.0.113.25:443

    identify a TCP endpoint.


    60. Socket Connection

    A TCP connection is identified by endpoints.

    Conceptually:

    Client IP:client-port
            ↕
    Server IP:443

    For example:

    192.168.1.20:51832
            ↕
    203.0.113.25:443

    The client-side port is usually dynamically selected.


    61. Ephemeral Ports

    Client applications usually use temporary:

    Ephemeral ports

    For example:

    51832

    Then:

    client
    192.168.1.20:51832

    connects to:

    server
    203.0.113.25:443

    62. Why the Server Can Handle Many Users

    The server isn’t limited to one connection on port 443.

    A single listening port can have many simultaneous TCP connections.

    Conceptually:

                  Nginx :443
                      │
           ┌──────────┼──────────┐
           ▼          ▼          ▼
     Client A      Client B    Client C
     :50001        :50002      :50003

    Each connection has a distinct client endpoint.


    63. This Connects to RAM

    Now combine networking with your previous lesson.

    More simultaneous requests can mean:

    more TCP connections
     ↓
    more Nginx work
     ↓
    more PHP requests
     ↓
    more PHP workers
     ↓
    more RAM

    Therefore:

    NETWORK
     ↓
    APPLICATION
     ↓
    CPU/RAM

    are connected.


    64. Traffic → PHP → MySQL

    A busy website can generate:

    1000 requests
          ↓
    Nginx
          ↓
    PHP
          ↓
    MySQL

    If caching is poor:

    database workload increases

    Then:

    CPU
    RAM
    storage I/O

    can all increase.


    65. Why Caching Is So Important

    With page cache:

    Request
     ↓
    Nginx/cache
     ↓
    HTML

    Without it:

    Request
     ↓
    Nginx
     ↓
    PHP
     ↓
    WordPress
     ↓
    MySQL

    Caching can therefore reduce work throughout the stack.


    66. Your Hosting Architecture Is Becoming Clear

    You can now see:

                 INTERNET
                     │
                     ▼
                    DNS
                     │
                     ▼
                 PUBLIC IP
                     │
                     ▼
                  OCI VCN
                     │
                     ▼
                  SUBNET
                     │
                     ▼
                   VNIC
                     │
                     ▼
                   UBUNTU
                     │
              ┌──────┴──────┐
              ▼             ▼
            NETWORK        STORAGE
              │             │
              ▼             ▼
            NGINX       /storage
              │             │
              ▼             ▼
          PHP-FPM       WordPress
              │
              ▼
           MySQL

    And security surrounds it:

    Cloud security
    +
    Linux firewall
    +
    Users
    +
    Groups
    +
    Permissions

    67. Lesson 056 — Core Principle

    The most important idea:

    Routing determines where traffic goes; ports determine which service receives it.

    For your WordPress server:

    learn.cresignsys.com
            ↓
    DNS
            ↓
    Public IP
            ↓
    OCI routing
            ↓
    VNIC
            ↓
    TCP 443
            ↓
    Nginx
            ↓
    PHP-FPM
            ↓
    WordPress

    If you understand that chain, you can troubleshoot most basic hosting connectivity problems systematically.


    Next Lesson — 057

    DNS Deep Dive — How learn.cresignsys.com Finds Your VPS

    We will go deeper into:

    Domain
     ↓
    DNS hierarchy
     ↓
    Root DNS
     ↓
    TLD
     ↓
    Authoritative nameserver
     ↓
    A record
     ↓
    AAAA record
     ↓
    CNAME
     ↓
    TTL
     ↓
    DNS cache
     ↓
    Recursive resolver
     ↓
    Your VPS

    Then we will connect it directly to your CresignSys domains and explain why:

    domain works
    domain doesn't work
    www works
    root domain doesn't work
    IPv4 works
    IPv6 doesn't work

    can all happen even when the WordPress installation itself is perfectly correct.

  • CresignSys Learn — Lesson 055

    Linux Networking — From Internet to Nginx

    We now move from storage and permissions into the networking layer.

    The goal is to understand exactly what happens when someone opens:

    https://learn.cresignsys.com

    1. The Complete Journey

    At a high level:

    Browser
       ↓
    DNS
       ↓
    Public IP
       ↓
    Internet
       ↓
    Oracle Cloud network
       ↓
    VNIC
       ↓
    Ubuntu network interface
       ↓
    TCP port 443
       ↓
    Nginx
       ↓
    HTTPS
       ↓
    Website

    Each layer can fail independently.


    2. What Is a Network?

    A network allows computers to exchange data.

    For example:

    Your computer
          │
          │ Internet
          │
          ▼
    Oracle VPS

    Data travels between the two systems.


    3. IP Address

    An IP address identifies a network endpoint.

    IPv4 example:

    203.0.113.25

    IPv6 example:

    2001:db8::25

    Your VPS has network addresses assigned to its interfaces.


    4. Private vs Public IP

    A server can have:

    Private IP

    and:

    Public IP

    The private address is used inside a private network.

    The public address is reachable through the Internet, subject to routing and security controls.


    5. Example

    Conceptually:

    Internet
       │
       ▼
    Public IP
    203.0.113.25
       │
       ▼
    Private IP
    10.x.x.x
       │
       ▼
    Ubuntu

    The exact addressing depends on your Oracle Cloud network configuration.


    6. Your VNIC

    In Oracle Cloud, your VM uses a:

    VNIC

    Virtual Network Interface Card.

    Think of it as the VM’s virtual network adapter.

    Conceptually:

    Internet
       ↓
    OCI Network
       ↓
    VNIC
       ↓
    Ubuntu

    7. Physical NIC vs VNIC

    A physical computer may have:

    Ethernet card

    A cloud VM generally sees a virtual network interface:

    VNIC

    The cloud provider manages the underlying physical networking.


    8. Linux Sees a Network Interface

    Inside Ubuntu, you can inspect interfaces with:

    ip addr

    or:

    ip a

    You may see something similar to:

    lo
    ens3

    The exact interface name can differ.


    9. Loopback

    One interface you will usually see is:

    lo

    This is:

    Loopback

    It represents the computer talking to itself.

    Common address:

    127.0.0.1

    10. Why 127.0.0.1 Matters

    Suppose Nginx listens on:

    127.0.0.1:8080

    That means it is accessible through the local machine’s loopback interface.

    It does not necessarily mean it is directly reachable from the Internet.


    11. 0.0.0.0

    You may also see a service listening on:

    0.0.0.0:80

    This means it is listening on IPv4 interfaces generally, subject to other networking controls.

    For example:

    0.0.0.0:80

    can allow connections arriving through the server’s network interfaces.


    12. IPv6 Equivalent

    For IPv6, you may see:

    [::]:80

    This represents listening on IPv6 addresses broadly, subject to configuration.


    13. Check Interfaces

    Run:

    ip addr

    Look for:

    inet

    and:

    inet6

    Example:

    inet 10.0.0.10/24

    14. CIDR

    The:

    /24

    is part of:

    CIDR notation

    CIDR describes the network prefix length.

    Example:

    10.0.0.10/24

    means:

    IP = 10.0.0.10
    prefix length = 24 bits

    15. IPv4 Structure

    IPv4 has:

    32 bits

    Example:

    192.168.1.10

    It contains four octets:

    192
    .
    168
    .
    1
    .
    10

    Each octet is 8 bits.


    16. /24

    A /24 means:

    24 bits = network portion
    8 bits  = host portion

    Conceptually:

    192.168.1 | .10
    network   | host

    17. Don’t Memorize Subnet Math Yet

    For now remember:

    IP address
    +
    prefix length
    =
    network addressing information

    We will study subnetting separately.


    18. Default Gateway

    Your server needs to know where to send traffic that isn’t on its local network.

    That is the job of the:

    Default Gateway

    Check:

    ip route

    You may see:

    default via 10.0.0.1 dev ens3

    Conceptually:

    Ubuntu
     ↓
    default gateway
     ↓
    outside network

    19. Routing Table

    Linux maintains a:

    Routing Table

    It decides where packets should go.

    Check it:

    ip route

    Example:

    10.0.0.0/24 dev ens3
    default via 10.0.0.1 dev ens3

    20. What Does default Mean?

    It means:

    If no more specific route matches the destination, use this route.

    Conceptually:

    Destination known locally?
           │
       yes │ no
           ▼
     local route
           │
           └──── no ────► default route

    21. Packet

    When your browser sends data, it is broken into network packets.

    Conceptually:

    Message
     ↓
    Network data
     ↓
    Packets
     ↓
    Internet

    Each packet contains addressing information needed for delivery.


    22. IP Layer

    The IP protocol handles addressing and routing between networks.

    Conceptually:

    Source IP
         ↓
    Packet
         ↓
    Destination IP

    23. TCP

    For a typical HTTPS connection, TCP is involved.

    TCP provides a reliable, ordered byte stream.

    The simplified hierarchy is:

    HTTP
     ↓
    TLS
     ↓
    TCP
     ↓
    IP
     ↓
    Network interface

    24. Port

    An IP address identifies a network endpoint.

    A:

    Port

    helps identify the service/application endpoint on that host.

    For example:

    203.0.113.25:443

    means:

    IP   = 203.0.113.25
    Port = 443

    25. Common Ports

    You should know:

    22   SSH
    80   HTTP
    443  HTTPS
    25   SMTP
    53   DNS
    3306 MySQL

    These are conventional defaults, not laws.

    Services can be configured to use other ports.


    26. Why Ports Exist

    Imagine your VPS has:

    Nginx
    SSH
    MySQL

    all running on the same server.

    They need different network endpoints.

    Conceptually:

    VPS
    │
    ├── :22   SSH
    ├── :80   HTTP
    ├── :443  HTTPS
    └── :3306 MySQL

    27. Socket

    A network connection is associated with a:

    Socket

    A simplified endpoint can be thought of as:

    IP + protocol + port

    For example:

    TCP
    203.0.113.25
    443

    28. Listening Socket

    When Nginx waits for connections:

    Nginx
     ↓
    listen
     ↓
    TCP :443

    It is listening on a socket.

    Check:

    sudo ss -ltnp

    29. Understand ss

    Example:

    LISTEN
    0
    128
    0.0.0.0:443

    The important part:

    0.0.0.0:443

    means something is listening on TCP port 443 on IPv4 interfaces generally.


    30. Find Port 80

    sudo ss -ltnp | grep ':80'

    Find HTTPS:

    sudo ss -ltnp | grep ':443'

    31. Example

    Suppose you see:

    LISTEN 0 511 0.0.0.0:443

    This suggests:

    something
     ↓
    listening
     ↓
    TCP
     ↓
    port 443

    Now identify the process using the -p information.


    32. Nginx

    If the process is:

    nginx

    then:

    Nginx
     ↓
    TCP 443

    is listening.

    That is a good sign.

    But it doesn’t prove Internet connectivity yet.


    33. Local vs External Testing

    Suppose:

    curl https://localhost

    works.

    But:

    curl https://your-domain.com

    fails.

    That means the problem may be somewhere between:

    Internet
     ↓
    DNS
     ↓
    cloud network
     ↓
    firewall
     ↓
    server

    34. Local Test

    Run:

    curl -I http://127.0.0.1

    This tests locally.

    If Nginx is listening on port 80, you may receive an HTTP response.


    35. HTTPS Local Test

    You might use:

    curl -kI https://127.0.0.1

    The -k option tells curl not to reject an invalid/untrusted certificate during this test.

    This is a diagnostic technique, not a recommendation to ignore certificate validation in normal use.


    36. Test the Domain

    From a client:

    curl -I https://learn.cresignsys.com

    This tests much more of the actual path.


    37. DNS Check

    Before network troubleshooting:

    dig +short learn.cresignsys.com

    You want to confirm it resolves to the expected public IP.


    38. DNS Correct but Website Fails

    Suppose:

    DNS
    ✓

    but:

    Website
    ✗

    Then investigate:

    port
    firewall
    Nginx
    TLS
    application

    39. Connection Refused

    Suppose:

    Connection refused

    This often means the destination was reachable at the network level, but no service accepted the connection on that endpoint, or an active firewall/reject rule rejected it.

    Common causes include:

    Nginx not running
    nothing listening on the port
    wrong bind address
    firewall reject

    40. Connection Timed Out

    A timeout often indicates that packets or responses aren’t getting through as expected.

    Possible causes include:

    cloud security rules
    firewall
    routing
    wrong IP
    service unreachable
    network path issue

    The exact cause must be tested.


    41. Refused vs Timeout

    A useful first approximation:

    refused
    =
    you reached something, but connection wasn't accepted
    timeout
    =
    you didn't receive the expected response in time

    These are clues, not definitive diagnoses.


    42. Oracle Cloud Security

    Your Oracle Cloud environment has network security controls.

    For a web server, you normally need appropriate inbound access for:

    TCP 80
    TCP 443

    For SSH:

    TCP 22

    But exposure should be limited to what is actually required.


    43. Cloud Firewall vs Linux Firewall

    There can be multiple security layers.

    For example:

    Internet
     ↓
    OCI network security
     ↓
    Ubuntu firewall
     ↓
    Nginx

    A connection can be blocked before it ever reaches Nginx.


    44. OCI Network Layer

    At the Oracle Cloud level, your VM can be associated with:

    VCN
    Subnet
    VNIC
    Route Table
    Security List
    Network Security Group
    Public IP

    These components work together to determine network reachability.


    45. VCN

    VCN means:

    Virtual Cloud Network

    Think of it as your virtual private network environment in Oracle Cloud.

    Conceptually:

    OCI
     ↓
    VCN
     ↓
    Subnet
     ↓
    VNIC
     ↓
    VM

    46. Subnet

    A subnet is a logical IP network within the VCN.

    For example:

    VCN
    │
    ├── Public subnet
    │
    └── Private subnet

    The exact design depends on your architecture.


    47. Public Subnet

    A public subnet can be configured so that resources can have paths to/from the Internet through appropriate routing and public IP configuration.

    It does not mean:

    Every resource is automatically exposed to every Internet connection.

    Security rules still matter.


    48. Private Subnet

    A private subnet is typically designed without direct public Internet exposure for its resources.

    For example:

    Internet
       │
       ▼
    Web server
       │
       ▼
    Private database

    This is a common architecture.


    49. Public IP

    A public IP provides an Internet-facing address for the VM/network interface when appropriately configured.

    Your domain’s A record can point to it.

    Conceptually:

    learn.cresignsys.com
            ↓
    public IP
            ↓
    VPS

    50. Private IP

    Inside the VCN, the VNIC has a private IP.

    For example:

    10.0.0.10

    The Internet does not normally directly route to this RFC1918 private address.


    51. NAT

    NAT means:

    Network Address Translation

    It allows traffic to be translated between addressing domains.

    For example, private systems may access the Internet through a NAT gateway without receiving public IP addresses.

    This becomes important in more advanced cloud architectures.


    52. Internet Gateway

    A VCN can use an:

    Internet Gateway

    to provide Internet connectivity for appropriately routed resources.

    Conceptually:

    VM
     ↓
    VCN
     ↓
    Internet Gateway
     ↓
    Internet

    Routing and security rules must also permit the traffic.


    53. Route Table

    A route table tells the VCN where traffic should go.

    Conceptually:

    Destination
    0.0.0.0/0
           ↓
    Internet Gateway

    means traffic destined for addresses outside the local network can be routed toward the Internet gateway, assuming the rest of the configuration permits it.


    54. Security List

    Oracle Cloud can use security lists associated with subnets.

    They define allowed traffic rules.

    For a web server you might allow:

    TCP 80
    TCP 443

    and SSH:

    TCP 22

    from an appropriate source range.


    55. Network Security Group

    OCI also supports:

    NSG

    Network Security Group.

    NSGs allow security rules to be associated with VNICs/resources rather than simply treating the whole subnet as one security boundary.

    This can provide more granular architecture.


    56. Security Rule Concept

    Think:

    Source
     ↓
    Protocol
     ↓
    Destination port
     ↓
    Allow / deny

    Example concept:

    Internet
     ↓
    TCP
     ↓
    443
     ↓
    ALLOW
     ↓
    web server

    57. Don’t Open Everything

    Avoid:

    0.0.0.0/0

    for every possible port.

    For example, exposing MySQL:

    3306

    to the entire Internet is generally unnecessary for a typical single-server WordPress setup.


    58. MySQL Should Usually Be Private

    If:

    Nginx
    PHP-FPM
    MySQL

    are all on the same VPS, WordPress can communicate with MySQL locally.

    There is usually no reason to expose:

    3306

    to the Internet.


    59. SSH

    SSH uses:

    TCP 22

    by default.

    If you expose SSH publicly:

    Internet
     ↓
    TCP 22
     ↓
    SSH

    you should secure it appropriately.


    60. Web Ports

    For normal websites:

    HTTP
    TCP 80

    and:

    HTTPS
    TCP 443

    are the common public ports.


    61. HTTP Redirect

    Many websites use:

    Port 80
     ↓
    redirect
     ↓
    HTTPS 443

    So both ports can be needed.


    62. HTTPS Flow

    When the user enters:

    https://learn.cresignsys.com

    the simplified path is:

    DNS
     ↓
    Public IP
     ↓
    TCP 443
     ↓
    TLS handshake
     ↓
    HTTP request
     ↓
    Nginx

    63. TCP Three-Way Handshake

    TCP connection establishment traditionally begins with:

    Client → SYN
    Server → SYN-ACK
    Client → ACK

    Conceptually:

    Client                    Server
    
      SYN  -------------------->
    
           <-------------------- SYN-ACK
    
      ACK  -------------------->

    Now the TCP connection is established.


    64. Why TCP Handshake Matters

    If you cannot establish TCP:

    TLS

    cannot proceed normally.

    Therefore:

    TCP failure
     ↓
    HTTPS failure

    65. TLS Comes After TCP

    The simplified order:

    DNS
     ↓
    IP routing
     ↓
    TCP connection
     ↓
    TLS handshake
     ↓
    HTTP

    This is important for troubleshooting.


    66. Test TCP Port

    From another machine, you can use:

    nc -vz example.com 443

    or:

    nc -vz example.com 80

    If nc is installed.


    67. What Does nc -vz Do?

    It attempts to connect to the specified host and port.

    Example:

    example.com:443

    This helps answer:

    Can I establish a TCP connection to port 443?


    68. curl Tests More

    Compare:

    nc -vz example.com 443

    with:

    curl -I https://example.com

    nc focuses on connectivity.

    curl can test higher-level HTTP/HTTPS behavior.


    69. ping

    You may also know:

    ping example.com

    But:

    Ping is not a reliable test of whether a website works.

    Why?

    Because ping uses:

    ICMP

    while websites use:

    TCP 80/443

    70. Ping Can Fail While Website Works

    A server may block ICMP.

    So:

    ping
    ✗

    doesn’t necessarily mean:

    website
    ✗

    71. Website Can Fail While Ping Works

    Conversely:

    ping
    ✓

    only tells you that ICMP communication worked.

    It doesn’t prove:

    TCP 443
    ✓

    72. Better Website Test

    Use:

    curl -I https://learn.cresignsys.com

    This tests the actual HTTP/HTTPS service.


    73. Check Nginx

    On the VPS:

    sudo systemctl status nginx

    Then:

    sudo ss -ltnp | grep ':443'

    You want to establish:

    Nginx
    ✓ running
    
    Port 443
    ✓ listening

    74. Check Firewall

    On Ubuntu, you may use:

    sudo ufw status

    If UFW is active, check whether the required ports are allowed.

    For example, you may see rules for:

    80/tcp
    443/tcp

    75. Important: UFW May Not Be Your Only Firewall

    Even if:

    ufw

    looks correct, Oracle Cloud network security may still block traffic.

    Therefore:

    OCI security
    +
    Ubuntu firewall
    +
    service listener

    all need to align.


    76. Complete Port 443 Troubleshooting

    If HTTPS doesn’t work:

    1. DNS
       ↓
    2. Public IP
       ↓
    3. OCI routing
       ↓
    4. OCI security rules
       ↓
    5. Ubuntu firewall
       ↓
    6. Nginx listening
       ↓
    7. TCP 443
       ↓
    8. TLS certificate
       ↓
    9. Nginx server_name
       ↓
    10. WordPress

    77. Example Failure

    DNS

    learn.cresignsys.com
     ↓
    correct IP

    Nginx

    running

    Port

    443
    not listening

    Result:

    HTTPS fails

    The problem is not DNS.


    78. Another Failure

    Everything:

    DNS ✓
    Nginx ✓
    443 ✓

    but OCI security rules:

    443 blocked

    Result:

    Internet
     ↓
    blocked
     ↓
    Nginx never receives connection

    79. Another Failure

    Everything:

    DNS ✓
    443 ✓
    Nginx ✓
    TLS ✓

    but:

    server_name

    is wrong.

    You may receive the wrong website or default server.


    80. Another Failure

    Everything reaches Nginx:

    DNS ✓
    network ✓
    TCP ✓
    TLS ✓
    Nginx ✓

    but PHP-FPM is down.

    Then a dynamic WordPress request may produce:

    502 Bad Gateway

    Now you move to the application layer.


    81. This Is the Layered Troubleshooting Method

    Never randomly change everything.

    Move from outside to inside:

    DNS
     ↓
    IP
     ↓
    route
     ↓
    cloud firewall
     ↓
    Linux firewall
     ↓
    TCP
     ↓
    Nginx
     ↓
    TLS
     ↓
    PHP-FPM
     ↓
    WordPress
     ↓
    MySQL

    82. Essential Networking Commands

    Interfaces

    ip addr

    Routes

    ip route

    Listening ports

    sudo ss -ltnp

    DNS

    dig +short example.com

    HTTP/HTTPS

    curl -I https://example.com

    TCP test

    nc -vz example.com 443

    Firewall

    sudo ufw status

    83. Three Commands to Memorize First

    If you remember only three:

    ip addr
    ip route
    sudo ss -ltnp

    They tell you:

    What interfaces do I have?
            ↓
    Where does traffic go?
            ↓
    What services are listening?

    84. Your Oracle VPS Mental Model

    Think of your VPS as:

                      INTERNET
                          │
                          ▼
                    PUBLIC IP
                          │
                          ▼
                         VCN
                          │
                          ▼
                       SUBNET
                          │
                          ▼
                        VNIC
                          │
                          ▼
                    UBUNTU NETWORK
                          │
                 ┌────────┴────────┐
                 ▼                 ▼
              TCP 80            TCP 443
                 │                 │
                 ▼                 ▼
              NGINX              NGINX
                                   │
                                   ▼
                                  TLS
                                   │
                                   ▼
                               WORDPRESS

    85. The Deepest Concept

    A domain name is not directly connected to WordPress.

    The actual chain is:

    Domain
     ↓
    DNS
     ↓
    IP
     ↓
    Network routing
     ↓
    VNIC
     ↓
    Linux interface
     ↓
    TCP port
     ↓
    Listening socket
     ↓
    Nginx process
     ↓
    Website configuration
     ↓
    PHP-FPM
     ↓
    WordPress

    Each arrow represents another technical layer.


    86. Lesson 055 Core Principle

    Remember:

    A server being online does not mean a website is reachable.

    For the website to work:

    DNS
    ✓
    
    Routing
    ✓
    
    Cloud security
    ✓
    
    Linux firewall
    ✓
    
    TCP port
    ✓
    
    Nginx
    ✓
    
    TLS
    ✓
    
    PHP-FPM
    ✓
    
    WordPress
    ✓
    
    MySQL
    ✓

    All required layers must work together.


    Next Lesson — 056

    Linux Networking Deeper — IP, Subnet, Gateway, NAT & Routing

    We will now go below the port level and understand:

    IPv4
     ↓
    Binary
     ↓
    Subnet mask
     ↓
    CIDR
     ↓
    Network address
     ↓
    Broadcast
     ↓
    Host address
     ↓
    Gateway
     ↓
    ARP
     ↓
    Routing table
     ↓
    NAT
     ↓
    Public ↔ Private IP

    Then we will apply it directly to your Oracle Cloud VCN, subnet, VNIC and public IP, so you understand exactly how a packet travels from a user’s laptop in Kerala to your VPS.