docs: comprehensive README with setup, usage, and pitfalls

This commit is contained in:
2026-09-13 10:19:22 +02:00
parent 205d3a462d
commit 5415254034
+126 -3
View File
@@ -8,8 +8,131 @@ Lightweight webhook container for NAS auto-deploy. Alpine-based with `docker-cli
registry.gitlab.com/bgrolleman/nas-webhook:latest
```
## Usage
Built automatically by GitLab CI on every push to `main`. Image is **public** — no registry login needed on the NAS to pull it.
See the [webhook documentation](https://github.com/adnanh/webhook) for hook configuration.
## How it works
Requires `/var/run/docker.sock` mounted to execute Docker commands from within the container.
1. A GitLab CI pipeline builds and pushes a new image (e.g. `hugo_basg.nl:latest`)
2. The CI pipeline sends a POST to `http://webhook.nas.basg.nl/hooks/<hook-id>` with a secret token in the `X-Webhook-Token` header
3. The webhook container receives the request, validates the token, and runs `deploy.sh <compose-dir>`
4. `deploy.sh` does `docker compose pull && docker compose up -d` in the project directory
## Deployment on NAS
Place the following files in a directory on the NAS (e.g. `/volume1/docker/webhook/`):
```
webhook/
├── docker-compose.yml
├── hooks.json
└── scripts/
└── deploy.sh
```
Then bring it up via the UGREEN web interface or `docker compose up -d`.
The Docker socket (`/var/run/docker.sock`) must be mounted so the container can run Docker commands. The NAS docker directory (`/volume1/docker`) must also be mounted so `deploy.sh` can reach the project compose files.
### docker-compose.yml
```yaml
networks:
external:
external: true
services:
webhook:
image: registry.gitlab.com/bgrolleman/nas-webhook:latest
restart: always
command: ["-hooks", "/config/hooks.json", "-verbose", "-hotreload"]
volumes:
- ./hooks.json:/config/hooks.json:ro
- ./scripts:/scripts:ro
- /var/run/docker.sock:/var/run/docker.sock
- /volume1/docker:/volume1/docker
expose:
- 9000
environment:
- VIRTUAL_HOST=webhook.nas.basg.nl
- VIRTUAL_PORT=9000
networks:
- external
```
Note: No `LETSENCRYPT_HOST` — running HTTP only. The ACME challenge (Let's Encrypt) doesn't work for this container because it only exposes port 9000, not 80. Since it's only called by GitLab CI (not a browser), HTTP is fine.
## Adding a new project
### 1. Add a hook to `hooks.json`
```json
{
"id": "my-project",
"execute-command": "/scripts/deploy.sh",
"command-working-directory": "/scripts",
"pass-arguments-to-command": [
{
"source": "string",
"name": "/volume1/docker/my-project"
}
],
"trigger-rule": {
"match": {
"type": "value",
"value": "YOUR_SECRET_TOKEN_HERE",
"parameter": {
"source": "header",
"name": "X-Webhook-Token"
}
}
}
}
```
Generate a token with: `openssl rand -hex 32`
The webhook container uses `-hotreload` so it picks up `hooks.json` changes without a restart.
### 2. Add deploy stage to the project's `.gitlab-ci.yml`
Store the token as a masked CI variable (e.g. `DEPLOY_WEBHOOK_TOKEN`) in the GitLab project settings.
```yaml
deploy:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache curl
script:
- |
curl -f -X POST \
-H "X-Webhook-Token: $DEPLOY_WEBHOOK_TOKEN" \
http://webhook.nas.basg.nl/hooks/my-project
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
needs: [build]
```
### 3. Make sure the project image is public
The NAS pulls images without authentication. Either make the GitLab registry public (project → Settings → General → Visibility → Public) or set up a deploy token and run `sudo docker login registry.gitlab.com` on the NAS.
## Testing a hook manually
```bash
curl -X POST \
-H "X-Webhook-Token: YOUR_TOKEN" \
http://webhook.nas.basg.nl/hooks/your-hook-id
```
## Current hooks
| Hook ID | Project | Compose dir |
|---------|---------|-------------|
| `hugo-basg` | bgrolleman/hugo_basg.nl | `/volume1/docker/basg-hugo` |
## Known issues / pitfalls
- **No HTTPS**: Let's Encrypt won't issue a cert because the container doesn't serve HTTP on port 80. Since only GitLab CI calls this endpoint, HTTP is acceptable. If HTTPS is needed in the future, put a separate nginx container in front that handles port 80/443 and proxies to port 9000.
- **Docker socket permissions**: The webhook runs as root inside the container (required to use the socket). This is standard for Docker-in-Docker patterns on a home NAS.
- **Image must be public or NAS must be logged in**: The deploy script runs `docker compose pull` which needs registry access. Easiest solution is a public GitLab project.