Tuesday, June 16, 2026

Open port 8080 for WebSocket

 

To open port 8080 on an Apache2 server running on Ubuntu for WebSocket communication, you must configure Apache to listen on that port, enable the proxy tunnel modules, and allow the traffic through your system firewall. [1, 2, 3]
1. Enable Apache WebSocket Modules [1]
You must first enable the proxy and WebSocket tunnel modules so Apache can route connection upgrades. Run the following commands: [1]
bash
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_wstunnel
sudo a2enmod rewrite

2. Configure Apache to Listen on Port 8080 [1]
Tell Apache to actively monitor port 8080 alongside its default ports. [1, 2]
  1. Open the ports configuration file:
    bash
    sudo nano /etc/apache2/ports.conf
    

  2. Add Listen 8080 below the existing Listen 80 line:
    apache
    Listen 80
    Listen 8080
    

  3. Save and close the file (Ctrl+O, Enter, then Ctrl+X). [1, 2, 3, 4, 5]
3. Set Up the WebSocket Virtual Host [1]
Create or modify a virtual host configuration file to capture traffic on port 8080 and forward it to your local WebSocket application. [1, 2]
  1. Open your virtual host file (replace 000-default.conf with your actual site file if different):
    bash
    sudo nano /etc/apache2/sites-available/000-default.conf
    

  2. Append a new block at the bottom of the file. Change ws://127.0.0.1:9000 to the actual internal IP and port where your backend WebSocket application (e.g., Node.js, Python, or Ratchet) is listening:
    apache
    <VirtualHost *:8080>
        ServerName yourdomain.com
    
        ProxyRequests Off
        ProxyPreserveHost On
    
        # Proxy WebSocket connections to your backend app
        ProxyPass / ws://127.0.0.1:9000/
        ProxyPassReverse / ws://127.0.0.1:9000/
    </VirtualHost>
    

  3. Save and close the file. [1, 2, 3, 4, 5]
4. Open Port 8080 in the Ubuntu Firewall (UFW) [1]
By default, the Ubuntu firewall blocks outside connections to high ports. Use the Uncomplicated Firewall (UFW) to allow inbound TCP traffic: [1, 2, 3, 4, 5]
bash
sudo ufw allow 8080/tcp
sudo ufw reload

5. Restart Apache [1]
Apply all structural changes by restarting the Apache web service: [1, 2]
bash
sudo systemctl restart apache2

6. Verify the Port is Open [1]
Confirm that Apache is successfully binding to the port with netstat: [1, 2, 3]
bash
sudo netstat -tuln | grep 8080

Note: If your server is hosted on a cloud provider like AWS, Google Cloud, or Azure, you must also add an Inbound Security Rule in their web dashboard to let port 8080 traffic pass through their platform firewalls. [1, 2]

Sunday, June 7, 2026

Add websocket support on Bluehost Ubuntu VPS for Django App to talk to OpenAI voice API

tee /etc/systemd/system/uvicorn.service > /dev/null << 'EOF'

Install Claude Code on ubuntu VPS of Bluehost

Trying to install claude code on bluehost vps with "curl -fsSL https://claude.ai/install.sh | bash" freezed the machine. the curl -fsSL https://claude.ai/install.sh | bash script hanging or freezing the machine during the final stages of a Linux installation is a documented issue.

The script frequently hangs at the Finalizing installation... step. This is because the downloaded Claude binary executes an internal loop to automatically scan, detect, and rewrite shell files (like .bashrc or .zshrc) to insert itself into your system PATH. In restricted virtual private server (VPS) environments like Bluehost—where terminal TTY inputs, file locks, or strict security permissions block background configuration rewrites—this loop gets permanently stuck and consumes available server resources.


You can easily bypass the broken native script by using the traditional, highly reliable Node Package Manager (npm) installation path.

 

How to Install Claude Code Safely via npm

Because Bluehost VPS servers typically run standard Linux environments, installing via npm avoids the buggy shell-rewriting binary wrapper entirely. [1]

1. Install Node.js and npm (if not already present on your VPS): 

 sudo apt update && sudo apt install -y nodejs npm

2. Configure npm to install globally without root permissions (highly recommended to avoid EACCES security lockouts):

mkdir -p ~/.npm-global
npm config set prefix '~/.npm-global'
 

3. Manually add the new path to your profile file (manually doing what the frozen script failed to do):

echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
  

4. Install Claude Code via npm:

npm install -g @anthropic-ai/claude-code
 

5. Turn off the buggy auto-updater (the native background auto-updater can trigger the same system freeze later on):

echo 'export DISABLE_AUTOUPDATER=1' >> ~/.bashrc
source ~/.bashrc
 

6. Launch and authenticate:

claude
 

Saturday, June 6, 2026

Install PostgreSQL on Mac

Documentation: https://www.postgresql.org/docs/ 

Download: https://www.postgresql.org/download/ 

Installation log: 

$ brew install postgresql@18
✔︎ JSON API cask.jws.json                                                      Downloaded   16.9MB/ 16.9MB
✔︎ JSON API formula.jws.json                                                   Downloaded   33.2MB/ 33.2MB
Inspect the formula dependency plan before installing with `brew install --ask`.
Enable ask mode by setting `HOMEBREW_ASK=1`.
Hide these hints with `HOMEBREW_NO_ENV_HINTS=1` (see `man brew`).
==> Fetching downloads for: postgresql@18 
✔︎ Bottle Manifest postgresql@18 (18.4)                                        Downloaded   30.5KB/ 30.5KB
✔︎ Bottle ca-certificates (2026-05-14)                                         Downloaded  112.1KB/112.1KB
✔︎ Bottle Manifest openssl@3 (3.6.2)                                           Downloaded   12.0KB/ 12.0KB
✔︎ Bottle postgresql@18 (18.4)                                                 Downloaded   20.8MB/ 20.8MB
✔︎ Bottle openssl@3 (3.6.2)                                                    Downloaded   10.1MB/ 10.1MB
==> Installing dependencies for postgresql@18: ca-certificates and openssl@3
==> Installing postgresql@18 dependency: ca-certificates
==> Pouring ca-certificates--2026-05-14.all.bottle.tar.gz
==> Regenerating CA certificate bundle from keychain, this may take a while...
🍺  /usr/local/Cellar/ca-certificates/2026-05-14: 4 files, 200.9KB
==> Installing postgresql@18 dependency: openssl@3
==> Pouring openssl@3--3.6.2.tahoe.bottle.tar.gz
🍺  /usr/local/Cellar/openssl@3/3.6.2: 7,627 files, 38MB
==> Installing postgresql@18
==> Pouring postgresql@18--18.4.sonoma.bottle.1.tar.gz
==> /usr/local/Cellar/postgresql@18/18.4/bin/initdb --locale=en_US.UTF-8 -E UTF-8 /usr/local/var/postgres
==> Caveats
This formula has created a default database cluster with:
  initdb --locale=en_US.UTF-8 -E UTF-8 /usr/local/var/postgresql@18

When uninstalling, some dead symlinks are left behind so you may want to run:
  brew cleanup --prune-prefix

To start postgresql@18 now and restart at login:
  brew services start postgresql@18
Or, if you don't want/need a background service you can just run:
  LC_ALL="en_US.UTF-8" /usr/local/opt/postgresql@18/bin/postgres -D /usr/local/var/postgresql@18
==> Summary
🍺  /usr/local/Cellar/postgresql@18/18.4: 3,871 files, 74.1MB
==> Running `brew cleanup postgresql@18`...
Disable this behaviour by setting `HOMEBREW_NO_INSTALL_CLEANUP=1`.
Hide these hints with `HOMEBREW_NO_ENV_HINTS=1` (see `man brew`).
==> Caveats
==> postgresql@18
This formula has created a default database cluster with:
  initdb --locale=en_US.UTF-8 -E UTF-8 /usr/local/var/postgresql@18

When uninstalling, some dead symlinks are left behind so you may want to run:
  brew cleanup --prune-prefix

To start postgresql@18 now and restart at login:
  brew services start postgresql@18
Or, if you don't want/need a background service you can just run:
  LC_ALL="en_US.UTF-8" /usr/local/opt/postgresql@18/bin/postgres -D /usr/local/var/postgresql@18

 

Operations: 

  - show services installed via brew: brew services list 

  - start postgresql: brew services start postgresql@18
  - psql postgres
  - \?, \dt (show tables), \du (show users), \l (\list : show databases)
  - \c (\connect : connect to a database)
  - \dn : show schemas
  - \dt *.* : show tables in all schemas
  - select * from information_schema.sql_features;
  - CREATE TABLE users (
      id SERIAL PRIMARY KEY,
      name TEXT NOT NULL
    );
  - INSERT INTO users (name) VALUES ('Alice'), ('Bob'), ('Charlie');
  - select * from users;
  - \d users; (check table structure) 

Thursday, April 16, 2026

Card shuffling problem

A card shuffling algorithm is a method for randomly permuting a deck of cards so that every ordering is equally likely (in a “good” shuffle).

The most important and widely used algorithm is:

Fisher–Yates Shuffle (a.k.a. Knuth Shuffle)

This is the gold standard for unbiased shuffling.

Idea

You go through the deck from the last card to the first, and for each position, swap it with a randomly chosen earlier (or same) position.

Algorithm (array-based deck)

Let A be an array of n cards (array index: [0, ..., n-1]):

for i from n - 1 down to 1:
j = random integer such that 0 ≤ j ≤ i
swap A[i] and A[j]

Why it works

  • Each card has an equal probability of ending in any position.
  • It avoids subtle bias found in naive shuffles (like sorting with random comparator).

Complexity

  • Time: O(n)
  • Space: O(1) (in-place)

Variants you might see

1. Inside-out Fisher–Yates

Useful when building a shuffled array from scratch:

for i from 0 to n-1:
j = random integer in [0, i]
A[i] = A[j]
A[j] = current element

2. Riffle shuffle (card-deck realistic)

Models human shuffling:

  • Split deck into two halves
  • Interleave them probabilistically

Used in probability studies, but needs many repeats (~7 riffle shuffles) to approximate randomness.


Practical note

In most programming languages:

  • Use a built-in shuffle (e.g., random.shuffle in Python), which implements Fisher–Yates.


Blog Archive

Followers