# MAD Lawsuit v2.0 - Production Deployment Guide ## Overview This guide covers deploying the Laravel + Vue + Inertia application to production using Docker. **Production URL**: https://v2.mad-lawsuit.org **Server**: 10.4.0.205 (public-websites) **Directory**: `~/websites/v2.mad-lawsuit.org/` --- ## Prerequisites ### On Local Machine - Git repository with all changes committed - `.env.production` file ready (NOT in Git) - All PDF files in `storage/app/public/documents/` ### On Production Server - Docker and Docker Compose installed - PostgreSQL container running (or use existing v1.0 database) - Caddy reverse proxy configured - SSH access: `ssh chaulmark@10.4.0.205` --- ## Deployment Steps ### 1. Prepare Local Repository ```bash # Ensure all changes are committed cd /Users/chaulmark/Eliza-MAD-docket-website git status # Commit any pending changes git add . git commit -m "Phase 4: Production deployment configuration" # Tag the release git tag -a v2.0 -m "MAD Lawsuit v2.0 - Laravel + Vue + Inertia" # Push to Gitea git push origin main git push origin v2.0 ``` ### 2. Transfer Sensitive Files via SCP **IMPORTANT**: `.env.production` is NOT in Git for security. ```bash # Copy .env.production to server scp .env.production chaulmark@10.4.0.205:~/websites/v2.mad-lawsuit.org/.env # Copy PDF files (if not already on server) scp -r storage/app/public/documents/*.pdf chaulmark@10.4.0.205:~/websites/v2.mad-lawsuit.org/storage/app/public/documents/ ``` ### 3. SSH to Production Server ```bash ssh chaulmark@10.4.0.205 ``` ### 4. Clone/Pull Repository ```bash # If first deployment cd ~/websites git clone https://gitea.sigd.net/chaulmark/mad-lawsuit.git v2.mad-lawsuit.org cd v2.mad-lawsuit.org git checkout v2.0 # If updating existing deployment cd ~/websites/v2.mad-lawsuit.org git fetch --all git checkout v2.0 git pull origin v2.0 ``` ### 5. Configure Environment ```bash # Verify .env file exists (transferred via SCP) ls -la .env # Generate application key docker compose run --rm app php artisan key:generate # Update .env with generated key nano .env # Copy the APP_KEY value from output above ``` ### 6. Build and Start Docker Containers ```bash # Build the Docker image docker compose build # Start containers docker compose up -d # Check container status docker compose ps docker compose logs -f app ``` ### 7. Run Database Migrations ```bash # Run migrations docker compose exec app php artisan migrate --force # Seed admin user docker compose exec app php artisan db:seed --class=AdminSeeder # Import v1.0 data docker compose exec app php artisan db:seed --class=V1DataMigrationSeeder # Create storage symlink docker compose exec app php artisan storage:link ``` ### 8. Verify Application ```bash # Check if app is running curl http://localhost:8080 # Check database connection docker compose exec app php artisan tinker >>> DB::connection()->getPdo(); >>> \App\Models\DocketEntry::count(); >>> exit ``` --- ## Caddy Configuration ### Add to Caddyfile **File**: `/home/chaulmark/docker/caddy/config/Caddyfile` ```caddyfile # MAD Lawsuit v2.0 v2.mad-lawsuit.org { reverse_proxy 172.18.0.X:8080 encode gzip log { output file /var/log/caddy/v2-mad-lawsuit.log } } ``` **Note**: Replace `172.18.0.X` with the actual container IP on the caddy_network. ### Find Container IP ```bash # Get container IP docker inspect mad-lawsuit-v2 | grep IPAddress # Or use docker network inspect docker network inspect caddy_network | grep -A 5 mad-lawsuit-v2 ``` ### Reload Caddy ```bash # Reload Caddy configuration docker exec caddy caddy reload --config /etc/caddy/Caddyfile ``` --- ## Database Configuration ### Option 1: Use Existing v1.0 PostgreSQL Update `.env`: ```env DB_CONNECTION=pgsql DB_HOST=mad-lawsuit-db # v1.0 container name DB_PORT=5432 DB_DATABASE=docket_db DB_USERNAME=docket_user DB_PASSWORD= ``` ### Option 2: Use New PostgreSQL Container The `docker-compose.yml` includes a PostgreSQL container: ```env DB_CONNECTION=pgsql DB_HOST=postgres DB_PORT=5432 DB_DATABASE=mad_lawsuit_v2 DB_USERNAME=mad_user DB_PASSWORD= ``` --- ## Post-Deployment Verification ### 1. Test Public Website ```bash # From local machine curl https://v2.mad-lawsuit.org ``` Or visit in browser: https://v2.mad-lawsuit.org **Check**: - [ ] Home page loads - [ ] Docket entries display - [ ] PDF downloads work - [ ] Email subscription form works ### 2. Test Admin Dashboard Visit: https://v2.mad-lawsuit.org/admin/login **Credentials**: - Username: `admin` - Password: `password` (change after first login) **Check**: - [ ] Login works - [ ] Dashboard shows correct statistics - [ ] Can view docket entries - [ ] Can create new entry - [ ] Can upload PDF - [ ] Can view subscribers ### 3. Check Logs ```bash # Application logs docker compose logs -f app # Nginx logs docker compose exec app tail -f /var/log/nginx/access.log docker compose exec app tail -f /var/log/nginx/error.log # Caddy logs docker exec caddy tail -f /var/log/caddy/v2-mad-lawsuit.log ``` --- ## Troubleshooting ### Container Won't Start ```bash # Check logs docker compose logs app # Check if port 8080 is available netstat -tuln | grep 8080 # Rebuild container docker compose down docker compose build --no-cache docker compose up -d ``` ### Database Connection Failed ```bash # Check PostgreSQL container docker compose ps postgres # Test connection docker compose exec app php artisan tinker >>> DB::connection()->getPdo(); ``` ### Permission Errors ```bash # Fix storage permissions docker compose exec app chown -R www-data:www-data /var/www/html/storage docker compose exec app chmod -R 775 /var/www/html/storage ``` ### PDF Files Not Found ```bash # Check if files exist docker compose exec app ls -la /var/www/html/storage/app/public/documents/ # Recreate storage symlink docker compose exec app php artisan storage:link ``` ### Caddy Not Routing ```bash # Check Caddy logs docker exec caddy caddy validate --config /etc/caddy/Caddyfile # Reload Caddy docker exec caddy caddy reload --config /etc/caddy/Caddyfile # Check container IP docker inspect mad-lawsuit-v2 | grep IPAddress ``` --- ## Maintenance Commands ### Update Application ```bash # Pull latest code cd ~/websites/v2.mad-lawsuit.org git pull origin main # Rebuild and restart docker compose down docker compose build docker compose up -d # Run migrations docker compose exec app php artisan migrate --force # Clear caches docker compose exec app php artisan cache:clear docker compose exec app php artisan config:clear docker compose exec app php artisan view:clear ``` ### Backup Database ```bash # Backup PostgreSQL docker compose exec postgres pg_dump -U mad_user mad_lawsuit_v2 > backup-$(date +%Y%m%d).sql # Or use v1.0 database docker exec mad-lawsuit-db pg_dump -U docket_user docket_db > backup-$(date +%Y%m%d).sql ``` ### View Logs ```bash # All logs docker compose logs -f # Specific service docker compose logs -f app docker compose logs -f postgres # Last 100 lines docker compose logs --tail=100 app ``` ### Restart Services ```bash # Restart all docker compose restart # Restart specific service docker compose restart app ``` --- ## Security Checklist - [ ] `.env` file has secure `APP_KEY` - [ ] Database password is strong and unique - [ ] Admin password changed from default - [ ] `APP_DEBUG=false` in production - [ ] SSL certificates active (via Caddy) - [ ] File permissions correct (775 for storage) - [ ] `.env` file NOT in Git repository - [ ] Firewall rules configured (if applicable) --- ## Rollback Plan If v2.0 has issues, v1.0 remains operational: 1. **Keep v1.0 running** at https://mad-lawsuit.org 2. **Test v2.0** at https://v2.mad-lawsuit.org 3. **Switch DNS** only after thorough testing 4. **Rollback**: Simply revert Caddy configuration to point to v1.0 --- ## Next Steps After Deployment 1. **Test thoroughly** on v2.mad-lawsuit.org 2. **Implement email notifications** (Phase 4.2) 3. **Monitor logs** for errors 4. **Update DNS** to switch from v1.0 to v2.0 5. **Decommission v1.0** after 48 hours of stable v2.0 --- ## Support **Repository**: https://gitea.sigd.net/chaulmark/mad-lawsuit **Server**: 10.4.0.205 (public-websites) **Contact**: chaulmark@sigd.net --- *Last Updated: December 17, 2025*