# Quick Reference - VPS Deployment ## Common Commands ### Docker Compose (Backend) ```bash cd /opt/app/backend # Start services docker compose -f docker-compose.prod.yml up -d # Stop services docker compose -f docker-compose.prod.yml down # Restart services docker compose -f docker-compose.prod.yml restart # View logs docker compose -f docker-compose.prod.yml logs -f # Rebuild and restart docker compose -f docker-compose.prod.yml up -d --build # Check status docker compose -f docker-compose.prod.yml ps ``` ### Nginx ```bash # Test configuration sudo nginx -t # Reload configuration sudo systemctl reload nginx # Restart Nginx sudo systemctl restart nginx # Check status sudo systemctl status nginx # View logs sudo tail -f /var/log/nginx/error.log sudo tail -f /var/log/nginx/access.log ``` ### SSL Certificate ```bash # Renew certificate sudo certbot renew # Test renewal sudo certbot renew --dry-run # Check certificates sudo certbot certificates ``` ### Database ```bash # Load database password from secret file (if not already loaded) cd /opt/app/backend source scripts/load-db-password.sh # Backup docker exec lottery-mysql mysqldump -u root -p${DB_PASSWORD} lottery_db > backup_$(date +%Y%m%d).sql # Restore docker exec -i lottery-mysql mysql -u root -p${DB_PASSWORD} lottery_db < backup.sql # Access MySQL shell docker exec -it lottery-mysql mysql -u root -p ``` ### Health Checks ```bash # Backend health curl http://localhost:8080/actuator/health # Frontend curl https://yourdomain.com/ # API endpoint curl https://yourdomain.com/api/health ``` ### Logs ```bash # Backend logs cd /opt/app/backend docker compose -f docker-compose.prod.yml logs -f backend # Database logs docker compose -f docker-compose.prod.yml logs -f db # All logs docker compose -f docker-compose.prod.yml logs -f # Nginx error log sudo tail -f /var/log/nginx/error.log ``` ### File Permissions ```bash # Fix avatar directory permissions sudo chown -R $USER:$USER /opt/app/data/avatars sudo chmod -R 755 /opt/app/data/avatars # Secure secret file sudo chmod 640 /run/secrets/lottery-config.properties sudo chown root:docker /run/secrets/lottery-config.properties ``` ### Update Application ```bash # Backend update cd /opt/app/backend git pull # or copy new files docker compose -f docker-compose.prod.yml up -d --build # Frontend update # 1. Build locally: npm run build # 2. Copy dist/ to /opt/app/frontend/dist/ scp -r dist/* user@vps:/opt/app/frontend/dist/ ``` ## Troubleshooting ### Backend won't start ```bash # Check logs docker compose -f docker-compose.prod.yml logs backend # Check secret file exists and is readable sudo ls -la /run/secrets/lottery-config.properties # Verify secret file is loaded (check logs for "Loading configuration from mounted secret file") docker compose -f docker-compose.prod.yml logs backend | grep "Loading configuration" # Verify database is ready docker compose -f docker-compose.prod.yml ps db ``` ### Frontend not loading ```bash # Check Nginx config sudo nginx -t # Verify files exist ls -la /opt/app/frontend/dist/ # Check Nginx error log sudo tail -f /var/log/nginx/error.log ``` ### WebSocket issues ```bash # Check backend logs docker compose -f docker-compose.prod.yml logs backend | grep -i websocket # Verify Nginx WebSocket config grep -A 10 "/ws" /opt/app/nginx/nginx.conf ``` ### Database connection failed ```bash # Check database container docker ps | grep mysql # Check database logs docker compose -f docker-compose.prod.yml logs db # Test connection docker exec -it lottery-mysql mysql -u root -p ``` ## File Locations ``` Backend source: /opt/app/backend/ Frontend build: /opt/app/frontend/dist/ Nginx config: /opt/app/nginx/nginx.conf Avatar storage: /opt/app/data/avatars/ Database data: /opt/app/mysql/data/ (via Docker volume) Secret file: /run/secrets/lottery-config.properties ``` ## Configuration Variables Required in `/run/secrets/lottery-config.properties`: - `SPRING_DATASOURCE_URL` - `SPRING_DATASOURCE_USERNAME` - `SPRING_DATASOURCE_PASSWORD` - `TELEGRAM_BOT_TOKEN` - `TELEGRAM_CHANNEL_CHECKER_BOT_TOKEN` - `TELEGRAM_FOLLOW_TASK_CHANNEL_ID` - `FRONTEND_URL` Optional: - `APP_AVATAR_STORAGE_PATH` - `APP_AVATAR_PUBLIC_BASE_URL` - `APP_SESSION_MAX_ACTIVE_PER_USER` - `APP_SESSION_CLEANUP_BATCH_SIZE` - `APP_SESSION_CLEANUP_MAX_BATCHES` - `GEOIP_DB_PATH` **Note:** The MySQL container also needs `DB_PASSWORD` and `DB_ROOT_PASSWORD` as environment variables (should match `SPRING_DATASOURCE_PASSWORD`).