Backend Stability, Basically functional.
This commit is contained in:
674
spring-backend/DEPLOYMENT.md
Normal file
674
spring-backend/DEPLOYMENT.md
Normal file
@@ -0,0 +1,674 @@
|
||||
# Deployment Guide - Debian/Proxmox VE
|
||||
|
||||
## Overview
|
||||
|
||||
This guide covers deploying the Group Ironmen backend to a Debian container on Proxmox VE.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ Proxmox VE Host │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ Debian Container 1 │ │
|
||||
│ │ - Java 17 │ │
|
||||
│ │ - Spring Boot Backend (Port 8080) │ │
|
||||
│ │ - systemd service │ │
|
||||
│ └───────────────┬───────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌───────────────┴───────────────────────┐ │
|
||||
│ │ Debian Container 2 (or same) │ │
|
||||
│ │ - MariaDB (Port 3306) │ │
|
||||
│ │ - Database: groupironman │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Network Bridge (vmbr0) │
|
||||
│ - Backend: 192.168.1.100:8080 │
|
||||
│ - Database: 192.168.1.101:3306 │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### 1. Proxmox VE Setup
|
||||
- Proxmox VE 7.x or 8.x installed
|
||||
- Two Debian LXC containers (or one for both services)
|
||||
- Network bridge configured
|
||||
|
||||
### 2. Debian Container Requirements
|
||||
- Debian 11 (Bullseye) or Debian 12 (Bookworm)
|
||||
- At least 1GB RAM for backend
|
||||
- At least 2GB RAM for MariaDB
|
||||
- 10GB disk space minimum
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Create LXC Containers in Proxmox
|
||||
|
||||
### Backend Container
|
||||
```bash
|
||||
# From Proxmox host
|
||||
pct create 100 \
|
||||
local:vztmpl/debian-12-standard_12.0-1_amd64.tar.zst \
|
||||
--hostname group-ironmen-backend \
|
||||
--memory 2048 \
|
||||
--cores 2 \
|
||||
--net0 name=eth0,bridge=vmbr0,ip=192.168.1.100/24,gw=192.168.1.1 \
|
||||
--rootfs local-lvm:10 \
|
||||
--unprivileged 1 \
|
||||
--features nesting=1
|
||||
|
||||
# Start container
|
||||
pct start 100
|
||||
```
|
||||
|
||||
### Database Container (Optional - can be same container)
|
||||
```bash
|
||||
pct create 101 \
|
||||
local:vztmpl/debian-12-standard_12.0-1_amd64.tar.zst \
|
||||
--hostname mariadb-server \
|
||||
--memory 4096 \
|
||||
--cores 2 \
|
||||
--net0 name=eth0,bridge=vmbr0,ip=192.168.1.101/24,gw=192.168.1.1 \
|
||||
--rootfs local-lvm:20 \
|
||||
--unprivileged 1
|
||||
|
||||
pct start 101
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Setup MariaDB Container
|
||||
|
||||
### Enter Database Container
|
||||
```bash
|
||||
pct enter 101
|
||||
```
|
||||
|
||||
### Install MariaDB
|
||||
```bash
|
||||
apt update
|
||||
apt install -y mariadb-server mariadb-client
|
||||
|
||||
# Secure installation
|
||||
mysql_secure_installation
|
||||
```
|
||||
|
||||
### Create Database and User
|
||||
```bash
|
||||
mysql -u root -p
|
||||
```
|
||||
|
||||
```sql
|
||||
-- Create database
|
||||
CREATE DATABASE groupironman CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- Create user for backend
|
||||
CREATE USER 'groupironmen'@'%' IDENTIFIED BY 'your_secure_password_here';
|
||||
|
||||
-- Grant privileges
|
||||
GRANT ALL PRIVILEGES ON groupironman.* TO 'groupironmen'@'%';
|
||||
FLUSH PRIVILEGES;
|
||||
|
||||
-- Verify
|
||||
SHOW DATABASES;
|
||||
SELECT User, Host FROM mysql.user WHERE User = 'groupironmen';
|
||||
|
||||
EXIT;
|
||||
```
|
||||
|
||||
### Configure MariaDB for Remote Access
|
||||
```bash
|
||||
# Edit MariaDB config
|
||||
nano /etc/mysql/mariadb.conf.d/50-server.cnf
|
||||
|
||||
# Change bind-address to allow connections from backend container
|
||||
# Find: bind-address = 127.0.0.1
|
||||
# Change to: bind-address = 0.0.0.0
|
||||
|
||||
# Restart MariaDB
|
||||
systemctl restart mariadb
|
||||
systemctl enable mariadb
|
||||
|
||||
# Check status
|
||||
systemctl status mariadb
|
||||
|
||||
# Test remote connection
|
||||
mysql -h 192.168.1.101 -u groupironmen -p groupironman
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Setup Backend Container
|
||||
|
||||
### Enter Backend Container
|
||||
```bash
|
||||
pct enter 100
|
||||
```
|
||||
|
||||
### Install Java 17
|
||||
```bash
|
||||
apt update
|
||||
apt install -y openjdk-17-jdk-headless wget curl vim
|
||||
|
||||
# Verify Java version
|
||||
java -version
|
||||
# Should show: openjdk version "17.x.x"
|
||||
```
|
||||
|
||||
### Create Application Directory
|
||||
```bash
|
||||
# Create app directory
|
||||
mkdir -p /opt/group-ironmen-backend
|
||||
cd /opt/group-ironmen-backend
|
||||
|
||||
# Create logs directory
|
||||
mkdir -p /var/log/group-ironmen-backend
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Build and Deploy Application
|
||||
|
||||
### Option A: Build on Development Machine (Recommended)
|
||||
|
||||
On your **Windows development machine**:
|
||||
|
||||
```bash
|
||||
cd C:\Users\Sonder\Gitea\leagues-tools\spring-backend
|
||||
|
||||
# Build JAR file
|
||||
./gradlew.bat clean build -x test
|
||||
|
||||
# JAR location: build/libs/group-ironmen-backend-1.0.0.jar
|
||||
```
|
||||
|
||||
Transfer to Proxmox container:
|
||||
```bash
|
||||
# From Windows (using scp or WinSCP)
|
||||
scp build/libs/group-ironmen-backend-1.0.0.jar root@192.168.1.100:/opt/group-ironmen-backend/
|
||||
|
||||
# Or use FileZilla/WinSCP GUI
|
||||
```
|
||||
|
||||
### Option B: Build on Container (Alternative)
|
||||
|
||||
```bash
|
||||
# Install Git
|
||||
apt install -y git
|
||||
|
||||
# Clone repository
|
||||
cd /opt
|
||||
git clone https://your-git-repo/leagues-tools.git
|
||||
cd leagues-tools/spring-backend
|
||||
|
||||
# Build
|
||||
./gradlew clean build -x test
|
||||
|
||||
# Copy JAR
|
||||
cp build/libs/group-ironmen-backend-1.0.0.jar /opt/group-ironmen-backend/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 5: Configure Application
|
||||
|
||||
### Create Environment Configuration
|
||||
```bash
|
||||
nano /opt/group-ironmen-backend/application.env
|
||||
```
|
||||
|
||||
```bash
|
||||
# Database Configuration
|
||||
DB_HOST=192.168.1.101
|
||||
DB_PORT=3306
|
||||
DB_NAME=groupironman
|
||||
DB_USER=groupironmen
|
||||
DB_PASSWORD=your_secure_password_here
|
||||
|
||||
# Server Configuration
|
||||
SERVER_PORT=8080
|
||||
|
||||
# Security
|
||||
BACKEND_SECRET=change_this_to_a_random_64_character_string_for_production
|
||||
|
||||
# CORS (allow frontend origins)
|
||||
CORS_ORIGINS=http://your-frontend-domain.com,http://localhost:4000
|
||||
|
||||
# Captcha (optional)
|
||||
CAPTCHA_ENABLED=false
|
||||
CAPTCHA_SITEKEY=
|
||||
CAPTCHA_SECRET=
|
||||
|
||||
# Logging
|
||||
LOGGING_LEVEL_ROOT=INFO
|
||||
LOGGING_LEVEL_COM_OSLEAGUE=DEBUG
|
||||
```
|
||||
|
||||
### Set Secure Permissions
|
||||
```bash
|
||||
chmod 600 /opt/group-ironmen-backend/application.env
|
||||
chown root:root /opt/group-ironmen-backend/application.env
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 6: Create systemd Service
|
||||
|
||||
### Create Service File
|
||||
```bash
|
||||
nano /etc/systemd/system/group-ironmen-backend.service
|
||||
```
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Group Ironmen Backend - Spring Boot Application
|
||||
After=network.target mariadb.service
|
||||
Wants=mariadb.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/group-ironmen-backend
|
||||
EnvironmentFile=/opt/group-ironmen-backend/application.env
|
||||
|
||||
ExecStart=/usr/bin/java \
|
||||
-Xms512m \
|
||||
-Xmx1024m \
|
||||
-Dserver.port=${SERVER_PORT} \
|
||||
-Dspring.datasource.url=jdbc:mariadb://${DB_HOST}:${DB_PORT}/${DB_NAME} \
|
||||
-Dspring.datasource.username=${DB_USER} \
|
||||
-Dspring.datasource.password=${DB_PASSWORD} \
|
||||
-Dapp.security.secret=${BACKEND_SECRET} \
|
||||
-Dapp.cors.allowed-origins=${CORS_ORIGINS} \
|
||||
-jar /opt/group-ironmen-backend/group-ironmen-backend-1.0.0.jar
|
||||
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=group-ironmen-backend
|
||||
|
||||
# Logging
|
||||
StandardOutput=append:/var/log/group-ironmen-backend/application.log
|
||||
StandardError=append:/var/log/group-ironmen-backend/error.log
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
### Enable and Start Service
|
||||
```bash
|
||||
# Reload systemd
|
||||
systemctl daemon-reload
|
||||
|
||||
# Enable service (start on boot)
|
||||
systemctl enable group-ironmen-backend
|
||||
|
||||
# Start service
|
||||
systemctl start group-ironmen-backend
|
||||
|
||||
# Check status
|
||||
systemctl status group-ironmen-backend
|
||||
|
||||
# View logs
|
||||
journalctl -u group-ironmen-backend -f
|
||||
tail -f /var/log/group-ironmen-backend/application.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 7: Test Deployment
|
||||
|
||||
### Test from Container
|
||||
```bash
|
||||
# Health check (if Spring Actuator enabled)
|
||||
curl http://localhost:8080/actuator/health
|
||||
|
||||
# Test GE prices endpoint
|
||||
curl http://localhost:8080/api/ge-prices
|
||||
|
||||
# Test captcha config
|
||||
curl http://localhost:8080/api/captcha-enabled
|
||||
|
||||
# Create test group
|
||||
curl -X POST http://localhost:8080/api/create-group \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "Test Group",
|
||||
"member_names": ["Player1", "Player2"],
|
||||
"captcha_response": ""
|
||||
}'
|
||||
```
|
||||
|
||||
### Test from External Machine
|
||||
```bash
|
||||
# From your Windows machine or another host
|
||||
curl http://192.168.1.100:8080/api/ge-prices
|
||||
|
||||
# Create group
|
||||
curl -X POST http://192.168.1.100:8080/api/create-group \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name": "My Group", "member_names": ["Player1"]}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 8: Firewall Configuration (Optional)
|
||||
|
||||
### Configure iptables
|
||||
```bash
|
||||
# Allow port 8080 from specific networks
|
||||
iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 8080 -j ACCEPT
|
||||
|
||||
# Or allow from specific IP (frontend container)
|
||||
iptables -A INPUT -p tcp -s 192.168.1.200 --dport 8080 -j ACCEPT
|
||||
|
||||
# Save rules
|
||||
apt install -y iptables-persistent
|
||||
netfilter-persistent save
|
||||
```
|
||||
|
||||
### Configure UFW (Alternative)
|
||||
```bash
|
||||
apt install -y ufw
|
||||
|
||||
# Allow SSH
|
||||
ufw allow 22/tcp
|
||||
|
||||
# Allow backend port
|
||||
ufw allow 8080/tcp
|
||||
|
||||
# Enable firewall
|
||||
ufw enable
|
||||
ufw status
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 9: Reverse Proxy (Optional - for HTTPS)
|
||||
|
||||
### Install Nginx
|
||||
```bash
|
||||
apt install -y nginx
|
||||
```
|
||||
|
||||
### Configure Nginx Reverse Proxy
|
||||
```bash
|
||||
nano /etc/nginx/sites-available/group-ironmen-backend
|
||||
```
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name api.groupiron.men; # Your domain
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:8080;
|
||||
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;
|
||||
|
||||
# CORS headers (handled by Spring, but can add here too)
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
# Enable site
|
||||
ln -s /etc/nginx/sites-available/group-ironmen-backend /etc/nginx/sites-enabled/
|
||||
|
||||
# Test config
|
||||
nginx -t
|
||||
|
||||
# Restart Nginx
|
||||
systemctl restart nginx
|
||||
systemctl enable nginx
|
||||
```
|
||||
|
||||
### Add SSL with Let's Encrypt
|
||||
```bash
|
||||
apt install -y certbot python3-certbot-nginx
|
||||
|
||||
# Get certificate
|
||||
certbot --nginx -d api.groupiron.men
|
||||
|
||||
# Auto-renewal is configured automatically
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 10: Monitoring and Maintenance
|
||||
|
||||
### View Logs
|
||||
```bash
|
||||
# Application logs
|
||||
tail -f /var/log/group-ironmen-backend/application.log
|
||||
|
||||
# System logs
|
||||
journalctl -u group-ironmen-backend -f
|
||||
|
||||
# Last 100 lines
|
||||
journalctl -u group-ironmen-backend -n 100
|
||||
```
|
||||
|
||||
### Restart Service
|
||||
```bash
|
||||
systemctl restart group-ironmen-backend
|
||||
```
|
||||
|
||||
### Update Application
|
||||
```bash
|
||||
# Stop service
|
||||
systemctl stop group-ironmen-backend
|
||||
|
||||
# Backup current JAR
|
||||
cp /opt/group-ironmen-backend/group-ironmen-backend-1.0.0.jar \
|
||||
/opt/group-ironmen-backend/backup/group-ironmen-backend-1.0.0.jar.$(date +%Y%m%d)
|
||||
|
||||
# Upload new JAR
|
||||
# ... (use scp or WinSCP)
|
||||
|
||||
# Start service
|
||||
systemctl start group-ironmen-backend
|
||||
|
||||
# Check status
|
||||
systemctl status group-ironmen-backend
|
||||
```
|
||||
|
||||
### Database Backups
|
||||
```bash
|
||||
# Create backup script
|
||||
nano /opt/scripts/backup-database.sh
|
||||
```
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
BACKUP_DIR="/opt/backups/mariadb"
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
mkdir -p $BACKUP_DIR
|
||||
|
||||
mysqldump -u groupironmen -p'your_password' groupironman \
|
||||
> $BACKUP_DIR/groupironman_$DATE.sql
|
||||
|
||||
# Keep last 7 days
|
||||
find $BACKUP_DIR -name "groupironman_*.sql" -mtime +7 -delete
|
||||
```
|
||||
|
||||
```bash
|
||||
chmod +x /opt/scripts/backup-database.sh
|
||||
|
||||
# Add to crontab (daily at 2 AM)
|
||||
crontab -e
|
||||
0 2 * * * /opt/scripts/backup-database.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Service Won't Start
|
||||
```bash
|
||||
# Check logs
|
||||
journalctl -u group-ironmen-backend -n 50 --no-pager
|
||||
|
||||
# Check if port is already in use
|
||||
netstat -tulpn | grep 8080
|
||||
|
||||
# Check Java is installed
|
||||
java -version
|
||||
|
||||
# Check file permissions
|
||||
ls -la /opt/group-ironmen-backend/
|
||||
```
|
||||
|
||||
### Database Connection Issues
|
||||
```bash
|
||||
# Test connection from backend container
|
||||
mysql -h 192.168.1.101 -u groupironmen -p groupironman
|
||||
|
||||
# Check MariaDB is listening on correct interface
|
||||
netstat -tulpn | grep 3306
|
||||
|
||||
# Check firewall rules
|
||||
iptables -L -n | grep 3306
|
||||
```
|
||||
|
||||
### Application Errors
|
||||
```bash
|
||||
# Enable debug logging
|
||||
# Edit /opt/group-ironmen-backend/application.env
|
||||
LOGGING_LEVEL_COM_OSLEAGUE=DEBUG
|
||||
|
||||
# Restart service
|
||||
systemctl restart group-ironmen-backend
|
||||
|
||||
# Watch logs
|
||||
tail -f /var/log/group-ironmen-backend/application.log
|
||||
```
|
||||
|
||||
### High Memory Usage
|
||||
```bash
|
||||
# Check Java heap
|
||||
jps -lv
|
||||
|
||||
# Adjust JVM settings in systemd service
|
||||
# Edit /etc/systemd/system/group-ironmen-backend.service
|
||||
# Change: -Xms512m -Xmx1024m
|
||||
# To: -Xms256m -Xmx768m
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl restart group-ironmen-backend
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance Tuning
|
||||
|
||||
### JVM Tuning
|
||||
```bash
|
||||
# Edit systemd service file
|
||||
nano /etc/systemd/system/group-ironmen-backend.service
|
||||
|
||||
# Add JVM options
|
||||
ExecStart=/usr/bin/java \
|
||||
-Xms512m \
|
||||
-Xmx1024m \
|
||||
-XX:+UseG1GC \
|
||||
-XX:MaxGCPauseMillis=200 \
|
||||
-XX:+UseStringDeduplication \
|
||||
...
|
||||
```
|
||||
|
||||
### MariaDB Tuning
|
||||
```bash
|
||||
# Edit MariaDB config
|
||||
nano /etc/mysql/mariadb.conf.d/50-server.cnf
|
||||
|
||||
# Add under [mysqld]
|
||||
innodb_buffer_pool_size = 1G
|
||||
innodb_log_file_size = 256M
|
||||
max_connections = 100
|
||||
|
||||
systemctl restart mariadb
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security Checklist
|
||||
|
||||
- [ ] Changed default passwords for MariaDB root and groupironmen user
|
||||
- [ ] Set secure BACKEND_SECRET (64+ random characters)
|
||||
- [ ] Configured firewall (iptables/ufw) to restrict access
|
||||
- [ ] CORS origins set to specific domains (not *)
|
||||
- [ ] Regular database backups scheduled
|
||||
- [ ] Nginx reverse proxy with SSL (if public-facing)
|
||||
- [ ] Kept system updated (`apt update && apt upgrade`)
|
||||
- [ ] Monitored logs for suspicious activity
|
||||
- [ ] File permissions set correctly (600 for env file)
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Service Commands
|
||||
```bash
|
||||
systemctl start group-ironmen-backend
|
||||
systemctl stop group-ironmen-backend
|
||||
systemctl restart group-ironmen-backend
|
||||
systemctl status group-ironmen-backend
|
||||
systemctl enable group-ironmen-backend # Start on boot
|
||||
systemctl disable group-ironmen-backend # Don't start on boot
|
||||
```
|
||||
|
||||
### Log Commands
|
||||
```bash
|
||||
journalctl -u group-ironmen-backend -f # Follow logs
|
||||
journalctl -u group-ironmen-backend -n 100 # Last 100 lines
|
||||
journalctl -u group-ironmen-backend --since today # Today's logs
|
||||
tail -f /var/log/group-ironmen-backend/application.log
|
||||
```
|
||||
|
||||
### Database Commands
|
||||
```bash
|
||||
mysql -u groupironmen -p groupironman # Connect to DB
|
||||
mysqldump -u groupironmen -p groupironman > backup.sql # Backup
|
||||
mysql -u groupironmen -p groupironman < backup.sql # Restore
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Network Diagram
|
||||
|
||||
```
|
||||
Internet
|
||||
↓
|
||||
[Firewall/Router]
|
||||
↓
|
||||
Proxmox Bridge (vmbr0) - 192.168.1.0/24
|
||||
│
|
||||
├── Backend Container (192.168.1.100:8080)
|
||||
│ └── group-ironmen-backend.service
|
||||
│ └── Spring Boot App
|
||||
│ ├── Port 8080 (HTTP API)
|
||||
│ └── Connects to → 192.168.1.101:3306
|
||||
│
|
||||
├── Database Container (192.168.1.101:3306)
|
||||
│ └── MariaDB
|
||||
│ └── Database: groupironman
|
||||
│
|
||||
└── Frontend Container (192.168.1.200:4000) [Future]
|
||||
└── Next.js/React Frontend
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Deployment Status**: Ready for production deployment!
|
||||
**Last Updated**: 2025-10-27
|
||||
Reference in New Issue
Block a user