A complete webhook receiver and UI dashboard for GitLab events.
- CORS-enabled webhook API endpoint
- Optional GitLab token verification
- Live event stream with WebSocket updates
- Dynamic dashboard with:
- Total events
- Live WebSocket client count
- Event type counts
- Source counts
- Recent webhook logs
- Dockerized runtime with Docker Compose
.
|-- app/
| |-- main.py
| `-- store.py
|-- static/
| |-- index.html
| |-- styles.css
| `-- app.js
|-- .env.example
|-- .gitignore
|-- Dockerfile
|-- docker-compose.yml
|-- requirements.txt
`-- README.md
- Python 3.11+ (3.12 recommended)
# from project root
python -m venv .venv
# Windows PowerShell
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
copy .env.example .envuvicorn app.main:app --host 0.0.0.0 --port 8000 --reload- UI:
http://localhost:8000/ - Health:
http://localhost:8000/health - Logs API:
http://localhost:8000/api/logs
- Docker
- Docker Compose
# from project root
copy .env.example .env
docker compose up --build -ddocker compose down- UI:
http://localhost:8000/ - API:
http://localhost:8000/webhook/gitlab
Create .env from .env.example and adjust:
CORS_ALLOW_ORIGINS=*
WEBHOOK_SECRET=replace-me
MAX_EVENTS=1000CORS_ALLOW_ORIGINSsupports comma-separated origins.- Example:
http://localhost:3000,http://localhost:5173
- Example:
- If
WEBHOOK_SECRETis set, incoming headerX-Gitlab-Tokenmust match. MAX_EVENTScontrols in-memory retention limit.
- In GitLab, open your project.
- Go to Settings -> Webhooks.
- Set URL:
http://<your-host>:8000/webhook/gitlab
- Set Secret token:
- Use the same value as
WEBHOOK_SECRETin.env.
- Use the same value as
- Select trigger events (recommended):
- Push events
- Merge request events
- Tag push events
- Pipeline events
- Save webhook.
- Click Test and choose an event.
- Verify dashboard updates at
http://<your-host>:8000/.
$body = @{
object_kind = "push"
event_name = "push"
user_name = "Demo User"
user_username = "demo"
project = @{
name = "sample-project"
path_with_namespace = "group/sample-project"
web_url = "https://gitlab.example.com/group/sample-project"
}
} | ConvertTo-Json -Depth 10
Invoke-RestMethod `
-Uri "http://localhost:8000/webhook/gitlab" `
-Method Post `
-Headers @{ "X-Gitlab-Event" = "Push Hook"; "X-Gitlab-Token" = "replace-me" } `
-ContentType "application/json" `
-Body $bodyIf GitLab cannot reach your local machine:
- Use a tunnel (for example, ngrok or cloudflared)
- Point GitLab webhook URL to your HTTPS tunnel endpoint
- Keep path as
/webhook/gitlab
- Run behind reverse proxy (Nginx/Traefik/Caddy)
- Restrict CORS origins
- Use a strong webhook secret
- Add persistent storage if long-term log history is required
- Add authentication if dashboard is exposed publicly