Skip to content

melancholic-ksm/none

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 

Repository files navigation

Perfect πŸš€. Since you now have 6 fresh Ubuntu 24 VMs, let’s prepare them step by step so you get:

  • Nginx installed
  • PHP 8.3 installed
  • Domain cayana.me pointing to VMs (via Cloudflare DNS)
  • GitHub repo sync β†’ CI/CD deploy to /var/www/cayana.me
  • Dummy HTML page (to test across all)
  • Later β†’ load balancer logic

🟒 Step 1. SSH into all 6 VMs

ssh azureuser@<VM_PUBLIC_IP>

(replace <VM_PUBLIC_IP> with Kitkat/Dairymilk/Exoticdark’s public IPs; private-only ones you reach through their sibling public VMs or Azure Bastion/SSH proxy).


🟒 Step 2. Update & Install Dependencies

Run on all 6 VMs:

sudo apt update && sudo apt upgrade -y
sudo apt install -y nginx git unzip curl software-properties-common

🟒 Step 3. Install PHP 8.3 + FPM

sudo add-apt-repository ppa:ondrej/php -y
sudo apt update
sudo apt install -y php8.3 php8.3-fpm php8.3-cli php8.3-common php8.3-mysql php8.3-curl php8.3-xml php8.3-mbstring

Enable PHP-FPM:

sudo systemctl enable --now php8.3-fpm

Check it:

php -v

🟒 Step 4. Set up Nginx VirtualHost for cayana.me

sudo mkdir -p /var/www/cayana.me
sudo chown -R $USER:$USER /var/www/cayana.me

Dummy HTML for testing:

echo "<h1>Hello from $(hostname) at cayana.me</h1>" | sudo tee /var/www/cayana.me/index.html

Now create Nginx site config:

sudo nano /etc/nginx/sites-available/cayana.me

Paste:

server {
    listen 80;
    server_name cayana.me www.cayana.me;

    root /var/www/cayana.me;
    index index.php index.html;

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

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

Enable & reload:

sudo ln -s /etc/nginx/sites-available/cayana.me /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

🟒 Step 5. DNS Setup (Cloudflare)

  • In Cloudflare, go to DNS for cayana.me.
  • Add A records for:
cayana.me β†’ <Kitkat Public IP>
cayana.me β†’ <Dairymilk Public IP>
cayana.me β†’ <Exoticdark Public IP>

(leave Barone, 5-Star, Kisses private β€” they’ll join cluster later).

That gives DNS round robin across 3 accounts.


🟒 Step 6. GitHub Repo Auto-Sync (CI/CD Lite)

On each VM:

cd /var/www/cayana.me
git init
git remote add origin https://github.com/<your-username>/<your-repo>.git
git pull origin main

To auto-deploy on new pushes, use a GitHub webhook + small script.

Create script:

sudo nano /var/www/deploy.sh
#!/bin/bash
cd /var/www/cayana.me || exit
git fetch --all
git reset --hard origin/main

Make executable:

sudo chmod +x /var/www/deploy.sh

Now setup a webhook in your repo β†’ pointing to VM (http://<vm-ip>/webhook) OR use GitHub Actions to SSH deploy.


🟒 Step 7. Test

  1. Visit http://cayana.me β€” should load from random VM. Each VM prints hostname β†’ you’ll see e.g.:

    • Hello from kitkat-vm at cayana.me
    • Hello from dairymilk-vm at cayana.me
    • etc.
  2. PHP test:

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

Visit http://cayana.me/info.php β†’ should show PHP 8.3 page.


πŸ‘‰ At this stage:

  • You have working site across 6 VMs (3 public, 3 private).
  • DNS is set (Cloudflare Free).
  • GitHub repo is synced (manual pull for now, or CI/CD later).
  • PHP 8.3 + Nginx ready.

⚑ Next step: I can help you wire the cluster load-aware redirect/proxy so private VMs also serve traffic through public ones.


Got it πŸ‘ thanks for sharing the error details.

You’re seeing ERR_CONNECTION_REFUSED when opening https://cayana.me. Let’s troubleshoot step by step:


1. Meaning of ERR_CONNECTION_REFUSED

This usually means:

  • The server is not listening on the requested port (443 for HTTPS).
  • A firewall / security group is blocking access.
  • Nginx is running but not configured for SSL, so it’s rejecting HTTPS traffic.

2. Check DNS

Run:

dig cayana.me +short

or

nslookup cayana.me

βœ… Make sure it resolves to the public IP of your VPS.


3. Check if Nginx is Running

On the VPS:

sudo systemctl status nginx

If it’s inactive, start it:

sudo systemctl start nginx
sudo systemctl enable nginx

4. Check Which Ports Are Open

sudo ss -tlnp | grep nginx

You should see something like:

LISTEN 0 128 *:80    nginx
LISTEN 0 128 *:443   nginx

πŸ‘‰ If port 443 is missing, Nginx isn’t serving HTTPS.


5. Check Firewall / Security Group

On Ubuntu with UFW:

sudo ufw status

Make sure you allow:

sudo ufw allow 80
sudo ufw allow 443

If you’re on cloud VPS (AWS Lightsail, Azure, etc.), also check the provider’s security group rules.


6. Configure SSL in Nginx

If you only have a test setup and didn’t install SSL yet, Nginx is likely refusing HTTPS. You have two quick options:

Option A β€” Enable HTTP (for testing)

Edit your Nginx config:

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

Add:

server {
    listen 80;
    server_name cayana.me www.cayana.me;

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

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

Then:

sudo nginx -t
sudo systemctl reload nginx

βœ… Now test http://cayana.me.


Option B β€” Set Up SSL with Let’s Encrypt

Install certbot:

sudo apt install -y certbot python3-certbot-nginx

Run:

sudo certbot --nginx -d cayana.me -d www.cayana.me

This will:

  • Get a free SSL cert
  • Update Nginx config
  • Enable HTTPS automatically

Then reload Nginx:

sudo systemctl reload nginx

7. Test Again

  • http://cayana.me should work if you did Option A.
  • https://cayana.me should work if you did Option B.

πŸ‘‰ Based on your note β€œmaybe nginx is not having ssl is problem as only https is on” β€” yes, exactly. If you only have an A record but no SSL certificate & Nginx HTTPS config, the browser refuses HTTPS.


Would you like me to prepare a ready-to-use minimal Nginx config for cayana.me (with or without SSL), so you can just paste it into /etc/nginx/sites-available/ and enable it?


Perfect question πŸ‘ β€” if you’re using Cloudflare, you don’t need Let’s Encrypt; instead, you can install a Cloudflare Origin Certificate on your VPS.

This is often better because:

  • The certificate is issued by Cloudflare and only trusted between your VPS ↔ Cloudflare edge servers.
  • Visitors see Cloudflare’s SSL (the public one).
  • You can enable β€œFull (Strict)” SSL mode in Cloudflare for best security.

πŸš€ Steps to Install Cloudflare Origin SSL/TLS on Your VPS


1. Generate Origin Certificate in Cloudflare

  1. Log in to Cloudflare Dashboard β†’ Select your domain (cayana.me).

  2. Go to SSL/TLS β†’ Origin Server.

  3. Click Create Certificate.

  4. Choose:

    • Private key type: RSA (2048).
    • Hosts: cayana.me and *.cayana.me.
    • Validity: up to 15 years.
  5. Cloudflare will generate:

    • An Origin Certificate (looks like -----BEGIN CERTIFICATE-----).
    • A Private Key (save it, you won’t see it again).

2. Upload Certificate to VPS

On your VPS (Linux):

sudo mkdir -p /etc/ssl/certs/cloudflare
sudo nano /etc/ssl/certs/cloudflare/cayana.me.pem

Paste the Origin Certificate here.

Then create the private key file:

sudo nano /etc/ssl/certs/cloudflare/cayana.me.key

Paste the Private Key here.

Secure permissions:

sudo chmod 600 /etc/ssl/certs/cloudflare/cayana.me.*

3. Configure Nginx

Edit your site config:

sudo nano /etc/nginx/sites-available/cayana.me

Example config:

server {
    listen 80;
    server_name cayana.me www.cayana.me;

    # Redirect HTTP -> HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name cayana.me www.cayana.me;

    ssl_certificate     /etc/ssl/certs/cloudflare/cayana.me.pem;
    ssl_certificate_key /etc/ssl/certs/cloudflare/cayana.me.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers   HIGH:!aNULL:!MD5;

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

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

Enable site and reload Nginx:

sudo ln -s /etc/nginx/sites-available/cayana.me /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

4. Enable Full (Strict) in Cloudflare

  1. Go to Cloudflare Dashboard β†’ SSL/TLS β†’ Overview.
  2. Select Full (Strict) mode.

This ensures:

  • Cloudflare ↔ Client = Cloudflare’s cert (trusted).
  • Cloudflare ↔ Origin VPS = Origin Cert (yours).

5. Verify

Check from local machine:

curl -I https://cayana.me

You should see a 200 OK (or your page’s status).


βœ… Now, your site is:

  • Securely encrypted end-to-end.
  • Protected by Cloudflare SSL in front.
  • Using Cloudflare Origin Certificate at your VPS.

⚠️ Note: If you ever bypass Cloudflare (accessing VPS IP directly in browser), you’ll see a cert warning β€” that’s normal, because the Origin Cert is only trusted by Cloudflare, not public browsers.


Do you want me to also write a ready-to-paste Nginx config with Cloudflare’s recommended SSL hardening (HSTS, OCSP stapling, ciphers) so you get an A+ rating on SSL Labs?


Thanks for pasting the error β€” this tells us exactly what’s wrong.

The key error is:

SSL_CTX_set_cipher_list(...) failed (SSL: error:0A000118:SSL routines::invalid command)

That happens when:

  • Your Nginx build (or linked OpenSSL library) doesn’t recognize some cipher strings I gave.
  • Different distros ship Nginx with different SSL modules, so certain cipher lists fail.

βœ… Fix

We’ll simplify the SSL section so it’s compatible across most Linux distros:

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;
    ssl_ciphers HIGH:!aNULL:!MD5;

This keeps it secure but avoids hardcoding unsupported ciphers.


πŸ”§ Updated Config

Your /etc/nginx/sites-available/cayana.me should look like this:

server {
    listen 80;
    server_name cayana.me www.cayana.me;

    # Redirect HTTP -> HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name cayana.me www.cayana.me;

    root /var/www/cayana.me;
    index index.php index.html;

    ssl_certificate     /etc/ssl/certs/cloudflare/cayana.me.pem;
    ssl_certificate_key /etc/ssl/certs/cloudflare/cayana.me.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1h;

    # Optional: enable HSTS (be careful in testing!)
    # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

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

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

πŸš€ Apply Changes

  1. Test config:
sudo nginx -t
  1. If no errors:
sudo systemctl restart nginx

⚠️ About ln: failed to create symbolic link

That message just means you already had a symlink from /etc/nginx/sites-enabled/cayana.me β†’ /etc/nginx/sites-available/cayana.me. No problem β€” it’s already enabled, so you don’t need to re-link.


After this fix, nginx -t should succeed and https://cayana.me should load through Cloudflare.

πŸ‘‰ Do you want me to also add OCSP stapling & auto security headers (X-Frame-Options, Referrer-Policy, etc.) to harden your Nginx further, or keep it minimal for now?


Nice! πŸ‘Œ Now let’s make your repo directly mapped to /var/www/cayana.me so you can update your site with one simple git pull or even push directly from GitHub β†’ VM.


🟒 Step 1. Initialize Repo in /var/www/cayana.me

cd /var/www/cayana.me
sudo rm -rf .git   # in case any leftover
git init
git remote add origin https://github.com/<your-username>/<your-repo>.git
git fetch origin main
git checkout -t origin/main

Now /var/www/cayana.me = your repo.


🟒 Step 2. Set Permissions for Web User

sudo chown -R $USER:$USER /var/www/cayana.me

🟒 Step 3. Create β€œOne-Click” Pull Script

Create deploy script:

sudo nano /usr/local/bin/deploy-cayana.sh

Paste:

#!/bin/bash
cd /var/www/cayana.me || exit
git fetch --all
git reset --hard origin/main
echo "βœ… cayana.me updated at $(date)"

Make executable:

sudo chmod +x /usr/local/bin/deploy-cayana.sh

Now anytime you want to update:

deploy-cayana.sh

🟒 Step 4. (Optional) One-Click Push From VM β†’ GitHub

If you want to make edits on the VM itself:

cd /var/www/cayana.me
git add .
git commit -m "Update from VM"
git push origin main

πŸ‘‰ For this to work, you’ll need to set up SSH deploy key or use HTTPS with a GitHub Personal Access Token.


🟒 Step 5. Auto-Deploy on GitHub Push (Optional)

If you want automatic updates whenever you push to GitHub:

  1. Go to GitHub Repo β†’ Settings β†’ Webhooks
  2. Add webhook β†’ http://<VM_PUBLIC_IP>/webhook

On VM, set up a tiny webhook listener (Python/Node or PHP) that just runs deploy-cayana.sh.


πŸ”₯ Result:

  • /var/www/cayana.me is now your repo
  • deploy-cayana.sh gives one-click pull
  • You can push changes back if you want

Do you want me to set this up push-only from GitHub (CI/CD style), or keep it manual one-click pull for now?


Exactly πŸ‘ β€” but only if you set up the webhook listener on your VM.

Right now with just deploy-cayana.sh, you need to manually run it to pull changes. To make it automatic whenever you push to GitHub, you need:


Option 1: Easiest – Use GitHub Actions + SSH

  • On GitHub β†’ Actions Workflow that runs every push to main.
  • The workflow connects to your VM via SSH and runs deploy-cayana.sh. βœ… Super reliable, no need to open ports on VM. ⚑ Recommended.

Option 2: GitHub Webhook + Local Listener

  1. Add a webhook in GitHub repo:

    http://<your-vm-public-ip>/webhook
    

    (event: push)

  2. On VM, run a tiny service (Node.js, Python Flask, or PHP) that listens on /webhook and executes deploy-cayana.sh. Example with Python (Flask):

    pip install flask
    # /opt/webhook/webhook.py
    from flask import Flask, request
    import subprocess
    
    app = Flask(__name__)
    
    @app.route('/webhook', methods=['POST'])
    def webhook():
        subprocess.Popen(["/usr/local/bin/deploy-cayana.sh"])
        return "OK", 200
    
    if __name__ == '__main__':
        app.run(host="0.0.0.0", port=80)

    Then run it as a service (so it auto-starts).

⚠️ Downside: your VM must allow inbound HTTP (port 80), and you should secure it with a GitHub secret token.


Option 3: Cronjob Pull (No webhook)

  • Just set a cronjob to auto-pull every 1 minute (or 5):

    crontab -e

    Add:

    * * * * * /usr/local/bin/deploy-cayana.sh >> /var/log/deploy.log 2>&1
    

    βœ… Super simple ❌ Not instant β€” updates apply on schedule (every minute).


πŸ‘‰ If you want real-time auto-deploy β†’ go with GitHub Actions (Option 1). πŸ‘‰ If you want no GitHub config, just VM side β†’ cronjob (Option 3).

Do you want me to write you the GitHub Actions workflow for Option 1 (best way), so your VM always updates instantly on push?


Got it πŸ‘ β€” since your repo is now synced to /var/www/cayana.me, we don’t need that old index.html we manually created.

Run this on each VM where you created the dummy file:

sudo rm -f /var/www/cayana.me/index.html

πŸ” Then confirm the repo content is being served instead:

ls -l /var/www/cayana.me

You should see your GitHub repo files there.

Would you like me to also adjust your Nginx config so it serves /var/www/cayana.me/public (in case your repo has a public/ folder, like many PHP/Laravel setups), or should it directly serve the repo root?


Ah got it πŸ‘ you mean the script you made earlier (deploy-cayana.sh) inside /usr/local/bin.

To run it manually, just SSH into your VM and run:

deploy-cayana.sh

or explicitly:

bash /usr/local/bin/deploy-cayana.sh

πŸ” What it does

  • Goes to /var/www/cayana.me
  • Fetches the latest changes from your GitHub repo
  • Resets files to match origin/main
  • Prints a log line like: βœ… cayana.me updated at Thu Sep 12 15:32:00 UTC 2025

βœ… Ways to use it

  1. Manual update Run deploy-cayana.sh anytime you want to pull the latest repo changes.

  2. Cronjob (already set up) Runs automatically every minute via your crontab:

    * * * * * /usr/local/bin/deploy-cayana.sh >> /var/log/deploy.log 2>&1

    You can check logs with:

    tail -f /var/log/deploy.log
  3. GitHub Actions / Webhook (optional) If you want instant deployment (not every 1 min), you can make GitHub trigger this script via SSH or webhook.


πŸ‘‰ Do you want me to write you a GitHub Actions workflow so every time you push to your repo, GitHub automatically SSHes into your VM and runs deploy-cayana.sh?


Got it πŸ‘ right now your cron runs every 1 minute. To change it to every 5 minutes, edit the crontab:

crontab -e

Then replace this line:

* * * * * /usr/local/bin/deploy-cayana.sh >> /var/log/deploy.log 2>&1

with:

*/5 * * * * /usr/local/bin/deploy-cayana.sh >> /var/log/deploy.log 2>&1

βœ… Now deploy-cayana.sh will run every 5 minutes. You can confirm it’s loaded by checking:

crontab -l

And watch the logs:

tail -f /var/log/deploy.log

Want me to also set up a manual trigger alias (like update-site command) so you can force an update instantly without waiting for cron?


Ah, yes β€” the /load script idea πŸ”₯

Here’s how you can implement it step by step so each VM knows the cluster load and forwards new users to the least-loaded VM:


🟒 Step 1. Install tools for measuring load

On all 6 VMs:

sudo apt install -y jq curl

🟒 Step 2. Add a /load endpoint to each VM

We’ll use a small PHP script served by Nginx. Create the file:

sudo nano /var/www/cayana.me/load.php

Paste this:

<?php
// Basic load metric
$load = sys_getloadavg();  // 1, 5, 15 min load averages
$connections = (int) exec("netstat -an | grep ESTABLISHED | wc -l");

$data = [
    "vm" => gethostname(),
    "load1" => $load[0],
    "connections" => $connections,
    "timestamp" => time()
];

header('Content-Type: application/json');
echo json_encode($data);
?>

βœ… Now visiting http://<vm-ip>/load.php will return something like:

{
  "vm": "kitkat-vm",
  "load1": 0.42,
  "connections": 12,
  "timestamp": 1694567890
}

🟒 Step 3. Nginx /load proxy rule

If you prefer not to expose PHP, you can let Nginx serve /load as a reverse proxy, but for simplicity PHP is fine.


🟒 Step 4. Cluster β€œrouter” logic

Now modify each VM’s main Nginx site to have a small PHP front controller that:

  1. On each new request, it queries all 6 VMs’ /load.php.
  2. Chooses the VM with the lowest load.
  3. Redirects the user there (302).

Example:

<?php
$nodes = [
    "http://KITKAT_PUBLIC_IP/load.php",
    "http://DAIRYMILK_PUBLIC_IP/load.php",
    "http://EXOTICDARK_PUBLIC_IP/load.php",
    "http://10.1.0.5/load.php",   // Barone private IP
    "http://10.2.0.5/load.php",   // 5-Star private IP
    "http://10.3.0.5/load.php"    // Kisses private IP
];

$best = null;
$lowest = PHP_FLOAT_MAX;

foreach ($nodes as $url) {
    $resp = @file_get_contents($url);
    if ($resp) {
        $data = json_decode($resp, true);
        if ($data && $data['load1'] < $lowest) {
            $lowest = $data['load1'];
            $best = $url;
        }
    }
}

if ($best) {
    // Strip /load.php β†’ root of site
    $best = str_replace("/load.php", "/", $best);
    header("Location: $best");
    exit;
}

echo "All nodes unreachable. Please try later.";

Save as:

sudo nano /var/www/cayana.me/index.php

🟒 Step 5. Behavior

  • Cloudflare DNS β†’ RR to kitkat, dairymilk, exoticdark
  • User lands on one of those
  • That VM runs the script β†’ checks cluster load β†’ redirects new user to the least loaded VM (public or private)
  • Existing users stay where they landed (so sessions not broken)

🟒 Step 6. Improvements (later)

  • Cache results in /tmp/load.json for ~5s to avoid excessive inter-VM calls.
  • Use Nginx lua instead of PHP for lower latency.
  • Secure /load.php with a token so outsiders can’t scrape your VM load.

πŸ‘‰ Do you want me to make this transparent reverse-proxy (user doesn’t see redirect, VM internally forwards traffic), or keep the 302 redirect version (simpler but user’s URL changes)?


Would you prefer me to design the redirect-based model (302) first, or the transparent reverse-proxy model (user never leaves VM, but traffic is forwarded to least-loaded one)?

About

none

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages