# GYM Locker Management — Deployment Guide

This guide walks you through deploying the system on a VPS with GitHub Actions auto-deploy.
Every time you push code to the `main` branch, the server automatically updates itself.

---

## Overview

```
Your Computer → git push → GitHub → GitHub Actions → Your VPS Server
                              ↑                            ↓
                         (triggers CI/CD)        (pulls code, builds, restarts)
```

**What you need:**
- A VPS (DigitalOcean, Linode, Contabo, Hetzner — any Ubuntu 22.04 server)
- A domain name pointed to your server's IP
- Your code pushed to GitHub (github.com/kaziramjan/gym-locker-management)

---

## Part 1 — First-Time Server Setup

### 1.1 SSH into your server

```bash
ssh root@YOUR_SERVER_IP
```

### 1.2 Upload and run the setup script

From your **Mac terminal** (one-time only):

```bash
# Copy the deploy folder to your server
scp -r "deploy/" root@YOUR_SERVER_IP:/root/gymlocker-deploy/

# SSH in and run the script
ssh root@YOUR_SERVER_IP
cd /root/gymlocker-deploy
chmod +x server-setup.sh
./server-setup.sh
```

> The script will print MySQL credentials at the end. **Save them** — you need them for your `.env` file.

### 1.3 Edit the script variables first

Open `deploy/server-setup.sh` and change these two lines at the top:

```bash
DOMAIN="yourdomain.com"         # ← your real domain, e.g. gymlocker.com
API_DOMAIN="api.yourdomain.com" # ← e.g. api.gymlocker.com
```

---

## Part 2 — Clone the Repo onto Your Server

### 2.1 Generate a deploy SSH key (on the server)

```bash
# Switch to the deploy user
su - deploy

# Generate SSH key pair
ssh-keygen -t ed25519 -C "deploy@gymlocker" -f ~/.ssh/id_ed25519 -N ""

# Print the PUBLIC key (you'll add this to GitHub)
cat ~/.ssh/id_ed25519.pub
```

Copy the output (starts with `ssh-ed25519 ...`).

### 2.2 Add the deploy key to GitHub

1. Go to **github.com/kaziramjan/gym-locker-management**
2. Click **Settings → Deploy keys → Add deploy key**
3. Title: `VPS Deploy Key`
4. Key: paste the public key you copied
5. ✅ Check **Allow write access** → **Add key**

### 2.3 Clone the repository

```bash
# Still as the 'deploy' user on the server
git clone git@github.com:kaziramjan/gym-locker-management.git /var/www/gymlocker/repo

# Symlink or copy backend and frontend into the expected paths
cp -r /var/www/gymlocker/repo/backend/*  /var/www/gymlocker/backend/
cp -r /var/www/gymlocker/repo/frontend/* /var/www/gymlocker/frontend/

# OR — update the GitHub Secrets BACKEND_PATH and FRONTEND_PATH to point
# directly inside the cloned repo:
#   BACKEND_PATH = /var/www/gymlocker/repo/backend
#   FRONTEND_PATH = /var/www/gymlocker/repo/frontend   (for static files)
```

> **Easiest approach:** Set `BACKEND_PATH=/var/www/gymlocker/repo` and keep the
> whole repo there. The deploy script does `git pull` from that path.

---

## Part 3 — Configure Laravel on the Server

### 3.1 Create the `.env` file

```bash
cd /var/www/gymlocker/backend
cp .env.example .env
nano .env   # or: vim .env
```

Fill in these values (use the MySQL credentials from the setup script output):

```dotenv
APP_ENV=production
APP_DEBUG=false
APP_URL=https://api.yourdomain.com

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=gymlocker
DB_USERNAME=gymlocker
DB_PASSWORD=YOUR_GENERATED_PASSWORD

SANCTUM_STATEFUL_DOMAINS=yourdomain.com,www.yourdomain.com
SESSION_DOMAIN=.yourdomain.com
```

### 3.2 Run first-time setup

```bash
cd /var/www/gymlocker/backend

# Install PHP dependencies
composer install --no-dev --optimize-autoloader

# Generate app encryption key
php artisan key:generate

# Run migrations and seed initial data
php artisan migrate --seed

# Cache config for production
php artisan config:cache
php artisan route:cache
php artisan view:cache

# Create storage symlink
php artisan storage:link

# Fix permissions
sudo chown -R www-data:www-data storage bootstrap/cache
sudo chmod -R 775 storage bootstrap/cache
```

**Default admin login after seeding:**
- Email: `admin@gymlocker.com`
- Password: `Admin@1234`

---

## Part 4 — Point DNS to Your Server

In your domain registrar's DNS settings, add these **A records**:

| Type | Name | Value            | TTL |
|------|------|------------------|-----|
| A    | @    | YOUR_SERVER_IP   | 300 |
| A    | www  | YOUR_SERVER_IP   | 300 |
| A    | api  | YOUR_SERVER_IP   | 300 |

Wait for DNS to propagate (usually 5–30 minutes). Check with:

```bash
ping yourdomain.com
ping api.yourdomain.com
```

---

## Part 5 — Enable SSL (HTTPS)

Once DNS is pointing to your server:

```bash
# On the server as root
certbot --nginx -d yourdomain.com -d www.yourdomain.com -d api.yourdomain.com
```

Follow the prompts. Certbot will automatically:
- Get SSL certificates from Let's Encrypt
- Update your Nginx config to use HTTPS
- Set up auto-renewal (cron job)

Test auto-renewal:

```bash
certbot renew --dry-run
```

---

## Part 6 — Add GitHub Secrets

These secrets are used by the GitHub Actions auto-deploy workflow.

Go to: **github.com/kaziramjan/gym-locker-management → Settings → Secrets and variables → Actions → New repository secret**

Add all of these:

| Secret Name     | Value                                    | Example                              |
|-----------------|------------------------------------------|--------------------------------------|
| `VPS_HOST`      | Your server's IP address                 | `123.45.67.89`                       |
| `VPS_USER`      | Linux user to SSH as                     | `deploy`                             |
| `VPS_SSH_KEY`   | **Private** SSH key of the deploy user   | (contents of `~/.ssh/id_ed25519`)    |
| `VPS_PORT`      | SSH port (usually 22)                    | `22`                                 |
| `BACKEND_PATH`  | Absolute path to backend on server       | `/var/www/gymlocker/repo`            |
| `FRONTEND_PATH` | Absolute path where frontend files go    | `/var/www/gymlocker/frontend`        |
| `VITE_API_URL`  | Full URL of your Laravel API             | `https://api.yourdomain.com`         |

### How to get the private SSH key

```bash
# On the server, as the deploy user
su - deploy
cat ~/.ssh/id_ed25519
```

Copy the **entire output** including the `-----BEGIN OPENSSH PRIVATE KEY-----` and `-----END OPENSSH PRIVATE KEY-----` lines, and paste it as the value for `VPS_SSH_KEY`.

---

## Part 7 — Trigger the First Auto-Deploy

After GitHub Secrets are set, push any small change to `main`:

```bash
# On your Mac
cd "Locker Management For GYM"
git add .
git commit -m "chore: trigger first auto-deploy"
git push origin main
```

Then watch the deployment:

1. Go to **github.com/kaziramjan/gym-locker-management → Actions**
2. Click the running workflow
3. Watch each job: **Deploy Laravel Backend** → **Build & Deploy React Frontend** → **Deployment Status**

A green ✅ means everything deployed successfully.

---

## Part 8 — Daily Development Workflow

After everything is set up, your normal workflow is:

```bash
# Make changes locally
# ... edit files ...

# Push to GitHub
git add .
git commit -m "feat: add expiry reminder feature"
git push origin main

# GitHub Actions automatically:
#   1. SSHes into your server
#   2. git pull origin main
#   3. composer install (backend)
#   4. php artisan migrate --force
#   5. php artisan config:cache + route:cache
#   6. Restarts PHP-FPM
#   7. npm ci + npm run build (frontend)
#   8. Copies new frontend files to the server
```

Your live site is updated within **2–3 minutes** of your push. Zero manual steps.

---

## Troubleshooting

### Deployment failed — how to check logs

```bash
# Check the GitHub Actions logs first (most detailed)
# github.com/kaziramjan/gym-locker-management → Actions → click the failed run

# On the server — check Nginx error log
tail -50 /var/log/nginx/gymlocker-api-error.log

# Check Laravel log
tail -50 /var/www/gymlocker/backend/storage/logs/laravel.log

# Check PHP-FPM
sudo systemctl status php8.2-fpm
```

### 502 Bad Gateway

PHP-FPM is not running. Fix:

```bash
sudo systemctl restart php8.2-fpm
sudo systemctl status php8.2-fpm
```

### Permission errors on storage/

```bash
cd /var/www/gymlocker/backend
sudo chown -R www-data:www-data storage bootstrap/cache
sudo chmod -R 775 storage bootstrap/cache
```

### API returns 500 errors after deploy

Check if the `.env` file exists (it's gitignored, so it won't be overwritten by git pull — that's correct):

```bash
ls -la /var/www/gymlocker/backend/.env
```

If missing, re-create it from `.env.example` and fill in the values.

### React app shows blank page after deploy

The new frontend files weren't copied. Check the GitHub Actions SCP step. Also verify:

```bash
ls -la /var/www/gymlocker/frontend/
# Should contain: index.html, assets/
```

### SSL certificate expired

Certbot auto-renews, but if it failed:

```bash
certbot renew
sudo systemctl reload nginx
```

---

## Server Reference

| Item           | Value                                    |
|----------------|------------------------------------------|
| Backend path   | `/var/www/gymlocker/backend`             |
| Frontend path  | `/var/www/gymlocker/frontend`            |
| Nginx config   | `/etc/nginx/sites-available/gymlocker`   |
| PHP-FPM config | `/etc/php/8.2/fpm/php.ini`              |
| Laravel log    | `backend/storage/logs/laravel.log`       |
| Nginx log      | `/var/log/nginx/gymlocker-api-error.log` |
| SSL certs      | `/etc/letsencrypt/live/yourdomain.com/`  |

---

## Quick Command Reference

```bash
# Restart services
sudo systemctl restart nginx
sudo systemctl restart php8.2-fpm

# Check service status
sudo systemctl status nginx
sudo systemctl status php8.2-fpm
sudo systemctl status mysql

# Manual deploy (if GitHub Actions fails)
cd /var/www/gymlocker/backend
git pull origin main
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan config:cache && php artisan route:cache && php artisan view:cache
sudo systemctl restart php8.2-fpm

# View live logs
tail -f /var/www/gymlocker/backend/storage/logs/laravel.log
```
