12 KiB
Webhook Notifications
ComposeSync can send webhook notifications for various events, including enhanced Git context information.
Configuration
Set the webhook URL in your configuration:
[global]
NOTIFICATION_WEBHOOK_URL = "https://your-webhook-url.com/endpoint"
Or in .env format:
NOTIFICATION_WEBHOOK_URL=https://your-webhook-url.com/endpoint
Webhook Events
ComposeSync sends notifications for the following events:
| Event | Description | When Sent |
|---|---|---|
update_success |
Stack updated successfully | After successful docker compose up |
update_failure |
Update failed, rollback initiated | When docker compose up fails |
rollback_success |
Rollback completed successfully | After successful rollback |
rollback_failure |
Rollback failed | When rollback also fails |
dry_run |
Dry-run mode simulation | When DRY_RUN=true |
Webhook Payload
Each webhook notification includes:
{
"event": "update_success",
"stack_name": "immich",
"timestamp": "2024-01-15T10:30:00Z",
"message": "Successfully updated stack immich",
"version_id": "abc1234",
"diff": "- old line\n+ new line\n...",
"git_context": "Commit: abc1234 - Update dependencies (Ref: main) | Repo: immich-app"
}
Payload Fields
| Field | Description | Example |
|---|---|---|
event |
Event type | update_success |
stack_name |
Name of the stack | immich |
timestamp |
ISO 8601 timestamp | 2024-01-15T10:30:00Z |
message |
Human-readable message | Successfully updated stack immich |
version_id |
Version identifier | abc1234 (Git commit) or 20240115103000 (timestamp) |
diff |
Changes applied (truncated to 50 lines) | - old line\n+ new line |
git_context |
Git information (for Git repositories) | `Commit: abc1234 - Update deps (Ref: main) |
Git Context Information
For Git repositories, the git_context field provides:
- Commit hash: Short commit hash
- Commit message: First 100 characters of commit message
- Reference: Branch, tag, or commit hash being tracked
- Repository: Repository name (sanitized)
Example Git context:
Commit: abc1234 - Update dependencies and fix security issues (Ref: main) | Repo: immich-app
Testing Webhooks
You can test webhook notifications using services like:
- webhook.site - Temporary webhook endpoints
- ngrok - Expose local endpoints
- Discord webhooks
- Slack webhooks
Example: Discord Integration
[global]
NOTIFICATION_WEBHOOK_URL = "https://discord.com/api/webhooks/YOUR_WEBHOOK_URL"
Example: Slack Integration
[global]
NOTIFICATION_WEBHOOK_URL = "https://hooks.slack.com/services/YOUR_WEBHOOK_URL"
Error Handling
- Webhook failures don't stop the update process
- Failed webhook requests are logged but don't cause errors
- Network timeouts are handled gracefully
Overview
Webhook notifications provide:
- Real-time updates on stack changes
- Error notifications for failed updates
- Integration with monitoring systems
- Diff output showing what changed
- Support for dry-run mode notifications
TOML Configuration
Global Webhook Configuration
Configure webhooks for all stacks in your TOML file:
# Global settings
[global]
UPDATE_INTERVAL_SECONDS = 3600
KEEP_VERSIONS = 10
DRY_RUN = false
NOTIFICATION_WEBHOOK_URL = "https://your-webhook-url.com/endpoint"
# Stack configurations
[immich]
URL = "https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml"
PATH = "/opt/composesync/stacks/immich"
TOOL = "wget"
[dev-app]
URL = "https://github.com/user/dev-app.git"
PATH = "/opt/composesync/stacks/dev-app"
TOOL = "git"
GIT_SUBPATH = "docker/docker-compose.yml"
GIT_REF = "develop"
Per-Stack Webhook Configuration
Override webhook settings for specific stacks:
# Global settings
[global]
UPDATE_INTERVAL_SECONDS = 3600
KEEP_VERSIONS = 10
NOTIFICATION_WEBHOOK_URL = "https://default-webhook.com/endpoint"
# Production stack (use global webhook)
[immich]
URL = "https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml"
PATH = "/opt/composesync/stacks/immich"
TOOL = "wget"
# Development stack (different webhook)
[dev-app]
URL = "https://github.com/user/dev-app.git"
PATH = "/opt/composesync/stacks/dev-app"
TOOL = "git"
GIT_SUBPATH = "docker/docker-compose.yml"
GIT_REF = "develop"
NOTIFICATION_WEBHOOK_URL = "https://dev-webhook.com/endpoint"
Legacy .env Configuration
Global Webhook Configuration
# Global settings
UPDATE_INTERVAL_SECONDS=3600
KEEP_VERSIONS=10
DRY_RUN=false
NOTIFICATION_WEBHOOK_URL=https://your-webhook-url.com/endpoint
# Stack configurations
STACKS=2
STACK_1_NAME=immich
STACK_1_URL=https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
STACK_1_PATH=/opt/composesync/stacks/immich
STACK_1_TOOL=wget
STACK_2_NAME=dev-app
STACK_2_URL=https://github.com/user/dev-app.git
STACK_2_PATH=/opt/composesync/stacks/dev-app
STACK_2_TOOL=git
STACK_2_GIT_SUBPATH=docker/docker-compose.yml
STACK_2_GIT_REF=develop
Per-Stack Webhook Configuration
# Global settings
UPDATE_INTERVAL_SECONDS=3600
KEEP_VERSIONS=10
NOTIFICATION_WEBHOOK_URL=https://default-webhook.com/endpoint
# Stack configurations
STACKS=2
# Production stack (use global webhook)
STACK_1_NAME=immich
STACK_1_URL=https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
STACK_1_PATH=/opt/composesync/stacks/immich
STACK_1_TOOL=wget
# Development stack (different webhook)
STACK_2_NAME=dev-app
STACK_2_URL=https://github.com/user/dev-app.git
STACK_2_PATH=/opt/composesync/stacks/dev-app
STACK_2_TOOL=git
STACK_2_GIT_SUBPATH=docker/docker-compose.yml
STACK_2_GIT_REF=develop
STACK_2_NOTIFICATION_WEBHOOK_URL=https://dev-webhook.com/endpoint
Webhook Payload Format
ComposeSync sends JSON payloads with the following structure:
{
"event": "update_success",
"stack_name": "immich",
"timestamp": "2024-01-15T10:30:02Z",
"message": "Successfully updated stack immich",
"version_id": "20240115103002",
"diff": "--- a/docker-compose.yml\n+++ b/docker-compose.yml\n@@ -15,7 +15,7 @@ services:\n immich-server:\n- image: ghcr.io/immich-app/immich-server:release\n+ image: ghcr.io/immich-app/immich-server:v1.75.0\n"
}
Event Types
| Event | Description | When Sent |
|---|---|---|
update_success |
Stack updated successfully | After successful update |
update_failure |
Stack update failed | After failed update (with rollback) |
dry_run |
Dry-run mode notification | When dry-run mode is enabled |
Payload Fields
| Field | Type | Description |
|---|---|---|
event |
string | Event type (update_success, update_failure, dry_run) |
stack_name |
string | Name of the stack being updated |
timestamp |
string | ISO 8601 timestamp |
message |
string | Human-readable message |
version_id |
string | Version identifier (timestamp or git commit) |
diff |
string | Unified diff of changes (truncated to 50 lines) |
Webhook Service Examples
Discord Webhook
[global]
NOTIFICATION_WEBHOOK_URL = "https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_TOKEN"
Discord will display the notification with:
- Stack name as title
- Message as content
- Diff in a code block
- Timestamp
Slack Webhook
[global]
NOTIFICATION_WEBHOOK_URL = "https://hooks.slack.com/services/YOUR_WORKSPACE/YOUR_CHANNEL/YOUR_TOKEN"
Slack will display:
- Rich message with stack information
- Diff in a collapsible section
- Color coding for success/failure
Microsoft Teams Webhook
[global]
NOTIFICATION_WEBHOOK_URL = "https://your-org.webhook.office.com/webhookb2/YOUR_WEBHOOK_ID/IncomingWebhook/YOUR_TOKEN/YOUR_CHANNEL"
Teams will show:
- Adaptive card with stack details
- Diff in a code block
- Action buttons for quick access
Custom Webhook Service
[global]
NOTIFICATION_WEBHOOK_URL = "https://your-service.com/webhook"
Your service can parse the JSON payload to:
- Store update history
- Trigger automated responses
- Send email notifications
- Update monitoring dashboards
Dry-Run Mode Notifications
When dry-run mode is enabled, webhooks are still sent with a [DRY-RUN] prefix:
{
"event": "update_success",
"stack_name": "immich",
"timestamp": "2024-01-15T10:30:02Z",
"message": "[DRY-RUN] Would apply changes to immich",
"version_id": "20240115103002",
"diff": "--- a/docker-compose.yml\n+++ b/docker-compose.yml\n@@ -15,7 +15,7 @@ services:\n immich-server:\n- image: ghcr.io/immich-app/immich-server:release\n+ image: ghcr.io/immich-app/immich-server:v1.75.0\n"
}
This is useful for:
- Testing webhook configurations
- Previewing changes before applying
- Validating webhook integrations
Error Notifications
When updates fail, ComposeSync sends error notifications:
{
"event": "update_failure",
"stack_name": "immich",
"timestamp": "2024-01-15T10:30:02Z",
"message": "Failed to update stack immich, rolled back to previous version",
"version_id": "20240115103002",
"diff": "--- a/docker-compose.yml\n+++ b/docker-compose.yml\n@@ -15,7 +15,7 @@ services:\n immich-server:\n- image: ghcr.io/immich-app/immich-server:release\n+ image: ghcr.io/immich-app/immich-server:v1.75.0\n"
}
Testing Webhooks
Manual Testing
Test your webhook endpoint manually:
# Test basic webhook
curl -X POST -H "Content-Type: application/json" \
-d '{"event": "test", "message": "Test notification"}' \
https://your-webhook-url.com/endpoint
# Test with full payload
curl -X POST -H "Content-Type: application/json" \
-d '{
"event": "update_success",
"stack_name": "test-stack",
"timestamp": "2024-01-15T10:30:02Z",
"message": "Test update notification",
"version_id": "test-123",
"diff": "--- a/test.yml\n+++ b/test.yml\n@@ -1,1 +1,1 @@\n- old\n+ new\n"
}' \
https://your-webhook-url.com/endpoint
Enable Dry-Run Mode
Test webhooks safely with dry-run mode:
[global]
DRY_RUN = true
NOTIFICATION_WEBHOOK_URL = "https://your-webhook-url.com/endpoint"
[test-stack]
URL = "https://github.com/user/test-app.git"
PATH = "/opt/composesync/stacks/test"
TOOL = "git"
GIT_SUBPATH = "docker/docker-compose.yml"
GIT_REF = "main"
Best Practices
1. Use Different Webhooks for Different Environments
# Production webhook
[global]
NOTIFICATION_WEBHOOK_URL = "https://prod-webhook.com/endpoint"
# Development webhook
[dev-app]
URL = "https://github.com/user/dev-app.git"
PATH = "/opt/composesync/stacks/dev-app"
TOOL = "git"
NOTIFICATION_WEBHOOK_URL = "https://dev-webhook.com/endpoint"
2. Handle Webhook Failures Gracefully
ComposeSync continues to work even if webhook notifications fail:
- Webhook failures don't affect stack updates
- Failed webhooks are logged but don't stop the process
- You can monitor webhook delivery in the logs
3. Secure Your Webhooks
- Use HTTPS endpoints only
- Consider webhook authentication if supported
- Rotate webhook tokens regularly
- Monitor webhook access logs
4. Monitor Webhook Delivery
# Check webhook delivery in logs
sudo journalctl -u composesync | grep "webhook"
# Filter for webhook errors
sudo journalctl -u composesync | grep "ERROR.*webhook"
Troubleshooting
Webhook Not Being Sent
# Check if webhook URL is configured
grep "NOTIFICATION_WEBHOOK_URL" /opt/composesync/config.toml
# Check service logs for webhook errors
sudo journalctl -u composesync | grep "webhook"
Webhook Delivery Failures
# Test webhook endpoint manually
curl -X POST -H "Content-Type: application/json" \
-d '{"test": "message"}' \
https://your-webhook-url.com/endpoint
# Check network connectivity
wget -q --spider https://your-webhook-url.com/endpoint
echo $?
Webhook Payload Issues
# Check webhook payload format
sudo journalctl -u composesync | grep "payload"
# Verify JSON syntax
echo '{"test": "payload"}' | jq .
Rate Limiting
If your webhook service has rate limits:
- Consider batching notifications
- Implement retry logic in your webhook service
- Use different webhooks for different stacks