E2E Tests on Coolify

Options for running the Docker E2E suite against deployed environments on Coolify.

What we already have

Every PR against main runs the self-contained Docker E2E suite via GitHub Actions. It spins up its own Postgres + app + Playwright stack in RAM, runs all tests, and tears itself down. Nothing touches real infrastructure.

This is the primary gate. If it passes, the code is safe to merge and deploy.

A scheduled GitHub Actions workflow runs the self-contained Docker suite against the main branch every night.

Why:

  • Zero Coolify configuration — fully self-contained.
  • Catches regressions that slipped in without a PR (dependency updates, Dependabot merges).
  • Same controlled environment as CI — results are deterministic and easy to debug.

How: Add a schedule trigger to e2e.yml (or a separate e2e-nightly.yml):

on:
  schedule:
    - cron: '0 2 * * *'
  workflow_dispatch:

Option B — Post-deploy smoke test against the live app

After Coolify deploys, trigger Playwright to run against the real URL. Catches deployment-specific failures: environment config bugs, secrets not set, infrastructure issues.

The challenge: Coolify doesn’t natively trigger GitHub Actions after a deploy. A small bridge is needed.

Step 1 — Add workflow_dispatch input to e2e.yml

on:
  workflow_dispatch:
    inputs:
      target_url:
        description: 'Base URL to test against (leave empty for self-contained run)'
        required: false
        default: ''

Step 2 — Conditionally skip Docker compose if target_url is set

- name: 🧪 Run E2E tests
  run: |
    if [ -n "${{ inputs.target_url }}" ]; then
      npx playwright test
    else
      ./scripts/e2e-ci.sh
    fi
  env:
    E2E_BASE_URL: ${{ inputs.target_url }}
    E2E_TEST_EMAIL: ${{ secrets.E2E_TEST_EMAIL }}
    E2E_TEST_PASSWORD: ${{ secrets.E2E_TEST_PASSWORD }}

Step 3 — Coolify post-deploy webhook

In Coolify → application → Webhooks → add a post-deploy webhook:

POST https://api.github.com/repos/{owner}/{repo}/actions/workflows/e2e.yml/dispatches
Authorization: Bearer <GitHub PAT with workflow scope>
Content-Type: application/json

{
  "ref": "main",
  "inputs": { "target_url": "https://your-app.example.com" }
}

⚠️ The live app needs a real E2E test user. Create one manually (or via a deploy-time seed) and store credentials as GitHub secrets.


Comparison

Nightly self-containedPost-deploy smoke test
EffortMinimal (one cron line)Moderate (PAT + webhook + test user)
Tests real infra
Deterministic⚠️ depends on live state
Blocks deploys❌ (runs after)

Recommendation

Start with Option A. Add Option B when you have specific reason to distrust the deployed environment — e.g. when you start using environment-specific secrets, feature flags, or infrastructure that can drift from the Docker stack.