Add operational documentation
CloudBeaver database manager guide, Ecija intranet deployment, Gitea-Coolify auto-deploy and integration docs, monitoring setup with presentation, remote access guide, security architecture, and Turbostarter deployment procedure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
250
docs/gitea-coolify-auto-deploy.md
Normal file
250
docs/gitea-coolify-auto-deploy.md
Normal file
@@ -0,0 +1,250 @@
|
||||
# Gitea-Coolify Auto-Deploy Guide
|
||||
|
||||
Automatic deployment on git push using Coolify's manual webhook integration with self-hosted Gitea.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Developer → git push → Gitea → Webhook → Coolify → Build & Deploy
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### 1. Deploy Key for Git Access
|
||||
|
||||
Apps use SSH deploy keys to pull code from Gitea:
|
||||
|
||||
| Resource | Value |
|
||||
|----------|-------|
|
||||
| **Deploy Key UUID** | `akssgwowsccgwgoggs4ks8ck` |
|
||||
| **Gitea Container** | `gitea-ho0cwgcwos88cwc48g84c0g8` |
|
||||
| **SSH Port** | 22222 (external) → 22 (internal) |
|
||||
|
||||
### 2. Network Connectivity
|
||||
|
||||
Gitea container must be on the `coolify` network:
|
||||
|
||||
```bash
|
||||
docker network connect coolify gitea-ho0cwgcwos88cwc48g84c0g8
|
||||
```
|
||||
|
||||
### 3. ⚠️ CRITICAL: Gitea Webhook Allowed Hosts
|
||||
|
||||
**Gitea blocks webhooks to internal hosts by default.** You MUST configure `ALLOWED_HOST_LIST` in Gitea's app.ini.
|
||||
|
||||
```bash
|
||||
# Add [webhook] section to Gitea's app.ini
|
||||
ssh nuc "docker exec gitea-ho0cwgcwos88cwc48g84c0g8 sh -c 'echo \"\" >> /data/gitea/conf/app.ini && echo \"[webhook]\" >> /data/gitea/conf/app.ini && echo \"ALLOWED_HOST_LIST = coolify,10.0.1.5,192.168.1.3,localhost,host.docker.internal,external\" >> /data/gitea/conf/app.ini'"
|
||||
|
||||
# Restart Gitea
|
||||
ssh nuc "docker restart gitea-ho0cwgcwos88cwc48g84c0g8"
|
||||
|
||||
# Verify
|
||||
ssh nuc "docker exec gitea-ho0cwgcwos88cwc48g84c0g8 cat /data/gitea/conf/app.ini | grep -A2 '\[webhook\]'"
|
||||
```
|
||||
|
||||
**Without this, webhooks will fail with:**
|
||||
```
|
||||
dial tcp 10.0.1.5:8080: webhook can only call allowed HTTP servers
|
||||
(check your webhook.ALLOWED_HOST_LIST setting), deny 'coolify(10.0.1.5:8080)'
|
||||
```
|
||||
|
||||
### 4. ⚠️ CRITICAL: Use Internal Port 8080
|
||||
|
||||
**Coolify listens on port 8080 internally**, not 8000. Port 8000 is only the external Docker port mapping.
|
||||
|
||||
| Context | Port | URL Example |
|
||||
|---------|------|-------------|
|
||||
| From Docker network (Gitea webhook) | **8080** | `http://coolify:8080/webhooks/...` |
|
||||
| From external/browser | 8000 | `http://192.168.1.3:8000` |
|
||||
|
||||
## Creating an App with Auto-Deploy
|
||||
|
||||
### Step 1: Create Application with Deploy Key
|
||||
|
||||
```python
|
||||
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"
|
||||
)
|
||||
```
|
||||
|
||||
### Step 2: Configure FQDN
|
||||
|
||||
```bash
|
||||
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->base_directory = '/';
|
||||
\\\$app->save();
|
||||
\""
|
||||
```
|
||||
|
||||
### Step 3: Generate and Set Webhook Secret
|
||||
|
||||
```bash
|
||||
# Generate a secret
|
||||
SECRET=$(openssl rand -hex 32)
|
||||
echo "Webhook Secret: $SECRET"
|
||||
|
||||
# Set in Coolify
|
||||
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 = '$SECRET';
|
||||
\\\$app->save();
|
||||
echo 'Set webhook secret for ' . \\\$app->name;
|
||||
\""
|
||||
```
|
||||
|
||||
### Step 4: Create Webhook in Gitea
|
||||
|
||||
1. Go to `http://192.168.1.3:3030/nuc/<repo>/settings/hooks`
|
||||
2. Click **Add Webhook** → **Gitea**
|
||||
3. Configure:
|
||||
- **Target URL:** `http://coolify:8080/webhooks/source/gitea/events/manual?uuid=<app-uuid>`
|
||||
- **Secret:** The secret generated in Step 3
|
||||
- **Trigger On:** Push Events
|
||||
- **Active:** ✓
|
||||
4. Click **Add Webhook**
|
||||
|
||||
**⚠️ IMPORTANT:** The webhook URL MUST include `?uuid=<app-uuid>` - without it, Coolify won't know which app to deploy!
|
||||
|
||||
### Step 5: Initial Deploy
|
||||
|
||||
```python
|
||||
mcp__coolify__deploy(tag_or_uuid="<app-uuid>")
|
||||
```
|
||||
|
||||
### Step 6: Test Webhook
|
||||
|
||||
In Gitea webhook settings, click **Test Delivery**. Check:
|
||||
- Response should be `200 OK`
|
||||
- Coolify should show a new deployment queued
|
||||
|
||||
## Webhook URL Format
|
||||
|
||||
**Correct format (use port 8080 for internal Docker network):**
|
||||
```
|
||||
http://coolify:8080/webhooks/source/gitea/events/manual?uuid=<app-uuid>
|
||||
```
|
||||
|
||||
| App | UUID | Webhook URL |
|
||||
|-----|------|-------------|
|
||||
| nuc-portal | `t80w0cw0oooc4g0soswos4so` | `http://coolify:8080/webhooks/source/gitea/events/manual?uuid=t80w0cw0oooc4g0soswos4so` |
|
||||
| whyrating-hub | `vw4ggc40socwkgwg4osc8wg8` | `http://coolify:8080/webhooks/source/gitea/events/manual?uuid=vw4ggc40socwkgwg4osc8wg8` |
|
||||
| whyrating-brand | `r80gk0ccgg0okos8cw848kkk` | `http://coolify:8080/webhooks/source/gitea/events/manual?uuid=r80gk0ccgg0okos8cw848kkk` |
|
||||
| whyrating-templates | `qw80g4sog0kk8cc4wkcs8sgc` | `http://coolify:8080/webhooks/source/gitea/events/manual?uuid=qw80g4sog0kk8cc4wkcs8sgc` |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Webhook Returns "dial tcp ... webhook can only call allowed HTTP servers"
|
||||
|
||||
**Cause:** Gitea's webhook security blocks internal hosts by default.
|
||||
|
||||
**Fix:** Add Coolify to Gitea's allowed host list:
|
||||
|
||||
```bash
|
||||
# Check current app.ini
|
||||
ssh nuc "docker exec gitea-ho0cwgcwos88cwc48g84c0g8 cat /data/gitea/conf/app.ini | grep -A5 '\[webhook\]'"
|
||||
|
||||
# Edit app.ini to add:
|
||||
[webhook]
|
||||
ALLOWED_HOST_LIST = coolify,10.0.1.5,192.168.1.3,localhost,host.docker.internal,external
|
||||
|
||||
# Or allow all private IPs (less secure):
|
||||
ALLOWED_HOST_LIST = private
|
||||
|
||||
# Restart Gitea
|
||||
ssh nuc "docker restart gitea-ho0cwgcwos88cwc48g84c0g8"
|
||||
```
|
||||
|
||||
### Webhook Returns 404 or No Deployment
|
||||
|
||||
**Cause:** Missing `?uuid=` parameter in webhook URL.
|
||||
|
||||
**Fix:** Ensure URL includes the app UUID:
|
||||
```
|
||||
http://coolify:8080/webhooks/source/gitea/events/manual?uuid=<app-uuid>
|
||||
```
|
||||
|
||||
### Webhook Returns "Connection Refused" (dial tcp ... connection refused)
|
||||
|
||||
**Cause:** Using external port 8000 instead of internal port 8080.
|
||||
|
||||
**Fix:** Coolify's nginx listens on port **8080** inside the container, not 8000. Change:
|
||||
```
|
||||
# Wrong (external port)
|
||||
http://coolify:8000/webhooks/...
|
||||
|
||||
# Correct (internal port)
|
||||
http://coolify:8080/webhooks/...
|
||||
```
|
||||
|
||||
### Webhook Returns 401 Unauthorized
|
||||
|
||||
**Cause:** Webhook secret mismatch.
|
||||
|
||||
**Fix:** Verify the secret matches in both Gitea and Coolify:
|
||||
```bash
|
||||
# Check Coolify
|
||||
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;
|
||||
\""
|
||||
```
|
||||
|
||||
### Webhook Delivers but Deployment Fails
|
||||
|
||||
Check Coolify logs:
|
||||
```bash
|
||||
ssh nuc "docker logs coolify 2>&1 | grep -i 'deploy\|webhook' | tail -30"
|
||||
```
|
||||
|
||||
Common issues:
|
||||
- Git pull fails: Check deploy key is added to repo
|
||||
- Build fails: Check application logs in Coolify UI
|
||||
|
||||
## Current Configuration
|
||||
|
||||
### Shared Webhook Secret
|
||||
|
||||
All apps use the same webhook secret for simplicity:
|
||||
```
|
||||
9eb07a77964563378c5d66d99006e06ba3da39d232905d4b12554ff91ca39718
|
||||
```
|
||||
|
||||
### Deploy Key (add to each new repo)
|
||||
|
||||
```
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGHtsL3jicJTsBekYuwbKjO0EcRadYKhvLSUw/36XF7h coolify-gitea
|
||||
```
|
||||
|
||||
Add via Gitea: Repository → Settings → Deploy Keys → **Enable Write Access** ✓
|
||||
|
||||
## Why Not "Gitea Source"?
|
||||
|
||||
Coolify has a "Gitea Source" feature that attempts to use GitHub App-style OAuth. This **does not work well** with self-hosted Gitea because:
|
||||
|
||||
1. Gitea's OAuth2 is simpler than GitHub Apps (no JWT signing with private keys)
|
||||
2. The credentials stored in Coolify are invalid/fake
|
||||
3. Deployments fail with JWT parsing errors
|
||||
|
||||
**Use deploy keys + manual webhooks instead** - it's simpler and more reliable.
|
||||
|
||||
## References
|
||||
|
||||
- [Coolify CI/CD Gitea Integration](https://coolify.io/docs/applications/ci-cd/gitea/integration)
|
||||
- [Gitea Webhooks Documentation](https://docs.gitea.com/usage/webhooks)
|
||||
- [Gitea app.ini Cheat Sheet](https://docs.gitea.com/administration/config-cheat-sheet#webhook-webhook)
|
||||
Reference in New Issue
Block a user