Add webhook secret troubleshooting docs
- Document that webhook secret must be set in BOTH Coolify AND Gitea - Add verification command to check if secret is configured - Add whyrating-hub to webhook URL table Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
264
CLAUDE.md
264
CLAUDE.md
@@ -128,10 +128,43 @@ Task(subagent_type="general-purpose", prompt="Add services to Homepage...", desc
|
|||||||
| MCP | Purpose |
|
| MCP | Purpose |
|
||||||
|-----|---------|
|
|-----|---------|
|
||||||
| `mcp__coolify__*` | Service management, deployments, env vars |
|
| `mcp__coolify__*` | Service management, deployments, env vars |
|
||||||
|
| `mcp__nocodb__*` | Database operations, table management |
|
||||||
| `mcp__ssh-manager__*` | Direct SSH commands, file transfers |
|
| `mcp__ssh-manager__*` | Direct SSH commands, file transfers |
|
||||||
| `mcp__n8n__*` | Workflow automation (if configured) |
|
| `mcp__n8n__*` | Workflow automation (if configured) |
|
||||||
| `mcp__playwriter__*` | Browser automation fallback (see below) |
|
| `mcp__playwriter__*` | Browser automation fallback (see below) |
|
||||||
|
|
||||||
|
### Adding Remote MCP Servers (HTTP Transport)
|
||||||
|
|
||||||
|
**Use `claude mcp add --transport http` for remote MCP endpoints** - this is the recommended method for services with native MCP support.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Basic syntax
|
||||||
|
claude mcp add --transport http <name> <url> --scope user --header "<header>"
|
||||||
|
|
||||||
|
# Example: NocoDB MCP (globally available)
|
||||||
|
claude mcp add --transport http nocodb http://192.168.1.3:8084/mcp/ncnyir1cy6n9bf5p \
|
||||||
|
--scope user \
|
||||||
|
--header "xc-mcp-token: qjjAXRxuYzRtEn-cA4lbPFi5km_pojTX"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Scope options:**
|
||||||
|
- `--scope user` - Available across all projects (stored in `~/.claude.json`)
|
||||||
|
- `--scope local` - Current project only (default)
|
||||||
|
- `--scope project` - Shared via `.mcp.json` (committed to repo)
|
||||||
|
|
||||||
|
**Why CLI over JSON config:**
|
||||||
|
- JSON config with `mcp-remote` often fails to load tools
|
||||||
|
- CLI `--transport http` handles HTTP endpoints natively
|
||||||
|
- No need for `--allow-http` flag or other workarounds
|
||||||
|
|
||||||
|
**Managing MCP servers:**
|
||||||
|
```bash
|
||||||
|
claude mcp list # List all configured servers
|
||||||
|
claude mcp get nocodb # Get details for specific server
|
||||||
|
claude mcp remove nocodb # Remove a server
|
||||||
|
/mcp # Check status in Claude Code
|
||||||
|
```
|
||||||
|
|
||||||
### ⚠️ STRICT RULE: MCP Research Protocol
|
### ⚠️ STRICT RULE: MCP Research Protocol
|
||||||
|
|
||||||
**When asked to find/recommend new MCPs**, read the detailed guide at `docs/mcp-research-guide.md` which contains:
|
**When asked to find/recommend new MCPs**, read the detailed guide at `docs/mcp-research-guide.md` which contains:
|
||||||
@@ -234,6 +267,7 @@ ssh nuc "docker exec <container_name> <command>"
|
|||||||
| Coolify | 8000 | http://192.168.1.3:8000 | coolify |
|
| Coolify | 8000 | http://192.168.1.3:8000 | coolify |
|
||||||
| Gitea | 3030 | http://192.168.1.3:3030 | gitea-* |
|
| Gitea | 3030 | http://192.168.1.3:3030 | gitea-* |
|
||||||
| Outline | 3080 | http://192.168.1.3:3080 | outline-* |
|
| Outline | 3080 | http://192.168.1.3:3080 | outline-* |
|
||||||
|
| NocoDB | 8084 | http://192.168.1.3:8084 | nocodb-* |
|
||||||
| n8n | 5678 | http://192.168.1.3:5678 | n8n-* |
|
| n8n | 5678 | http://192.168.1.3:5678 | n8n-* |
|
||||||
| Vaultwarden | 8222 | http://192.168.1.3:8222 | vaultwarden-* |
|
| Vaultwarden | 8222 | http://192.168.1.3:8222 | vaultwarden-* |
|
||||||
| Ntfy | 8333 | http://192.168.1.3:8333 | ntfy-* |
|
| Ntfy | 8333 | http://192.168.1.3:8333 | ntfy-* |
|
||||||
@@ -493,6 +527,236 @@ mcp__chrome-devtools__fill(uid="<uid>", value="<text>")
|
|||||||
- Token URL: `http://192.168.1.3:3030/login/oauth/access_token`
|
- Token URL: `http://192.168.1.3:3030/login/oauth/access_token`
|
||||||
- Userinfo URL: `http://192.168.1.3:3030/login/oauth/userinfo`
|
- Userinfo URL: `http://192.168.1.3:3030/login/oauth/userinfo`
|
||||||
|
|
||||||
|
## Gitea-Coolify Integration (Git Auto-Deploy)
|
||||||
|
|
||||||
|
Deploy Next.js apps from self-hosted Gitea with auto-deploy on push. Full docs: `docs/gitea-coolify-auto-deploy.md`
|
||||||
|
|
||||||
|
### ⚠️ CRITICAL: Gitea Webhook Allowed Hosts
|
||||||
|
|
||||||
|
**Gitea blocks webhooks to internal hosts by default!** Before setting up webhooks, configure `ALLOWED_HOST_LIST` in Gitea's app.ini:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Edit Gitea config
|
||||||
|
ssh nuc "docker exec gitea-ho0cwgcwos88cwc48g84c0g8 vi /data/gitea/conf/app.ini"
|
||||||
|
|
||||||
|
# Add/modify [webhook] section:
|
||||||
|
[webhook]
|
||||||
|
ALLOWED_HOST_LIST = coolify,10.0.1.5,192.168.1.3,localhost,host.docker.internal,external
|
||||||
|
|
||||||
|
# Restart Gitea
|
||||||
|
ssh nuc "docker restart gitea-ho0cwgcwos88cwc48g84c0g8"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Without this, webhooks fail with:** `webhook can only call allowed HTTP servers`
|
||||||
|
|
||||||
|
### Key References
|
||||||
|
|
||||||
|
| Resource | Value |
|
||||||
|
|----------|-------|
|
||||||
|
| **Deploy Key UUID** | `akssgwowsccgwgoggs4ks8ck` |
|
||||||
|
| **Gitea Container** | `gitea-ho0cwgcwos88cwc48g84c0g8` |
|
||||||
|
| **Webhook Secret** | `9eb07a77964563378c5d66d99006e06ba3da39d232905d4b12554ff91ca39718` |
|
||||||
|
|
||||||
|
### ⚠️ CRITICAL: Webhook Secret Must Be Set in BOTH Places
|
||||||
|
|
||||||
|
**Auto-deploy won't work unless the webhook secret is configured in BOTH Coolify AND Gitea!**
|
||||||
|
|
||||||
|
**Step 1: Set secret in Coolify** (via tinker or when creating app):
|
||||||
|
```bash
|
||||||
|
ssh nuc "docker exec coolify php artisan tinker --execute=\"
|
||||||
|
use App\\Models\\Application;
|
||||||
|
\\\$app = Application::where('uuid', '<app-uuid>')->first();
|
||||||
|
\\\$app->manual_webhook_secret_gitea = '9eb07a77964563378c5d66d99006e06ba3da39d232905d4b12554ff91ca39718';
|
||||||
|
\\\$app->save();
|
||||||
|
\""
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: Set secret in Gitea webhook**:
|
||||||
|
1. Go to repo → Settings → Webhooks → Add/Edit Webhook
|
||||||
|
2. Target URL: `http://coolify:8080/webhooks/source/gitea/events/manual?uuid=<app-uuid>`
|
||||||
|
3. Secret: `9eb07a77964563378c5d66d99006e06ba3da39d232905d4b12554ff91ca39718`
|
||||||
|
4. Trigger: Push Events
|
||||||
|
5. Active: ✓
|
||||||
|
|
||||||
|
**Common symptom when secret is missing:** Git pushes succeed but no deployment is triggered. Check:
|
||||||
|
```bash
|
||||||
|
# Verify Coolify has the secret
|
||||||
|
ssh nuc "docker exec coolify php artisan tinker --execute=\"
|
||||||
|
use App\\Models\\Application;
|
||||||
|
\\\$app = Application::where('uuid', '<app-uuid>')->first();
|
||||||
|
echo 'Secret: ' . (\\\$app->manual_webhook_secret_gitea ? 'SET' : 'MISSING');
|
||||||
|
\""
|
||||||
|
```
|
||||||
|
|
||||||
|
### Local Development (Clone & Push)
|
||||||
|
|
||||||
|
SSH config is set up for direct git operations:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone a repo
|
||||||
|
git clone gitea:nuc/nuc-portal.git
|
||||||
|
|
||||||
|
# Push changes (triggers auto-deploy via webhook)
|
||||||
|
git push origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
**SSH Host Config** (in `~/.ssh/config`):
|
||||||
|
```
|
||||||
|
Host gitea
|
||||||
|
HostName 192.168.1.3
|
||||||
|
Port 22222
|
||||||
|
User git
|
||||||
|
IdentityFile ~/.ssh/id_ed25519_nuc
|
||||||
|
```
|
||||||
|
|
||||||
|
### Webhook URL Format (MUST include UUID and use port 8080!)
|
||||||
|
|
||||||
|
```
|
||||||
|
http://coolify:8080/webhooks/source/gitea/events/manual?uuid=<app-uuid>
|
||||||
|
```
|
||||||
|
|
||||||
|
**⚠️ Port 8080 is required** - Coolify listens on 8080 internally (not 8000, which is the external mapping).
|
||||||
|
|
||||||
|
| App | UUID | Webhook URL |
|
||||||
|
|-----|------|-------------|
|
||||||
|
| nuc-portal | `t80w0cw0oooc4g0soswos4so` | `...?uuid=t80w0cw0oooc4g0soswos4so` |
|
||||||
|
| whyrating-hub | `vw4ggc40socwkgwg4osc8wg8` | `...?uuid=vw4ggc40socwkgwg4osc8wg8` |
|
||||||
|
| whyrating-brand | `r80gk0ccgg0okos8cw848kkk` | `...?uuid=r80gk0ccgg0okos8cw848kkk` |
|
||||||
|
| whyrating-templates | `qw80g4sog0kk8cc4wkcs8sgc` | `...?uuid=qw80g4sog0kk8cc4wkcs8sgc` |
|
||||||
|
|
||||||
|
### Quick Deploy (Next.js)
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 1. Create application with deploy key
|
||||||
|
mcp__coolify__application(
|
||||||
|
action="create_key",
|
||||||
|
name="my-app",
|
||||||
|
project_uuid="a8484ggc88c40w4g4k004ow0",
|
||||||
|
environment_name="production",
|
||||||
|
server_uuid="qk84w0goo4w48g4ggsoo0oss",
|
||||||
|
git_repository="git@gitea-ho0cwgcwos88cwc48g84c0g8:nuc/<repo>.git",
|
||||||
|
git_branch="main",
|
||||||
|
build_pack="nixpacks",
|
||||||
|
ports_exposes="3000",
|
||||||
|
private_key_uuid="akssgwowsccgwgoggs4ks8ck"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 2. Set FQDN
|
||||||
|
ssh nuc "docker exec coolify php artisan tinker --execute=\"
|
||||||
|
use App\Models\Application;
|
||||||
|
\\\$app = Application::where('uuid', '<app-uuid>')->first();
|
||||||
|
\\\$app->fqdn = 'http://<name>.nuc.lan';
|
||||||
|
\\\$app->custom_labels = null;
|
||||||
|
\\\$app->save();
|
||||||
|
\""
|
||||||
|
|
||||||
|
# 3. Set webhook secret
|
||||||
|
ssh nuc "docker exec coolify php artisan tinker --execute=\"
|
||||||
|
use App\Models\Application;
|
||||||
|
\\\$app = Application::where('uuid', '<app-uuid>')->first();
|
||||||
|
\\\$app->manual_webhook_secret_gitea = '9eb07a77964563378c5d66d99006e06ba3da39d232905d4b12554ff91ca39718';
|
||||||
|
\\\$app->save();
|
||||||
|
\""
|
||||||
|
|
||||||
|
# 4. Create webhook in Gitea (via browser or API):
|
||||||
|
# URL: http://coolify:8080/webhooks/source/gitea/events/manual?uuid=<app-uuid>
|
||||||
|
# (Use port 8080, NOT 8000 - 8080 is the internal container port)
|
||||||
|
# Secret: 9eb07a77964563378c5d66d99006e06ba3da39d232905d4b12554ff91ca39718
|
||||||
|
# Trigger: Push Events
|
||||||
|
|
||||||
|
# 5. Deploy
|
||||||
|
mcp__coolify__deploy(tag_or_uuid="<app-uuid>")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deploy Key (add to each new repo)
|
||||||
|
|
||||||
|
```
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGHtsL3jicJTsBekYuwbKjO0EcRadYKhvLSUw/36XF7h coolify-gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
Add via Gitea: Repository → Settings → Deploy Keys → **Enable Write Access** ✓
|
||||||
|
|
||||||
|
### ✅ New Repo Auto-Deploy Checklist
|
||||||
|
|
||||||
|
When creating a new repo that should auto-deploy:
|
||||||
|
|
||||||
|
1. **[ ] Add deploy key to Gitea repo**
|
||||||
|
- Go to: `http://192.168.1.3:3030/nuc/<repo>/settings/keys`
|
||||||
|
- Add the deploy key above with **Write Access** enabled
|
||||||
|
|
||||||
|
2. **[ ] Create Coolify application** (use `mcp__coolify__application` with `action="create_key"`)
|
||||||
|
|
||||||
|
3. **[ ] Set FQDN** via tinker command
|
||||||
|
|
||||||
|
4. **[ ] Set webhook secret** via tinker command (use shared secret above)
|
||||||
|
|
||||||
|
5. **[ ] Create Gitea webhook**
|
||||||
|
- Go to: `http://192.168.1.3:3030/nuc/<repo>/settings/hooks`
|
||||||
|
- Add Webhook → Gitea
|
||||||
|
- **URL:** `http://coolify:8080/webhooks/source/gitea/events/manual?uuid=<app-uuid>`
|
||||||
|
- **Secret:** `9eb07a77964563378c5d66d99006e06ba3da39d232905d4b12554ff91ca39718`
|
||||||
|
- **Trigger:** Push Events
|
||||||
|
- **Active:** ✓
|
||||||
|
|
||||||
|
6. **[ ] Test webhook** - Click "Test Delivery" and verify HTTP 200 response
|
||||||
|
|
||||||
|
7. **[ ] Initial deploy** - `mcp__coolify__deploy(tag_or_uuid="<app-uuid>")`
|
||||||
|
|
||||||
|
**Common mistakes:**
|
||||||
|
- ❌ Using port 8000 instead of 8080 in webhook URL
|
||||||
|
- ❌ Forgetting `?uuid=<app-uuid>` in webhook URL
|
||||||
|
- ❌ Not enabling Write Access on deploy key
|
||||||
|
|
||||||
|
### Quick Verification Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check Gitea has [webhook] section configured
|
||||||
|
ssh nuc "docker exec gitea-ho0cwgcwos88cwc48g84c0g8 cat /data/gitea/conf/app.ini | grep -A2 '\[webhook\]'"
|
||||||
|
|
||||||
|
# Test Coolify is reachable from Gitea (should return HTML)
|
||||||
|
ssh nuc "docker exec gitea-ho0cwgcwos88cwc48g84c0g8 wget -qO- --timeout=5 http://coolify:8080/ | head -5"
|
||||||
|
|
||||||
|
# Check Gitea is on coolify network
|
||||||
|
ssh nuc "docker inspect gitea-ho0cwgcwos88cwc48g84c0g8 --format '{{json .NetworkSettings.Networks}}' | jq -r 'keys[]'"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Why NOT "Gitea Source"
|
||||||
|
|
||||||
|
Coolify's "Gitea Source" uses GitHub App-style OAuth with JWT - **this doesn't work with Gitea**. Use deploy keys + manual webhooks instead.
|
||||||
|
|
||||||
|
### Current Deployed Apps
|
||||||
|
|
||||||
|
| App | URL | Repository | UUID |
|
||||||
|
|-----|-----|------------|------|
|
||||||
|
| nuc-portal | http://nuc.lan | `nuc/nuc-portal` | `t80w0cw0oooc4g0soswos4so` |
|
||||||
|
| whyrating-hub | http://whyrating.nuc.lan | `nuc/whyrating-hub` | `vw4ggc40socwkgwg4osc8wg8` |
|
||||||
|
| whyrating-brand | http://brand.nuc.lan | `nuc/whyrating-brand` | `r80gk0ccgg0okos8cw848kkk` |
|
||||||
|
| whyrating-templates | http://templates.nuc.lan | `nuc/whyrating-templates` | `qw80g4sog0kk8cc4wkcs8sgc` |
|
||||||
|
|
||||||
|
### New Site from nuc-portal Template
|
||||||
|
|
||||||
|
To create a new Next.js site using nuc-portal as a base:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Copy and clean
|
||||||
|
cp -r /path/to/nuc-portal /path/to/new-site
|
||||||
|
cd /path/to/new-site
|
||||||
|
rm -rf .git .next node_modules
|
||||||
|
|
||||||
|
# 2. Update package.json (name, description)
|
||||||
|
# 3. Customize src/app/page.tsx
|
||||||
|
# 4. Remove unused components if simplifying
|
||||||
|
|
||||||
|
# 5. Initialize and push
|
||||||
|
npm install && npm run build # verify it builds
|
||||||
|
git init && git add -A && git commit -m "Initial commit"
|
||||||
|
# Create repo in Gitea first, then:
|
||||||
|
git remote add origin gitea:nuc/<repo-name>.git
|
||||||
|
git push -u origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
Then follow the "New Repo Auto-Deploy Checklist" above.
|
||||||
|
|
||||||
## Public Access & Security Architecture
|
## Public Access & Security Architecture
|
||||||
|
|
||||||
**Full architecture details:** `docs/architecture.md`
|
**Full architecture details:** `docs/architecture.md`
|
||||||
|
|||||||
Reference in New Issue
Block a user