# Yories Website — Ubuntu Server Deployment

Step-by-step guide to host this Next.js app on an Ubuntu server (22.04 / 24.04 LTS) using **Node.js + PM2 + Nginx + Let's Encrypt SSL**.

Tested target: a fresh Ubuntu VPS (DigitalOcean / Hetzner / AWS Lightsail / EC2) with a public IP and a domain (e.g. `yoriesgames.com`) pointing at it.

---

## 0. Before you start

You need:

- An Ubuntu 22.04 or 24.04 server with `sudo` access.
- A domain name with **A records** pointed at the server's public IP
  (e.g. `yoriesgames.com` → `203.0.113.10` and `www.yoriesgames.com` → `203.0.113.10`).
- A **MongoDB Atlas** connection string (or any reachable MongoDB instance).
- SSH access to the server.

---

## 1. Connect to the server and update

```bash
ssh root@YOUR_SERVER_IP
# or: ssh ubuntu@YOUR_SERVER_IP

apt update && apt upgrade -y
```

Create a non-root user (recommended) and use it for the rest of the steps:

```bash
adduser deploy
usermod -aG sudo deploy
su - deploy
```

---

## 2. Install Node.js 20 LTS

The app targets Next.js 14 — use Node 20 LTS.

```bash
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

node -v   # should print v20.x.x
npm -v
```

---

## 3. Install Git, Nginx, PM2

```bash
sudo apt install -y git nginx
sudo npm install -g pm2
```

---

## 4. Get the code onto the server

### Option A — Clone from GitHub (recommended)

```bash
cd ~
git clone https://github.com/<your-org>/yories-website.git
cd yories-website
```

### Option B — Upload via SCP from your laptop

From your Mac, in the project folder:

```bash
rsync -avz --exclude node_modules --exclude .next --exclude .git \
  ./ deploy@YOUR_SERVER_IP:/home/deploy/yories-website/
```

Then on the server:

```bash
cd ~/yories-website
```

---

## 5. Configure environment variables

```bash
cp .env.local.example .env.local
nano .env.local
```

Fill in real values:

```
MONGODB_URI=mongodb+srv://USER:PASSWORD@cluster.xxxxx.mongodb.net/yories?retryWrites=true&w=majority
ADMIN_JWT_SECRET=<paste output of: openssl rand -hex 32>
ADMIN_BOOTSTRAP_EMAIL=admin@yoriesgames.com
ADMIN_BOOTSTRAP_PASSWORD=<a strong password>
NEXT_PUBLIC_SITE_NAME=Yories Games
NEXT_PUBLIC_SITE_URL=https://yoriesgames.com
```

Generate a secret quickly:

```bash
openssl rand -hex 32
```

**MongoDB Atlas:** in Atlas → Network Access, add the server's public IP to the allow-list (or `0.0.0.0/0` for testing).

---

## 6. Install dependencies and build

```bash
npm ci          # clean install from package-lock.json
npm run build   # produces .next/ production bundle
```

If `npm ci` runs out of memory on a small VPS (1 GB RAM), add swap:

```bash
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
```

---

## 7. Bootstrap the admin user and seed games (one-time)

```bash
npm run create-admin   # creates admin from ADMIN_BOOTSTRAP_* in .env.local
npm run seed           # scrapes yoriesgames.com and loads MongoDB
```

Re-running `seed` updates existing games (matched by slug) — safe to re-run.

---

## 8. Start the app with PM2

```bash
pm2 start npm --name yories -- start
pm2 save
pm2 startup systemd   # follow the printed command (sudo env PATH=... pm2 startup ...)
```

The app now listens on `http://127.0.0.1:3806`.

Useful PM2 commands:

```bash
pm2 status
pm2 logs yories
pm2 restart yories
pm2 stop yories
```

---

## 9. Configure Nginx as a reverse proxy

Create the site config:

```bash
sudo nano /etc/nginx/sites-available/yories
```

Paste (replace `yoriesgames.com` with your domain):

```nginx
server {
    listen 80;
    listen [::]:80;
    server_name yoriesgames.com www.yoriesgames.com;

    client_max_body_size 20M;

    location / {
        proxy_pass http://127.0.0.1:3806;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
        proxy_read_timeout 60s;
    }
}
```

Enable it and reload Nginx:

```bash
sudo ln -s /etc/nginx/sites-available/yories /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default   # optional: remove default site
sudo nginx -t
sudo systemctl reload nginx
```

Hit `http://yoriesgames.com` — the site should load.

---

## 10. Firewall (UFW)

```bash
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status
```

---

## 11. SSL with Let's Encrypt

```bash
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d yoriesgames.com -d www.yoriesgames.com
```

Pick "redirect HTTP to HTTPS" when prompted. Certbot auto-installs a cron/timer for renewals — verify with:

```bash
sudo systemctl status certbot.timer
sudo certbot renew --dry-run
```

The site is now live on `https://yoriesgames.com`.

---

## 12. Updating / redeploying

After pushing new code:

```bash
cd ~/yories-website
git pull
npm ci
npm run build
pm2 restart yories
```

(If you uploaded via rsync instead of git, re-run the rsync command from step 4B, then the `npm ci && npm run build && pm2 restart yories` part.)

---

## 13. Troubleshooting

| Symptom | Check |
|---|---|
| `502 Bad Gateway` from Nginx | `pm2 status` — is `yories` online? `pm2 logs yories` |
| App can't reach MongoDB | Atlas Network Access allow-list contains server IP |
| Build killed (OOM) | Add swap (see step 6) |
| Changes don't appear | `pm2 restart yories`; game pages revalidate every 60s |
| Admin login redirects in a loop | `ADMIN_JWT_SECRET` changed after login — clear cookies |
| Port 3806 already in use | `sudo lsof -i :3806` then `pm2 delete <name>` the stale process |

Logs to check:

```bash
pm2 logs yories --lines 200
sudo tail -f /var/log/nginx/error.log
sudo tail -f /var/log/nginx/access.log
```

---

## 14. Optional: run on a different port

If you need to run on a port other than 3806, edit the PM2 start command:

```bash
pm2 delete yories
PORT=4000 pm2 start npm --name yories -- start
pm2 save
```

Then update the `proxy_pass` line in the Nginx config to match (`http://127.0.0.1:4000;`) and `sudo systemctl reload nginx`.

---

## Quick reference

```bash
# status
pm2 status
sudo systemctl status nginx

# restart app after code change
cd ~/yories-website && git pull && npm ci && npm run build && pm2 restart yories

# reload nginx after config change
sudo nginx -t && sudo systemctl reload nginx

# renew ssl manually
sudo certbot renew
```
