Overview
Deploy the GitHub Webhook Server on Kubernetes with ConfigMaps for configuration, Secrets for sensitive data, and proper health checks.
Deployment Manifest
Here’s the complete Kubernetes deployment from the README:
apiVersion : apps/v1
kind : Deployment
metadata :
name : github-webhook-server
spec :
replicas : 2
selector :
matchLabels :
app : github-webhook-server
template :
metadata :
labels :
app : github-webhook-server
spec :
containers :
- name : webhook-server
image : ghcr.io/myk-org/github-webhook-server:latest
ports :
- containerPort : 5000
env :
- name : WEBHOOK_SERVER_DATA_DIR
value : "/data"
- name : WEBHOOK_SECRET
valueFrom :
secretKeyRef :
name : webhook-secret
key : secret
volumeMounts :
- name : config-volume
mountPath : /data
livenessProbe :
httpGet :
path : /webhook_server/healthcheck
port : 5000
initialDelaySeconds : 30
periodSeconds : 30
readinessProbe :
httpGet :
path : /webhook_server/healthcheck
port : 5000
initialDelaySeconds : 5
periodSeconds : 10
volumes :
- name : config-volume
configMap :
name : webhook-config
Service Configuration
Expose the webhook server with a LoadBalancer service:
apiVersion : v1
kind : Service
metadata :
name : github-webhook-server-service
spec :
selector :
app : github-webhook-server
ports :
- protocol : TCP
port : 80
targetPort : 5000
type : LoadBalancer
For production environments, use an Ingress controller instead of LoadBalancer for better SSL/TLS management.
ConfigMap for config.yaml
Store the webhook server configuration in a ConfigMap:
apiVersion : v1
kind : ConfigMap
metadata :
name : webhook-config
data :
config.yaml : |
# yaml-language-server: $schema=https://raw.githubusercontent.com/myk-org/github-webhook-server/refs/heads/main/webhook_server/config/schema.yaml
log-level: INFO
log-file: webhook-server.log
github-app-id: 123456
webhook-ip: https://your-domain.com/webhook_server
github-tokens:
- ghp_your_github_token
default-status-checks:
- "WIP"
- "can-be-merged"
repositories:
my-repository:
name: my-org/my-repository
protected-branches:
main: []
Do NOT store sensitive tokens in ConfigMaps. Use Secrets instead.
Secrets for Sensitive Data
Create a Secret for the webhook secret and GitHub tokens:
apiVersion : v1
kind : Secret
metadata :
name : webhook-secret
type : Opaque
stringData :
secret : "your-webhook-secret-here"
GitHub Tokens Secret
apiVersion : v1
kind : Secret
metadata :
name : github-tokens
type : Opaque
stringData :
token : "ghp_your_github_token_here"
GitHub App Private Key
For the GitHub App private key:
# Create secret from file
kubectl create secret generic github-app-key \
--from-file=webhook-server.private-key.pem=/path/to/private-key.pem
Mount it in the deployment:
volumeMounts :
- name : github-app-key
mountPath : /data/webhook-server.private-key.pem
subPath : webhook-server.private-key.pem
readOnly : true
volumes :
- name : github-app-key
secret :
secretName : github-app-key
Environment Variables
Configure environment variables in the deployment:
env :
- name : WEBHOOK_SERVER_DATA_DIR
value : "/data"
- name : WEBHOOK_SERVER_PORT
value : "5000"
- name : MAX_WORKERS
value : "20"
- name : WEBHOOK_SECRET
valueFrom :
secretKeyRef :
name : webhook-secret
key : secret
- name : VERIFY_GITHUB_IPS
value : "1"
- name : VERIFY_CLOUDFLARE_IPS
value : "1"
- name : ENABLE_LOG_SERVER
value : "true"
- name : ENABLE_MCP_SERVER
value : "false"
AI Integration (Optional)
For pr-test-oracle integration:
env :
- name : ANTHROPIC_API_KEY
valueFrom :
secretKeyRef :
name : ai-api-keys
key : anthropic
- name : GEMINI_API_KEY
valueFrom :
secretKeyRef :
name : ai-api-keys
key : gemini
- name : CURSOR_API_KEY
valueFrom :
secretKeyRef :
name : ai-api-keys
key : cursor
Health Checks and Probes
Liveness Probe
Ensures the container is restarted if unhealthy:
livenessProbe :
httpGet :
path : /webhook_server/healthcheck
port : 5000
initialDelaySeconds : 30
periodSeconds : 30
timeoutSeconds : 5
failureThreshold : 3
Readiness Probe
Ensures traffic is only sent to ready pods:
readinessProbe :
httpGet :
path : /webhook_server/healthcheck
port : 5000
initialDelaySeconds : 5
periodSeconds : 10
timeoutSeconds : 3
successThreshold : 1
failureThreshold : 3
Startup Probe (Optional)
For slow-starting applications:
startupProbe :
httpGet :
path : /webhook_server/healthcheck
port : 5000
initialDelaySeconds : 0
periodSeconds : 10
timeoutSeconds : 3
failureThreshold : 30
Resource Limits
Set resource requests and limits:
resources :
requests :
memory : "512Mi"
cpu : "500m"
limits :
memory : "2Gi"
cpu : "2000m"
Adjust based on your workload. Monitor actual usage and adjust accordingly.
Horizontal Pod Autoscaler
Automatically scale based on CPU/memory:
apiVersion : autoscaling/v2
kind : HorizontalPodAutoscaler
metadata :
name : github-webhook-server-hpa
spec :
scaleTargetRef :
apiVersion : apps/v1
kind : Deployment
name : github-webhook-server
minReplicas : 2
maxReplicas : 10
metrics :
- type : Resource
resource :
name : cpu
target :
type : Utilization
averageUtilization : 70
- type : Resource
resource :
name : memory
target :
type : Utilization
averageUtilization : 80
Ingress Configuration
For production deployments with SSL/TLS:
apiVersion : networking.k8s.io/v1
kind : Ingress
metadata :
name : github-webhook-server-ingress
annotations :
cert-manager.io/cluster-issuer : "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect : "true"
spec :
ingressClassName : nginx
tls :
- hosts :
- webhook.your-domain.com
secretName : webhook-tls
rules :
- host : webhook.your-domain.com
http :
paths :
- path : /
pathType : Prefix
backend :
service :
name : github-webhook-server-service
port :
number : 80
Persistent Storage (Optional)
For persistent logs and data:
apiVersion : v1
kind : PersistentVolumeClaim
metadata :
name : webhook-server-data
spec :
accessModes :
- ReadWriteOnce
resources :
requests :
storage : 10Gi
---
apiVersion : apps/v1
kind : Deployment
metadata :
name : github-webhook-server
spec :
template :
spec :
containers :
- name : webhook-server
volumeMounts :
- name : data-volume
mountPath : /home/podman/data/logs
volumes :
- name : data-volume
persistentVolumeClaim :
claimName : webhook-server-data
Privileged Mode for Container Building
Container building requires privileged mode. Use with caution in production.
If you need container building features:
securityContext :
privileged : true
For better security, use a dedicated build pod or external build service instead.
Deployment Steps
1. Create Namespace
kubectl create namespace webhook-server
2. Create Secrets
# Webhook secret
kubectl create secret generic webhook-secret \
--from-literal=secret= 'your-webhook-secret' \
-n webhook-server
# GitHub App private key
kubectl create secret generic github-app-key \
--from-file=webhook-server.private-key.pem=/path/to/private-key.pem \
-n webhook-server
# AI API keys (optional)
kubectl create secret generic ai-api-keys \
--from-literal=anthropic= 'sk-ant-xxx' \
--from-literal=gemini= 'xxx' \
--from-literal=cursor= 'xxx' \
-n webhook-server
3. Create ConfigMap
kubectl create configmap webhook-config \
--from-file=config.yaml=/path/to/config.yaml \
-n webhook-server
4. Apply Deployment
kubectl apply -f deployment.yaml -n webhook-server
5. Apply Service
kubectl apply -f service.yaml -n webhook-server
6. Verify Deployment
# Check pods
kubectl get pods -n webhook-server
# Check logs
kubectl logs -f deployment/github-webhook-server -n webhook-server
# Check service
kubectl get svc -n webhook-server
Monitoring
Check Health
# Port-forward to test
kubectl port-forward svc/github-webhook-server-service 5000:80 -n webhook-server
# Test health endpoint
curl http://localhost:5000/webhook_server/healthcheck
View Logs
# All pods
kubectl logs -l app=github-webhook-server -n webhook-server
# Specific pod
kubectl logs github-webhook-server-xxx -n webhook-server
# Follow logs
kubectl logs -f deployment/github-webhook-server -n webhook-server
Troubleshooting
Pod Not Starting
# Describe pod
kubectl describe pod github-webhook-server-xxx -n webhook-server
# Check events
kubectl get events -n webhook-server --sort-by= '.lastTimestamp'
ConfigMap Issues
# View ConfigMap
kubectl get configmap webhook-config -o yaml -n webhook-server
# Update ConfigMap
kubectl create configmap webhook-config \
--from-file=config.yaml=/path/to/config.yaml \
--dry-run=client -o yaml | kubectl apply -f -
# Restart deployment to pick up changes
kubectl rollout restart deployment/github-webhook-server -n webhook-server
Secret Issues
# View secret (base64 encoded)
kubectl get secret webhook-secret -o yaml -n webhook-server
# Decode secret
kubectl get secret webhook-secret -o jsonpath='{.data.secret}' -n webhook-server | base64 -d
Next Steps
Configuration Configure your webhook server
Docker Docker deployment options
Examples View deployment examples
Security Security best practices