# Sojorn VPS Setup Guide Complete guide to deploy Sojorn Flutter Web app to your VPS with Nginx. **Note:** You mentioned MariaDB, but since you're using Supabase (PostgreSQL) for your database, you don't need MariaDB on your VPS. This guide focuses on hosting the static Flutter web files. --- ## Prerequisites - VPS with Ubuntu 20.04/22.04 (or Debian-based distro) - Root or sudo access - Domain name (sojorn.net) pointed to your VPS IP - SSH access to your VPS --- ## Part 1: Initial VPS Setup ### 1. Connect to your VPS ```bash ssh root@your-vps-ip # or if you have a non-root user ssh your-username@your-vps-ip ``` ### 2. Update system packages ```bash apt update apt upgrade -y ``` ### 3. Set up firewall ```bash # Allow SSH ufw allow OpenSSH # Allow HTTP and HTTPS ufw allow 'Nginx Full' # Enable firewall ufw enable # Check status ufw status ``` **Note:** If you're logged in as root, you don't need `sudo`. If you're using a non-root user, prefix commands with `sudo`. --- ## Part 2: Install Nginx ### 1. Install Nginx ```bash apt install nginx -y ``` ### 2. Start and enable Nginx ```bash systemctl start nginx systemctl enable nginx systemctl status nginx ``` ### 3. Test Nginx Visit `http://your-vps-ip` in a browser. You should see the default Nginx welcome page. --- ## Part 3: SSL Certificate (Let's Encrypt) ### 1. Install Certbot ```bash apt install certbot python3-certbot-nginx -y ``` ### 2. Obtain SSL certificate **Important:** Make sure your domain DNS is already pointing to your VPS IP before running this. ```bash certbot --nginx -d sojorn.net -d www.sojorn.net ``` Follow the prompts: - Enter your email address - Agree to terms of service - Choose whether to redirect HTTP to HTTPS (recommended: Yes) ### 3. Test auto-renewal ```bash certbot renew --dry-run ``` Certbot will automatically renew your certificate before it expires. --- ## Part 4: Configure Nginx for Flutter Web ### 1. Create web root directory ```bash mkdir -p /var/www/sojorn chmod -R 755 /var/www/sojorn ``` ### 2. Create Nginx configuration ```bash nano /etc/nginx/sites-available/sojorn ``` Paste this configuration: ```nginx # Redirect www to non-www server { listen 80; listen [::]:80; listen 443 ssl http2; listen [::]:443 ssl http2; server_name www.sojorn.net; ssl_certificate /etc/letsencrypt/live/sojorn.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/sojorn.net/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; return 301 https://sojorn.net$request_uri; } # Main server block server { listen 80; listen [::]:80; server_name sojorn.net; # Redirect HTTP to HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name sojorn.net; # SSL Configuration ssl_certificate /etc/letsencrypt/live/sojorn.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/sojorn.net/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # Security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; # Root directory root /var/www/sojorn; index index.html; # Gzip compression gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/javascript application/json; # Flutter Web routing location / { try_files $uri $uri/ /index.html; } # Cache static assets location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; } # Cache control for Flutter assets location /assets/ { expires 1y; add_header Cache-Control "public, immutable"; } # Don't cache index.html or service worker location ~* (index\.html|flutter_service_worker\.js)$ { add_header Cache-Control "no-cache, no-store, must-revalidate"; expires 0; } # Security: deny access to hidden files location ~ /\. { deny all; access_log off; log_not_found off; } # Logging access_log /var/log/nginx/sojorn_access.log; error_log /var/log/nginx/sojorn_error.log; } ``` ### 3. Enable the site ```bash # Create symbolic link ln -s /etc/nginx/sites-available/sojorn /etc/nginx/sites-enabled/ # Test configuration nginx -t # Reload Nginx systemctl reload nginx ``` --- ## Part 5: Build and Deploy Flutter Web ### On your local machine (Windows): ### 1. Build Flutter for web ```bash cd C:\Webs\Sojorn\sojorn_app # Build for production flutter build web --release --web-renderer canvaskit ``` **Build options:** - `--web-renderer canvaskit`: Best for mobile-first apps (better compatibility) - `--web-renderer html`: Lighter weight, faster initial load (alternative) - `--web-renderer auto`: Flutter decides based on device (default) ### 2. The build output is in: `sojorn_app/build/web/` --- ## Part 6: Transfer Files to VPS ### Option A: Using SCP (from Windows PowerShell or WSL) ```bash # From your local machine cd C:\Webs\Sojorn\sojorn_app\build # Upload web directory scp -r web/* your-username@your-vps-ip:/var/www/sojorn/ ``` ### Option B: Using SFTP ```bash # Connect via SFTP sftp your-username@your-vps-ip # Navigate to local build directory lcd C:\Webs\Sojorn\sojorn_app\build\web # Navigate to remote directory cd /var/www/sojorn # Upload files put -r * # Exit exit ``` ### Option C: Using Git (Recommended for continuous deployment) **On your VPS:** ```bash cd /var/www/sojorn # Initialize git repo git init git remote add origin https://github.com/yourusername/sojorn-web.git # Pull latest git pull origin main ``` **On your local machine:** ```bash # Create a separate repo for web builds cd C:\Webs\Sojorn\sojorn_app\build\web git init git add . git commit -m "Initial Flutter web build" git remote add origin https://github.com/yourusername/sojorn-web.git git push -u origin main ``` --- ## Part 7: Set Correct Permissions On your VPS: ```bash # Set ownership (Nginx runs as www-data user) chown -R www-data:www-data /var/www/sojorn # Set permissions chmod -R 755 /var/www/sojorn ``` --- ## Part 8: Test Your Deployment 1. Visit `https://sojorn.net` - you should see your app 2. Test deep linking: `https://sojorn.net/username` should route to a profile 3. Check SSL: Look for the padlock icon in the browser --- ## Part 9: Set Up Automatic Deployments (Optional) ### Create a deployment script on your VPS: ```bash nano ~/deploy-sojorn.sh ``` Paste: ```bash #!/bin/bash echo "Deploying Sojorn..." # Navigate to web directory cd /var/www/sojorn # Pull latest changes (if using Git) git pull origin main # Set permissions chown -R www-data:www-data /var/www/sojorn chmod -R 755 /var/www/sojorn # Reload Nginx systemctl reload nginx echo "Deployment complete!" ``` Make it executable: ```bash chmod +x ~/deploy-sojorn.sh ``` Run deployments: ```bash ~/deploy-sojorn.sh ``` --- ## Part 10: Monitoring and Maintenance ### Check Nginx logs ```bash # Access logs tail -f /var/log/nginx/sojorn_access.log # Error logs tail -f /var/log/nginx/sojorn_error.log ``` ### Check Nginx status ```bash systemctl status nginx ``` ### Restart Nginx if needed ```bash systemctl restart nginx ``` ### Update SSL certificate (automatic, but manual command) ```bash certbot renew ``` --- ## Troubleshooting ### Issue: "502 Bad Gateway" - Check Nginx error logs: `tail -f /var/log/nginx/sojorn_error.log` - Verify file permissions - Restart Nginx: `systemctl restart nginx` ### Issue: Routes not working (404 on /u/username) - Verify `try_files` directive in Nginx config - Make sure index.html exists in /var/www/sojorn - Check Nginx configuration: `nginx -t` ### Issue: SSL certificate issues - Verify DNS is pointing to correct IP - Run: `certbot certificates` to check status - Renew manually: `certbot renew --force-renewal` ### Issue: Assets not loading - Check browser console for CORS errors - Verify file permissions: `ls -la /var/www/sojorn` - Clear browser cache --- ## Performance Optimization Tips ### 1. Enable HTTP/2 (already in config) HTTP/2 is enabled with `http2` directive in listen statements. ### 2. Add Brotli compression (optional) ```bash # Install brotli module sudo apt install nginx-module-brotli -y # Add to nginx.conf sudo nano /etc/nginx/nginx.conf ``` Add to http block: ```nginx brotli on; brotli_comp_level 6; brotli_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/javascript application/json; ``` ### 3. Set up CDN (optional but recommended) Consider using Cloudflare for: - Global CDN - DDoS protection - Free SSL - Automatic minification --- ## Next Steps 1. **Set up monitoring**: Use tools like UptimeRobot or Pingdom to monitor uptime 2. **Configure backups**: Regularly backup your VPS 3. **Set up CI/CD**: Automate deployments with GitHub Actions or GitLab CI 4. **Analytics**: Add Google Analytics or Plausible to track usage 5. **Performance monitoring**: Use tools like Lighthouse to monitor performance --- ## Quick Reference Commands ```bash # Restart Nginx systemctl restart nginx # Reload Nginx (without downtime) systemctl reload nginx # Test Nginx configuration nginx -t # Check Nginx status systemctl status nginx # View error logs tail -f /var/log/nginx/sojorn_error.log # Deploy new version ~/deploy-sojorn.sh # Renew SSL certbot renew ``` --- ## Summary You now have: ✅ Nginx web server installed and configured ✅ SSL certificate for HTTPS ✅ Flutter Web app served at https://sojorn.net ✅ Deep linking support for URLs like /username ✅ Gzip compression for better performance ✅ Proper security headers ✅ Caching for static assets Your app is now live and accessible at https://sojorn.net! 🎉