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.
Option A — Nightly run on main (Recommended)
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-contained | Post-deploy smoke test | |
|---|---|---|
| Effort | Minimal (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.