# Putting MMS online so people in different locations can join

Right now the system runs at `http://localhost/mms/public/` — "localhost" means *this
computer*. Nobody outside your machine can reach it. This is a hosting step, not a code
change: the application already supports remote participants, it just needs to live
somewhere reachable.

There are three requirements for cross-location video calls, and all three matter:

| Requirement | Why | Without it |
|---|---|---|
| A public address (domain or IP) | So other people can open the page | Nobody can reach the site |
| HTTPS (SSL certificate) | Browsers block camera/mic on anything except HTTPS or localhost | Page loads, but camera never turns on |
| A TURN relay | Direct browser connections fail across many networks | Some people connect, others see a black tile forever |

Skipping the third is the most common mistake — it "works" in testing and then fails
unpredictably for real users on mobile data or office wifi.

---

## Option A — Test it online today (30 minutes, free)

Keeps the app on your XAMPP machine and opens a secure public tunnel to it. Good for
proving it works with a colleague in another town before you spend money on a server.

**Limitations, honestly:** your PC must stay powered on and connected; the free URL changes
every restart; and it is not suitable as a permanent deployment.

1. Download `cloudflared` for Windows:
   https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/

2. Start Apache in the XAMPP Control Panel as usual.

3. In PowerShell, run:
   ```
   cloudflared tunnel --url http://localhost/mms/public
   ```

4. It prints a public HTTPS address like `https://random-words-here.trycloudflare.com`.
   Share that with the other person. HTTPS is included, so the camera will work.

5. Both of you log in, open the same meeting, click **Join Video Call**.

If one of you connects but the other's tile stays black and says
*"Blocked by network — TURN relay needed"*, that is the TURN requirement biting. Go to
Option B and set up coturn.

---

## Option B — Proper deployment on a VPS (permanent)

This is the real answer, and matches how you deployed JSCITS.

### What you need
- A VPS running Ubuntu 22.04 — 2 vCPU / 4 GB RAM is comfortable. Hetzner, Contabo, and
  DigitalOcean are all fine; a local Ugandan provider will give lower latency for local users.
- A domain name pointed at the server's IP (an A record).
- About an hour.

### 1. Install the web stack
```bash
sudo apt update
sudo apt install -y apache2 php php-sqlite3 php-mbstring libapache2-mod-php unzip
sudo a2enmod rewrite
```

### 2. Upload the application
```bash
sudo mkdir -p /var/www/mms
# upload and unzip the project so that /var/www/mms/public/index.php exists
sudo chown -R www-data:www-data /var/www/mms
sudo chmod -R 775 /var/www/mms/database /var/www/mms/storage /var/www/mms/public/uploads
```

The `database`, `storage`, and `public/uploads` folders must be writable by the web server —
SQLite needs write access to the *folder*, not just the file, or you will get
"attempt to write a readonly database".

### 3. Configure Apache
Create `/etc/apache2/sites-available/mms.conf`:
```apache
<VirtualHost *:80>
    ServerName meetings.yourdomain.com
    DocumentRoot /var/www/mms/public

    <Directory /var/www/mms/public>
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/mms_error.log
</VirtualHost>
```
Then:
```bash
sudo a2ensite mms
sudo a2dissite 000-default
sudo systemctl reload apache2
```

Note `DocumentRoot` points at `public`, not the project root — everything else stays outside
the web root so the database cannot be downloaded.

### 4. Get HTTPS (required for camera access)
```bash
sudo apt install -y certbot python3-certbot-apache
sudo certbot --apache -d meetings.yourdomain.com
```
Certbot installs the certificate and sets up automatic renewal. After this the site is on
`https://` and browsers will permit camera and microphone.

Then open `config/config.php` and enable the secure session cookie — find this line in
`app/Core/Session.php` and uncomment it:
```php
// 'secure' => true, // enable when served over HTTPS
```

### 5. Install a TURN relay (coturn)
This is what makes calls work between people on genuinely different networks.

```bash
sudo apt install -y coturn
sudo nano /etc/turnserver.conf
```

Minimal working config — replace the domain and pick a long random secret:
```
listening-port=3478
fingerprint
lt-cred-mech
user=mmsuser:PUT_A_LONG_RANDOM_SECRET_HERE
realm=meetings.yourdomain.com
total-quota=100
no-tls
no-dtls
```

Enable and start it:
```bash
sudo sed -i 's/#TURNSERVER_ENABLED=1/TURNSERVER_ENABLED=1/' /etc/default/coturn
sudo systemctl enable --now coturn
```

Open the firewall:
```bash
sudo ufw allow 3478/tcp
sudo ufw allow 3478/udp
sudo ufw allow 49152:65535/udp
```

Finally, tell the application about it in `config/config.php`:
```php
define('TURN_URL',      'turn:meetings.yourdomain.com:3478');
define('TURN_USERNAME', 'mmsuser');
define('TURN_PASSWORD', 'PUT_A_LONG_RANDOM_SECRET_HERE');
```

**Bandwidth warning:** when TURN is used, that participant's video flows through your
server. A relayed call is roughly 1–2 Mbps per participant in each direction. If most of
your users are on difficult networks, watch your VPS bandwidth allowance.

### 6. Change the secrets before going live
In `config/config.php`:
```php
define('VIDEO_ROOM_SALT', 'a-new-random-string');
```
Generate one with: `php -r "echo bin2hex(random_bytes(16));"`

And log in to change the default `admin` password immediately.

---

## Why not just port-forward my home router?

You can try, but in Uganda most residential and mobile connections sit behind **CGNAT** —
your router does not have a real public IP, so port forwarding has nothing to forward to.
Test by comparing the WAN IP shown in your router against what https://ifconfig.me reports.
If they differ, port forwarding will not work and you need Option A or B.

---

## The group-size ceiling still applies

Deploying online does not change the architecture. Each browser sends its video to every
other participant, so:

- **2–4 people:** works well
- **5–6 people:** degrades noticeably
- **7+:** not viable

If you need large briefings, the media has to be routed by a dedicated server (an "SFU")
instead of peer-to-peer. Realistic paths:

- **LiveKit** (`livekit.io`) — open source, Docker install, scales to large rooms. The
  login, access control, room naming, and meeting records here would all stay; only the
  peer-connection code in `app/Views/meetings/video.php` gets replaced.
- **Self-hosted Jitsi Meet** — bundles its own SFU, handles big rooms out of the box, less
  work than LiveKit but less control over the interface.

Both are separate infrastructure projects in their own right, not configuration changes.
