Server Migration – Moving Stage / Prod / In House

Server Migration Summary: MacBook Pro (.44) to Mac Mini (.9)

Initial Setup

  • Source: MacBook Pro running Ubuntu (192.168.1.44)
  • Destination: 2018 Mac Mini running Ubuntu (192.168.1.9)
  • Architecture: Proxy server (.26) routes all traffic via SSL termination
  • Challenge: Original documentation mentioned Apache, but actual setup was pure Nginx

Step 1: Network Configuration

  1. Assigned static IP 192.168.1.9 to Mac Mini in router

  2. Configured firewall on .9:

    • Allowed ports 80, 443, 8080, 9002 from proxy server (.26)
    • sudo ufw allow from 192.168.1.26 to any port 8080
    • sudo ufw allow from 192.168.1.26 to any port 9002

Step 2: Database Migration

  1. MySQL setup on .9:

    • Set root password
    • Created admin user spiffy-root with same password
    • Avoided auth_socket to prevent lockouts
  2. Matomo database:

    • Created database: matomo_db
    • Created user: matomo_user
    • Password: H0m0-Mat0m0! (matched config file)
    • Exported from .44: mysqldump -u matomo_user -p matomo_db > matomo.sql
    • Imported to .9: mysql -u matomo_user -p matomo_db < matomo.sql
  3. WordPress database:

    • Skipped migration – did fresh install instead

Step 3: File Transfer

  1. Created tarball on .44: sudo tar -czf /tmp/www-backup.tar.gz -C /var/www/html .
  2. Transferred to .9: scp /tmp/www-backup.tar.gz spiffy-root@192.168.1.9:/tmp/
  3. Extracted: sudo tar -xzf www-backup.tar.gz -C /var/www/html/
  4. Set permissions: sudo chown -R www-data:www-data /var/www/html/

Step 4: Web Server Configuration (Critical Discovery)

Key realization: .44 uses pure Nginx, NOT Apache+Nginx hybrid

  1. Removed Apache from .9:

    • sudo systemctl stop apache2
    • sudo systemctl disable apache2
  2. Configured Nginx on .9:

    • Copied all nginx configs from .44 to .9

    • Three sites on Nginx:

      • Matomo: port 80
      • wp-flap: port 8080
      • flap: port 8080
    • Removed default site to prevent conflicts

    • Enabled PHP-FPM: sudo a2enconf php8.3-fpm (wait, this is Apache command but we’re using Nginx – the config just routes PHP to FPM socket)

  3. PHP-FPM configuration:

    • Service: php8.3-fpm
    • Socket: /run/php/php8.3-fpm.sock
    • All nginx sites use fastcgi_pass to this socket
  4. Fixed Matomo security issue:

    • Original config blocked index.php from non-localhost
    • Caused 500 errors from proxy server
    • Removed restrictive location block

Step 5: Proxy Server Updates (.26)

Changed all proxy_pass directives from .44 to .9:

  1. flap.shawns-machine.com:

    • From: http://192.168.1.44:8080
    • To: http://192.168.1.9:8080
  2. wp-flap.shawns-machine.com:

    • From: http://192.168.1.44:8080
    • To: http://192.168.1.9:8080
  3. matomo.shawns-machine.com:

    • From: http://192.168.1.44:80
    • To: http://192.168.1.9:80 (or just IP without port)
  4. After each change: sudo nginx -t && sudo systemctl reload nginx

Step 6: Linear Webhook Migration

  1. Transferred files:

    • tar -czf /tmp/linear-webhook-backup.tar.gz /home/spiffy/linear-webhook/
    • Extracted to /home/spiffy-root/linear-webhook/ on .9
  2. Recreated Python environment:

    • sudo apt install python3.12-venv
    • python3 -m venv .venv
    • source .venv/bin/activate
    • pip install flask gunicorn
  3. Created systemd service at /etc/systemd/system/linear-webhook.service:

    • Changed User from spiffy to spiffy-root
    • Changed all paths from /home/spiffy/ to /home/spiffy-root/
    • Port: 9002
    • Token and other env vars stayed the same
  4. Started service:

    • sudo systemctl daemon-reload
    • sudo systemctl enable linear-webhook
    • sudo systemctl start linear-webhook
  5. Updated proxy for Linear:

    • From: http://192.168.1.44:9002
    • To: http://192.168.1.9:9002

Critical Lessons for Production Setup

  1. Verify actual architecture first – Documentation may be outdated
  2. User consistency matters – .44 used spiffy, .9 uses spiffy-root
  3. Firewall rules essential – Proxy can’t reach backend without them
  4. Python venvs don’t transfer – Rebuild from scratch
  5. Database passwords – Must match between config files and MySQL users
  6. Test locally first – Use curl with Host headers before updating proxy
  7. Remove default sites – They catch requests meant for virtual hosts

Production Migration Simplified Steps

For your new Ryzen5 production server:

  1. Set static IP and configure firewall
  2. Install Nginx + PHP-FPM (skip Apache entirely)
  3. Transfer web files via tarball
  4. Export/import databases with correct passwords
  5. Copy nginx configs (update any IP/hostname references)
  6. Recreate Linear webhook venv
  7. Create systemd service for webhook
  8. Update proxy server routing
  9. Test each site before decommissioning old server

The production migration should be faster since you now know:

  • Pure Nginx architecture (no Apache confusion)
  • Firewall requirements upfront
  • Database password matching importance
  • Python venv recreation process