# 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/setWebhook?url=https:///api/telegram/webhook/&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.` ### 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 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/ 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.