Skip to content

ERP-Unlocked Deployment Guide

This guide provides step-by-step instructions for deploying new versions of ERP-Unlocked using our PR-based deployment process with branch protection and dual deployment strategy: Coolify for Docker services via webhooks and Cloudflare Pages for the marketing site.

  1. Pre-Deployment Checklist
  2. Branch Protection & PR Workflow
  3. Staging Deployment
  4. Production Deployment
  5. Coolify Webhook Configuration
  6. Rollback Procedures
  7. Post-Deployment Verification
  8. Troubleshooting

Ensure you have the following access and credentials:

  • GitHub repository access with proper branch permissions
  • Coolify admin access (staging and production instances)
  • Cloudflare account access (for marketing site deployment)
  • Access to monitoring systems (SigNoz, Trigger.dev dashboard)
  • pnpm installed locally (for local testing)
  • All branch protection checks passing
  • Code review completed and approved
  • Feature flags configured appropriately
  • Database migrations reviewed (if applicable)
  • Security scan completed
  • Performance impact assessed
  • Notify team of upcoming deployment
  • Schedule deployment window if maintenance required
  • Prepare rollback communication plan

Our deployment process uses strict branch protection with automated validation:

  • main: Production deployments (protected)
  • staging: Staging deployments (protected)
  • develop: Integration branch for development
  1. PR Title Format: Must follow conventional commit format

    feat: add user authentication
    fix(api): resolve timeout issue
    docs: update deployment guide
  2. PR Description: Must contain meaningful description (minimum 10 characters)

  3. Branch Naming: Should follow pattern type/description

    feature/user-authentication
    fix/pdf-processing-bug
    hotfix/critical-security-patch
  4. Automated Checks: All PRs must pass:

    • Branch Protection: PR validation, security scan, deployment config validation
    • CI/CD Pipeline: Build validation (no push to registry)
    • Code Quality: Linting, type checking, formatting
  1. Create Feature Branch:

    Terminal window
    git checkout develop
    git pull origin develop
    git checkout -b feature/your-feature-name
  2. Make Changes and Push:

    Terminal window
    git add .
    git commit -m "feat: implement your feature"
    git push origin feature/your-feature-name
  3. Create Pull Request:

    • Target develop branch for features
    • Target staging for release candidates
    • Target main for hotfixes (emergency only)
  4. Validation Process:

    • Automatic validation builds run (no registry push)
    • Branch protection checks validate code quality
    • Security scans check for vulnerabilities
    • Manual code review by team members

Current staging runtime truth: the canonical PDF path is webapp -> Temporal -> temporal-worker. Staging should treat pdf-api as a legacy compatibility surface, not a required deployment success criterion.

Only after PR approval and validation:

  1. Create PR to staging:

    Terminal window
    # From your feature branch
    git checkout staging
    git pull origin staging
    # Create PR: develop -> staging
  2. Merge Process:

    • Merge approved PR to staging branch
    • Automatic triggers: Push to staging triggers deployment
  1. Watch GitHub Actions:

    • Go to https://github.com/ERP-Unlocked/ordermatic/actions
    • Monitor “Deploy to Staging” workflow
    • Ensure components complete successfully:
      • build ✅ (reusable build workflow)
      • deploy-web ✅ (triggers Coolify webhook)
      • deploy-temporal-compose ✅ (updates temporal-worker / ts-temporal-worker when needed)
      • deploy-pdf-worker ✅ only if you are still intentionally exercising the legacy Celery path
      • deploy-pdf-api is no longer a required staging success target
      • deploy-marketing ✅ (deploys to Cloudflare Pages)
  2. Monitor Coolify Deployment:

    • Coolify webhooks automatically trigger deployments
    • Watch deployment progress in Coolify dashboard
    • Verify services update with new images:
      • ghcr.io/ERP-Unlocked/ordermatic/webapp:staging-{sha}
      • ghcr.io/ERP-Unlocked/ordermatic/temporal-worker:staging-{sha} (when Temporal worker changes)
      • ghcr.io/ERP-Unlocked/ordermatic/ts-temporal-worker:staging-{sha} (when TS worker changes)
      • ghcr.io/ERP-Unlocked/ordermatic/pdf-worker:staging-{sha} only if legacy compatibility testing is still enabled
  1. Check Coolify Services:

    • webapp (Port 4321, proxied through 80/443)
    • temporal-worker (PDF extraction worker on pdf-extraction)
    • ts-temporal-worker (non-PDF Temporal workflows)
    • temporal-server / temporal-ui (if managed in the same staging stack)
    • pdf-worker / redis only if you are intentionally keeping the legacy Celery path live during drain-down
    • postgres (Internal, database)
  2. Test Application Functionality:

    • User authentication works (Clerk)
    • PDF upload and processing functional
    • ERP integration systems operational
    • Trigger.dev background jobs running
    • Database connections stable
    • API endpoints responding correctly
  3. Check Marketing Site:

    • Cloudflare Pages deployment successful
    • Marketing site accessible and functional
    • Content updates deployed correctly
  • QA testing completed
  • Product owner sign-off
  • Technical lead approval
  • Performance metrics acceptable

Only after successful staging validation:

  1. Create Production PR:

    Terminal window
    # Create PR: staging -> main
    git checkout main
    git pull origin main
    # Create PR from staging to main
  2. Production PR Process:

    • Enhanced validation: Full security scan, deployment readiness
    • Required approvals: Technical lead + product owner
    • Final verification: All staging tests passed
  3. Merge to Main:

    • Merge approved PR to main branch
    • Automatic triggers: Push to main triggers production deployment
  1. Watch GitHub Actions:

    • Monitor “Deploy to Production” workflow
    • Ensure all components deploy successfully:
      • build ✅ (full production build)
      • deploy-web ✅ (production Coolify webhook)
      • deploy-pdf-api ✅ (production Coolify webhook)
      • deploy-pdf-worker ✅ (production Coolify webhook)
      • deploy-marketing ✅ (production Cloudflare Pages)
  2. Monitor Coolify Production Deployment:

    • Production webhooks trigger deployments
    • Watch services restart with new images:
      • ghcr.io/ERP-Unlocked/ordermatic/webapp:main-{sha}
      • ghcr.io/ERP-Unlocked/ordermatic/pdf-api:main-{sha}
      • ghcr.io/ERP-Unlocked/ordermatic/pdf-worker:main-{sha}
  1. Immediate Checks (0-5 minutes):

    • All services respond to health checks
    • User authentication functional
    • Critical API endpoints operational
    • No spike in error rates
    • Trigger.dev tasks running normally
  2. Extended Verification (5-30 minutes):

    • PDF processing pipeline functional
    • Background jobs processing (ERP sync, thumbnails, etc.)
    • Database performance normal
    • SigNoz observability data flowing
    • Cache systems working correctly
  3. User Acceptance (30+ minutes):

    • Monitor user feedback channels
    • Watch for support tickets
    • Check analytics for unusual patterns
    • Verify business-critical workflows

Coolify deployments are triggered by GitHub Actions webhooks, not direct git integration:

  1. Webhook URLs (configured in repository secrets):

    Terminal window
    COOLIFY_STAGING_WEBHOOK_WEB
    COOLIFY_STAGING_WEBHOOK_PDF_WORKER
    COOLIFY_STAGING_WEBHOOK_PDF_API # optional legacy secret during retirement window
    COOLIFY_PRODUCTION_WEBHOOK_WEB
    COOLIFY_PRODUCTION_WEBHOOK_PDF_API
    COOLIFY_PRODUCTION_WEBHOOK_PDF_WORKER
  2. Webhook Payload:

    {
    "branch": "main",
    "commit": "{github.sha}",
    "tag": "{github.sha}"
    }
  3. Service Configuration:

    • Each service in Coolify has its own webhook endpoint
    • Webhooks trigger image pulls from GHCR
    • Images tagged with branch and commit SHA for traceability

For emergency deployments:

Terminal window
# Example: Manually trigger production webapp deployment
curl -X POST "${COOLIFY_PRODUCTION_WEBHOOK_WEB}" \
-H "Content-Type: application/json" \
-d '{
"branch": "main",
"commit": "abc123...",
"tag": "main-abc123"
}'
  1. Identify Last Stable Deployment:

    Terminal window
    # Check GitHub Actions for last successful deployment
    # Note the commit SHA from successful run
  2. Coolify-Based Rollback:

    • Go to Coolify dashboard
    • For each affected service:
      • Navigate to “Deployments” tab
      • Find previous stable deployment
      • Click “Redeploy” with previous image
  3. Emergency Manual Rollback:

    Terminal window
    # Use previous stable image tags
    curl -X POST "${COOLIFY_PRODUCTION_WEBHOOK_WEB}" \
    -H "Content-Type: application/json" \
    -d '{
    "branch": "main",
    "commit": "PREVIOUS_STABLE_SHA",
    "tag": "main-PREVIOUS_STABLE_SHA"
    }'
  1. Assess Database Changes:

    Terminal window
    cd packages/db
    pnpm run db:check # Check for schema drift
    # Review recent migration files
  2. Execute Database Rollback:

    Terminal window
    cd packages/db
    pnpm run db:rollback # Rollback latest migration
    # OR for multiple rollbacks:
    pnpm run db:rollback --steps=2
  1. Cloudflare Pages Rollback:
    • Navigate to Cloudflare Pages dashboard
    • Select the marketing site project
    • Go to “Deployments” tab
    • Select previous stable deployment
    • Click “Retry deployment” or “Promote to production”
  1. Immediate Actions:

    • Notify development team via Slack/Teams
    • Update internal status page
    • Prepare customer communication if needed
  2. Post-Rollback Process:

    • Document the incident and rollback reason
    • Plan hotfix or remediation strategy
    • Schedule post-mortem meeting
    • Update monitoring and alerting if needed
  1. Set up alerts for:

    • Application response times (SigNoz)
    • Error rates and exceptions
    • Database performance metrics
    • Trigger.dev task execution failures
  2. Monitor dashboards:

    • SigNoz application performance
    • Coolify infrastructure health
    • Trigger.dev background job status
    • User engagement analytics
  1. Core Functionality:

    • User registration/login (Clerk)
    • PDF upload and processing
    • Order creation and management
    • ERP integrations working
    • Background job processing
  2. Performance Verification:

    • Page load times acceptable (<3s)
    • API response times within SLA (<500ms)
    • Database queries optimized
    • Trigger.dev tasks completing successfully
  3. Background Services:

    • ERP sync tasks running (check Trigger.dev dashboard)
    • PDF thumbnail generation working
    • Database cleanup jobs executing
    • Health checks reporting green

Issue: Build validation fails on PR Solution:

  1. Check branch protection workflow logs
  2. Verify conventional commit format
  3. Ensure all required files are present
  4. Run local build to reproduce issue

Issue: Webhook deployment fails Solution:

  1. Verify webhook URLs in repository secrets
  2. Check Coolify webhook endpoint status
  3. Manually trigger webhook to test connectivity
  4. Review webhook payload format

Issue: Service fails to update with new image Solution:

  1. Verify image exists in GHCR with correct tag
  2. Check Coolify logs for pull errors
  3. Restart Coolify deployment manually
  4. Verify network connectivity to GHCR

Issue: Service starts but fails health checks Solution:

  1. Check service logs in Coolify
  2. Verify environment variables are set correctly
  3. Test database connectivity
  4. Check Redis/external service availability

Issue: PR blocked by branch protection Solution:

  1. Check conventional commit format: type: description
  2. Ensure PR description has meaningful content
  3. Verify security scan passes
  4. Fix any linting or type checking errors
Terminal window
# Check service health endpoints
curl -f https://your-webapp-url.com/health
curl -f https://your-api-url.com/health
# Verify Trigger.dev task status
# Visit: https://cloud.trigger.dev/projects/proj_zwlhawgpqrmanfxhquwv
# Database connectivity check
cd packages/db
pnpm run db:check
# Check recent deployments
# Visit: https://github.com/ERP-Unlocked/ordermatic/actions
# Monitor application performance
# Visit: your-signoz-dashboard.com
  • Technical Lead: [Name] - [Contact]
  • DevOps Engineer: [Name] - [Contact]
  • Product Owner: [Name] - [Contact]
  • On-call Engineer: [Name] - [Contact]
Terminal window
# Local development
cd apps/webapp
pnpm run dev # Start webapp (port 4321)
pnpm run dev # Start marketing (port 3001)
# Database operations
cd packages/db
pnpm run db:migrate # Apply migrations
pnpm run db:studio # Open Drizzle Studio
pnpm run db:seed # Seed test data
# Background job testing
cd apps/webapp
pnpm run trigger:dev # Start Trigger.dev development
pnpm run trigger:test # Test monitoring setup
# Build and validation
pnpm run build # Build all apps
pnpm run test # Run all tests
pnpm run lint # Lint all code
  • Create PR with proper format and description
  • Pass all branch protection checks
  • Get code review approval
  • Merge to staging branch
  • Monitor automated deployment
  • Verify staging functionality
  • Complete QA testing
  • Successful staging validation
  • Create staging → main PR
  • Enhanced production validation
  • Required production approvals
  • Merge to main branch
  • Monitor production deployment
  • Complete production verification
  • Monitor post-deployment metrics
  • Verify all services healthy
  • Check background jobs running
  • Monitor error rates and performance
  • Update documentation if needed
  • Communicate deployment success

Note: This deployment process ensures high reliability through automated validation, branch protection, and webhook-based deployments. Always follow the PR-based workflow and never bypass branch protection rules.