# Honey VPS Setup from Scratch (Inferno)

This guide walks through setting up a new VPS for the **Honey** app with the same layout as your existing lottery VPS: backend + MySQL + phpMyAdmin in Docker, frontend and admin panel served by Nginx, logging under `/opt/app/logs`, secrets in `/run/secrets`, and MySQL backups to a backup VPS.

**Target layout (mirrors your lottery setup):**

- **Containers:** backend (honey-be), MySQL (honey_db), phpMyAdmin
- **Served by Nginx:** frontend (honey-fe), admin panel (honey-admin)
- **Paths:** `/opt/app` for app files, `/run/secrets` for config, `/opt/app/logs` for logs
- **Nginx:** main config + site config (e.g. `nginx.conf` + `sites-enabled/your-domain`)

---

## 1. VPS basics

### 1.1 System update and installs

```bash
sudo apt update && sudo apt upgrade -y
```

```bash
# Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER

# Docker Compose (plugin)
sudo apt-get update
sudo apt-get install -y docker-compose-plugin

# Nginx + Certbot
sudo apt install -y nginx certbot python3-certbot-nginx
```

Log out and back in so `docker` group applies.

### 1.2 Directory structure under `/opt/app`

Create the same layout as lottery (backend, frontend, admin, nginx, data, logs, backups, mysql):

```bash
sudo mkdir -p /opt/app/backend
sudo mkdir -p /opt/app/frontend
sudo mkdir -p /opt/app/admin
sudo mkdir -p /opt/app/admin-panel
sudo mkdir -p /opt/app/nginx
sudo mkdir -p /opt/app/data/avatars
sudo mkdir -p /opt/app/logs
sudo mkdir -p /opt/app/backups
sudo mkdir -p /opt/app/mysql/data
sudo mkdir -p /opt/app/mysql/conf

sudo chown -R $USER:$USER /opt/app
sudo chmod -R 755 /opt/app
```

### 1.3 Git

```bash
sudo apt install git -y
git config --global alias.st status
ssh-keygen -t ed25519 -C "your_email@example.com" (replace email)
cat ~/.ssh/id_ed25519.pub (copy the key and add to origin)

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up (and login in local browser to tailscale)
```

Clone all repositories to respective folders.

---

## 2. Backend (honey-be) on VPS

### 2.1 Secret file (honey-config.properties)

Backend reads **`/run/secrets/honey-config.properties`** (see `ConfigLoader` and `docker-compose.prod.yml`). Create it from the template; **do not commit real values**.

On the VPS:

```bash
sudo mkdir -p /run/secrets
sudo cp /opt/app/backend/honey-be/honey-config.properties.template /run/secrets/honey-config.properties
sudo chmod 640 /run/secrets/honey-config.properties
sudo chown root:docker /run/secrets/honey-config.properties   # if your user is in docker group, or root:$USER
```

Edit and set real values:

```bash
sudo nano /run/secrets/honey-config.properties
```

Notes:

- `SPRING_DATASOURCE_URL` - set to new DB URL
- `SPRING_DATASOURCE_PASSWORD` - just generate new secret
- `TELEGRAM_BOT_TOKEN` - token for Telegram bot
- `FRONTEND_URL` - put new domain here
- `APP_ADMIN_JWT_SECRET` - generate new secret using `openssl rand -base64 48` on VPS and put here
- `APP_TELEGRAM_WEBHOOK_TOKEN` - generate a new secret and set it using `POST https://api.telegram.org/bot<token>/setWebhook?url=https://<domain>/api/telegram/webhook/<secret>&max_connections=100` 
- `PMA_ABSOLUTE_URI` - generate a new secret and set it. Don't forget to set the same to nginx

Create 2 files `admin_api_url` and `admin_base_path` with URL and secret path in `/run/secrets` folder.

### 2.3 Load DB password for Docker Compose

`docker-compose.prod.yml` expects `DB_ROOT_PASSWORD` (and MySQL healthcheck uses it). The repo has `scripts/load-db-password.sh` which reads the secret file; it’s currently wired to **lottery** path. For Honey, either:

- Edit `scripts/load-db-password.sh` and set:
  - `SECRET_FILE="/run/secrets/honey-config.properties"`
- Or create a small wrapper that exports the same variables from `honey-config.properties`.

**When you need to source it:** Only for one-off manual `docker compose` runs (e.g. first-time start in §2.6, or starting phpMyAdmin in §4.1). You do **not** need to source it for deployment: `scripts/rolling-update.sh` loads the password from the secret file automatically when `DB_ROOT_PASSWORD` is not set.

**IMPORTANT**
- `Change Java memory in docker-compose.prod.yml when you know the PROD VPS characteristics.`
- `Change the rolling-update.sh script to match sites-enabled nginx file name for PROD when you know the domain`
### 2.4 Logging (logback) and config dir

Backend uses an external **logback** config so you can change log level without rebuilding. Create the config dir and put `logback-spring.xml` there:

```bash
mkdir -p /opt/app/backend/config
mkdir -p /opt/app/logs
```

Either copy from the JAR or from source:

```bash
# From backend dir
cp src/main/resources/logback-spring.xml /opt/app/backend/config/
# or extract from built JAR:
# unzip -p target/honey-be-*.jar BOOT-INF/classes/logback-spring.xml > /opt/app/backend/config/logback-spring.xml
```

Optional: run the existing setup script (it may still reference lottery paths; adjust or run the copy above):

```bash
cd /opt/app/backend/honey-be
./scripts/setup-logging.sh
```

Edit log level at any time:

```bash
nano /opt/app/backend/config/logback-spring.xml
# e.g. change <logger name="com.honey" level="INFO"/> to DEBUG
# Logback rescans periodically (e.g. 30s); no restart needed if scan is enabled
```

### 2.5 MySQL my.cnf (optional)

If you use a custom MySQL config in prod (e.g. for buffer pool):

```bash
# Create /opt/app/mysql/conf/my.cnf with your tuning; then in docker-compose.prod.yml
# the volume is already: /opt/app/mysql/conf/my.cnf:/etc/mysql/conf.d/my.cnf:ro
```

Note: `on Staged VPS it has 4G RAM, so don't forget to change it for PROD accordingly.`

### 2.6 First start (backend + DB only)

```bash
cd /opt/app/backend/honey-be
source scripts/load-db-password.sh
docker compose -f docker-compose.prod.yml up -d db
# wait for DB healthy
docker compose -f docker-compose.prod.yml up -d backend
```

Note: `for Staged use a separate docker compose.`

Check:

```bash
docker ps
curl -s http://127.0.0.1:8080/actuator/health/readiness
```

Backend should listen only on `127.0.0.1:8080` (Nginx will proxy to it). Do **not** expose 8080 to the internet.

---

## 3. Nginx

### 3.1 Split config (like your lottery VPS)

- `Take 2 files from already working VPS: nginx.conf and sites-enabled/<domain.com> and put to new VPS.`
- `Remove or comment lines reg certificates and change 2 listen lines`: 

```bash
    # SSL Certificates
    ssl_certificate /etc/letsencrypt/live/testforapp.website/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/testforapp.website/privkey.pem;
    Change 'listen 443 ssl http2;' to 'listen 443;`
    Change `listen [::]:443 ssl http2;` to `listen [::]:443;`
```
Enable and test:

```bash
sudo ln -s /etc/nginx/sites-available/testforapp.website /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
```

### 3.3 SSL (Let’s Encrypt)

```bash
sudo certbot --nginx -d testforapp.website
```

Certbot will adjust the server block for certificates. Reload Nginx if needed.
And remove redundant ssl/listen lines from server block to not override certbot's configs.

---

## 4. phpMyAdmin

### 4.1 Start phpMyAdmin container

`docker-compose.prod.yml` already defines a **phpmyadmin** service (port 8081, same network as `db`). Start it:

```bash
cd /opt/app/backend/honey-be
source scripts/load-db-password.sh
docker compose -f docker-compose.prod.yml up -d phpmyadmin
```

### 4.2 Access via Nginx (recommended)

Do **not** expose 8081 publicly. Proxy it via Nginx under a secret path (e.g. `/your-secret-pma-path/`), as in the example above. Set `PMA_ABSOLUTE_URI` in the secret file so phpMyAdmin generates correct URLs:

In `/run/secrets/honey-config.properties` add (or use env when running compose):

```properties
PMA_ABSOLUTE_URI=https://your-domain.com/your-secret-pma-path/
```

Then reload Nginx and open `https://your-domain.com/your-secret-pma-path/`. Login: user `root`, password = `SPRING_DATASOURCE_PASSWORD` from the same secret file.

### 4.3 Optional: UFW for phpMyAdmin

If you ever expose 8081 temporarily, restrict it:

```bash
sudo ufw allow from YOUR_IP to any port 8081
sudo ufw reload
```

Prefer keeping 8081 bound to 127.0.0.1 and using only Nginx proxy.

---

## 5. Frontend (honey-fe)

### 5.1 Build locally and upload

On your machine (e.g. in `honey-test-fe` or your honey-fe repo):

```bash
cd honey-test-fe   # or honey-fe
npm install
npm run build
scp -r dist/* root@YOUR_VPS_IP:/opt/app/frontend/dist/
```

Or with rsync:

```bash
rsync -avz dist/ root@YOUR_VPS_IP:/opt/app/frontend/dist/
```

Ensure the app’s API base URL is correct for production (e.g. relative `""` or `VITE_API_BASE_URL` for your domain).

---

## 6. Admin panel (honey-admin)

### 6.1 Build with secret (on VPS or locally)

Admin often has a build that injects a public URL or env. From the repo:

```bash
cd honey-admin
npm install
npm run build:with-secret
```

Then copy the built output to the Nginx admin root:

**If you build on the VPS:**

```bash
cd /opt/app/admin/honey-admin
npm run build:with-secret
cp -r dist/* /opt/app/admin-panel/
```

**If you build locally:**

```bash
scp -r dist/* root@YOUR_VPS_IP:/opt/app/admin-panel/
```

The Nginx location for admin (e.g. `/your-secret-admin-path/`) must serve this directory and support SPA routing (`try_files` to `index.html`).

---

## 7. Rolling backend updates

Use the existing **rolling-update** script so Nginx switches to a new backend container with no downtime.

### 7.1 Script adaptation for Honey

The script in the repo may still reference **lottery** container names and Nginx paths. For Honey:

- **Containers:** `honey-backend` (primary), `honey-backend-new` (standby).
- **Nginx:** same idea as lottery: one upstream `backend` with `server 127.0.0.1:8080` and optionally `server 127.0.0.1:8082 backup;`. The script flips which port is primary.

Edit `scripts/rolling-update.sh` and replace:

- `lottery-backend` → `honey-backend`
- `lottery-backend-new` → `honey-backend-new`

The script auto-detects Nginx config from paths like `/etc/nginx/sites-enabled/win-spin.live`. For Honey, either:

- Symlink or name your site config so the script finds it (e.g. add a similar check for `honey.conf` in the script), or  
- Set the path explicitly before running: `export NGINX_CONF=/etc/nginx/sites-enabled/your-domain && sudo ./scripts/rolling-update.sh`

### 7.2 Run rolling update

From the backend directory, run (no need to source `load-db-password.sh` — the script does it):

```bash
cd /opt/app/backend/honey-be
chmod +x scripts/rolling-update.sh
sudo ./scripts/rolling-update.sh
```

The script loads `DB_ROOT_PASSWORD` from the secret file if not set, then: builds the new image, starts `backend-new` on 8082, health-checks it, points Nginx to 8082, reloads Nginx, then stops the old backend.

---

## 8. Logging

- **App logs:** `/opt/app/logs/` (mounted into backend container; path can be set via `LOG_DIR` / logback).
- **Config:** `/opt/app/backend/config/logback-spring.xml` (edit to change level; no restart if scan is enabled).
- **Nginx:** `/var/log/nginx/access.log`, `/var/log/nginx/error.log`.

View backend logs:

```bash
docker logs -f honey-backend
# or
tail -f /opt/app/logs/honey-be.log
```

---

## 9. MySQL backups to backup VPS

### 9.1 Backup script for Honey

Copy and adapt the existing **`scripts/backup-database.sh`** (or create a Honey-specific one). Set:

- `MYSQL_CONTAINER="honey-mysql"`
- `MYSQL_DATABASE="honey_db"`
- `SECRET_FILE="/run/secrets/honey-config.properties"`
- `BACKUP_FILENAME="honey_db_backup_${TIMESTAMP}.sql"` (and `.gz` if compressing)
- Remote path and retention (e.g. `BACKUP_VPS_PATH`, keep last 30 days) to match your backup server.

Ensure the script runs as root (or with sudo) so it can read `/run/secrets/honey-config.properties`, and that it uses the same `DB_PASSWORD` / `SPRING_DATASOURCE_PASSWORD` as in the secret file.

### 9.2 SSH key to backup VPS

On the Honey VPS:

```bash
ssh-keygen -t ed25519 -C "backup@honey-vps" -f ~/.ssh/backup_key
ssh-copy-id -i ~/.ssh/backup_key.pub user@BACKUP_VPS_IP
```

Test:

```bash
ssh -i ~/.ssh/backup_key user@BACKUP_VPS_IP "echo OK"
```

### 9.3 Cron (daily at 2 AM)

```bash
sudo crontab -e
```

Add:

```cron
0 2 * * * /opt/app/backend/honey-be/scripts/backup-database.sh >> /opt/app/logs/backup.log 2>&1
```

Use the Honey-adapted backup script path and ensure `backup-database.sh` uses `honey_db` and `honey-mysql`.

---

## 10. Quick reference

| Item | Honey                                                           |
|------|-----------------------------------------------------------------|
| **App root** | `/opt/app`                                                      |
| **Backend code** | `/opt/app/backend/honey-be` (honey-be)                          |
| **Frontend static** | `/opt/app/frontend/dist` (honey-fe build)                       |
| **Admin static** | `/opt/app/admin-panel` (honey-admin build)                      |
| **Secret file** | `/run/secrets/honey-config.properties`                          |
| **Logs** | `/opt/app/logs` (+ logback config in `/opt/app/backend/config`) |
| **Avatars** | `/opt/app/data/avatars`                                         |
| **Nginx** | `/etc/nginx/nginx.conf` + `/etc/nginx/sites-enabled/your-domain` |
| **DB container** | `honey-mysql`                                                   |
| **DB name** | `honey_db`                                                      |
| **Backend containers** | `honey-backend`, `honey-backend-new` (rolling)                  |
| **phpMyAdmin** | Container `honey-phpmyadmin`, port 8081 → proxy via Nginx secret path |

### Deploy commands (summary)

- **Backend (rolling):**  
  `cd /opt/app/backend/honey-be && chmod +x scripts/rolling-update.sh && sudo ./scripts/rolling-update.sh`  
  (Password is loaded from the secret file inside the script.)

- **Frontend:**  
  Local: `npm run build` then `scp -r dist/* root@VPS:/opt/app/frontend/dist/`

- **Admin:**  
  On VPS: `cd /opt/app/admin/honey-admin && npm run build:with-secret && cp -r dist/* /opt/app/admin-panel/`  
  Or build locally and `scp -r dist/* root@VPS:/opt/app/admin-panel/`

- **Log level:**  
  Edit `/opt/app/backend/config/logback-spring.xml` (no restart if scan enabled).

---

## 11. Checklist after setup

- [ ] `/opt/app` structure created; ownership and permissions correct.
- [ ] `/run/secrets/honey-config.properties` created and filled (no placeholders).
- [ ] `load-db-password.sh` (and backup/rolling scripts) use Honey secret path and container/db names.
- [ ] Backend + DB + phpMyAdmin start; health check returns 200.
- [ ] Nginx site config in place; `nginx -t` OK; HTTPS works.
- [ ] Frontend and admin builds deployed to `/opt/app/frontend/dist` and `/opt/app/admin-panel`.
- [ ] API and WebSocket work through Nginx; avatars and admin paths load.
- [ ] phpMyAdmin reachable only via Nginx secret path; 8081 not public.
- [ ] Rolling update script updated for `honey-backend` / `honey-backend-new` and tested.
- [ ] Backup script adapted for `honey_db` / `honey-mysql`; cron runs and backups appear on backup VPS.
- [ ] Logs under `/opt/app/logs` and logback config under `/opt/app/backend/config`; log level change works.

This gives you the same layout and workflow as your lottery VPS, but for Honey (honey-be, honey-fe, honey-admin) with Nginx, phpMyAdmin, logging, and backups.
