# Deploying to https://vault.b2of.com

This guide is for a Linux server with Nginx or Apache, PHP 8.2+, MySQL/MariaDB, and SSH access.
Shared hosting (cPanel) notes are at the end.

## 0. Requirements

- **PHP 8.2 or newer**, with these extensions:
  `mbstring`, `xml`, `dom`, `zip`, `gd`, `fileinfo`, `ctype`, `tokenizer`, `curl`, `openssl`, `pdo_mysql`.
  On Ubuntu:
  ```bash
  sudo apt install php8.2-fpm php8.2-{mbstring,xml,zip,gd,curl,mysql}
  ```
- **MySQL 5.7+ or MariaDB 10.3+.** The database is called `eduvault`, and it holds
  the game data, sessions and cache.
- **Composer**, only if you deploy from git. The release zip already includes `vendor/`.

## 1. DNS

Add an **A record** for `vault` in the `b2of.com` zone, pointing to the server's IP.

## 2. Get the code onto the server

**Option A: from GitHub**
```bash
cd /var/www
git clone https://github.com/tamilqs/vault.git vault
cd vault
composer install --no-dev --optimize-autoloader
```

**Option B: the release zip** (built on this PC)
```bash
php deploy/build-release.php              # app only
php deploy/build-release.php --with-data  # + current teams & batch assignments
```
Upload `dist/vault-release-*.zip` and unzip it into `/var/www/vault`.

## 3. Database

Create the database and a user for it (MySQL shell, or **MySQL Databases** in cPanel):
```sql
CREATE DATABASE eduvault CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'eduvault'@'localhost' IDENTIFIED BY 'a-strong-password';
GRANT ALL PRIVILEGES ON eduvault.* TO 'eduvault'@'localhost';
```

## 4. Configure

```bash
cd /var/www/vault
cp deploy/env.production.example .env
nano .env                       # set DB_PASSWORD and VAULT_ADMIN_PASSWORD (long secrets!)
php artisan key:generate
php artisan migrate --force     # creates the tables
php artisan optimize            # caches config, routes and views
```

Keep `APP_DEBUG=false` in production.

## 5. Permissions

The web server must be able to write to `storage/` and `bootstrap/cache/`:
```bash
sudo chown -R www-data:www-data storage bootstrap/cache
sudo chmod -R ug+rwX storage bootstrap/cache
```

## 6. Web server

The web root **must** be the `public/` folder. If it points at the app root, the
`.env` file and `data.json` (which holds the passcodes) become downloadable.

- **Nginx:** use `deploy/nginx-vault.b2of.com.conf`.
- **Apache:** use `deploy/apache-vault.b2of.com.conf`.

Then turn on HTTPS:
```bash
sudo certbot --nginx -d vault.b2of.com     # or: --apache
```

## 7. Teams and data

- **Release zip built with `--with-data`:** load its teams and batches into MySQL:
  ```bash
  php artisan vault:import-json      # reads storage/app/vault/data.json
  ```
- **Otherwise:** log in to `https://vault.b2of.com/admin` and import the CSV.
- **Back up the game:** use either of these.
  ```bash
  php artisan vault:export-json      # writes storage/app/vault/backup-<time>.json
  mysqldump eduvault > eduvault.sql
  ```

## 8. Check it

| Page | URL |
|---|---|
| Vault (teams) | https://vault.b2of.com/ |
| Leaderboard | https://vault.b2of.com/leaderboard |
| Control room | https://vault.b2of.com/admin |
| Health check (should return 200) | https://vault.b2of.com/up |

## Updating later

```bash
cd /var/www/vault
git pull
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan optimize
```

The game data lives in MySQL, so updating the code never touches it.

## Shared hosting (cPanel)

1. Upload the release zip and extract it, for example into `~/vault`.
2. In **Domains**, set the document root of `vault.b2of.com` to `~/vault/public`.
3. In **MySQL Databases**, create the `eduvault` database and a user with all privileges on it.
   cPanel adds a prefix (for example `b2of_eduvault`), so use the full names in `.env`.
4. Copy `deploy/env.production.example` to `.env`, then set the DB details, the admin password and `APP_KEY`.
   If you have no SSH, generate the key on this PC with `php artisan key:generate --show`
   and paste it into `.env`.
5. Create the tables. With SSH (or cPanel's **Terminal**), run `php artisan migrate --force`.
   Without either, run `php artisan migrate --pretend` on this PC to see the SQL, then
   paste it into phpMyAdmin.
6. **If the site must be served from `public_html`:** keep the app in `~/vault` and copy
   the *contents* of `~/vault/public` into `~/public_html`. Then edit
   `~/public_html/index.php` and replace both `__DIR__.'/../` paths with the app folder:
   ```php
   require '/home/YOURUSER/vault/vendor/autoload.php';
   $app = require_once '/home/YOURUSER/vault/bootstrap/app.php';
   ```
   Nothing in the app uses `public_path()`. Pages load their files with `asset()`, and the
   exports read the logo from `resources/brand/`, so this layout works as-is. After changing
   CSS or JS, raise `VAULT_ASSET_VERSION` in `.env` so browsers fetch the new files.
7. **If you can't change the document root:** copy `deploy/root.htaccess` to `~/vault/.htaccess`.
   It forwards requests into `public/` and blocks the private files.

## Troubleshooting

**`file_put_contents(D:\vault\storage\...)`, or any other `D:\vault` path, in an error**
The server is using a config cache built on the Windows PC. This happens when the
project folder is copied over directly. Fix it on the server:
```bash
rm -f bootstrap/cache/config.php bootstrap/cache/events.php bootstrap/cache/routes-v7.php
php artisan optimize
```
Also make sure `.env` comes from `deploy/env.production.example`, not from the PC.
Upload from GitHub or the release zip, which never include these files.

**`SQLSTATE[HY000] [1045] Access denied` or `[2002] Connection refused`**
The `DB_*` values in `.env` don't match the server's MySQL. On cPanel, the names
carry a prefix (`b2of_eduvault`). After fixing `.env`, run `php artisan optimize` again.

**`Base table or view not found: vault_teams`**
The tables haven't been created yet: run `php artisan migrate --force`.

**"Permission denied" in `storage/`**
```bash
sudo chown -R www-data:www-data storage bootstrap/cache
```
