Skip to main content
The GitHub Webhook Server is available as a pre-built container image from GitHub Container Registry.

Pull the Image

# Using Podman (recommended)
podman pull ghcr.io/myk-org/github-webhook-server:latest

# Using Docker
docker pull ghcr.io/myk-org/github-webhook-server:latest

Docker Compose Setup

The recommended way to run the webhook server is using Docker Compose. Here’s the complete configuration from examples/docker-compose.yaml:
services:
  github-webhook-server:
    container_name: github-webhook-server
    image: ghcr.io/myk-org/github-webhook-server:latest
    volumes:
      - "./webhook_server_data_dir:/home/podman/data:Z" # Should include config.yaml and webhook-server.private-key.pem
      # Mount temporary directories to prevent boot ID mismatch issues
      - "/tmp/podman-storage-${USER:-1000}:/tmp/storage-run-1000"
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Jerusalem
      - MAX_WORKERS=50 # Defaults to 10 if not set
      - WEBHOOK_SERVER_IP_BIND=0.0.0.0 # IP to listen
      - WEBHOOK_SERVER_PORT=5000 # Port to listen
      - WEBHOOK_SECRET=<secret> # If set verify hook is a valid hook from Github
      - VERIFY_GITHUB_IPS=1 # Verify hook request is from GitHub IPs
      - VERIFY_CLOUDFLARE_IPS=1 # Verify hook request is from Cloudflare IPs
      - ENABLE_LOG_SERVER=true # Enable log viewer endpoints (default: false)
      - ENABLE_MCP_SERVER=false # Enable MCP server for AI agent integration (default: false)
      # AI CLI API keys for pr-test-oracle integration
      # - ANTHROPIC_API_KEY=sk-ant-xxx       # Claude Code
      # - GEMINI_API_KEY=xxx                  # Gemini CLI
      # - CURSOR_API_KEY=xxx                  # Cursor Agent (API key method)
      # For Cursor interactive login: docker exec -it github-webhook-server agent
    ports:
      - "5000:5000"
    privileged: true
    restart: unless-stopped

Starting the Service

# Start the service
docker-compose up -d

# View logs
docker-compose logs -f

# Stop the service
docker-compose down

Volume Mounts

Required Volume

The data directory must contain:
  • config.yaml - Server configuration (see Configuration)
  • webhook-server.private-key.pem - GitHub App private key
volumes:
  - "./webhook_server_data_dir:/home/podman/data:Z"
The :Z suffix is required for SELinux systems to properly label the volume.

Temporary Storage Volume

Prevents boot ID mismatch issues when running Podman-in-Podman:
volumes:
  - "/tmp/podman-storage-${USER:-1000}:/tmp/storage-run-1000"

Environment Variables

Server Configuration

VariableDescriptionDefaultRequired
WEBHOOK_SERVER_DATA_DIRDirectory containing config.yaml/home/podman/dataYes
WEBHOOK_SERVER_IP_BINDIP address to bind server0.0.0.0No
WEBHOOK_SERVER_PORTPort to bind server5000No
MAX_WORKERSMaximum number of workers10No

Security Settings

VariableDescriptionDefaultRequired
WEBHOOK_SECRETGitHub webhook secret for HMAC verification-Recommended
VERIFY_GITHUB_IPSVerify webhook requests from GitHub IPsfalseNo
VERIFY_CLOUDFLARE_IPSVerify webhook requests from Cloudflare IPsfalseNo

Feature Toggles

VariableDescriptionDefaultRequired
ENABLE_LOG_SERVEREnable log viewer web interfacefalseNo
ENABLE_MCP_SERVEREnable MCP server for AI agentsfalseNo

AI Integration (Optional)

For pr-test-oracle integration:
VariableDescriptionTool
ANTHROPIC_API_KEYAPI key for Claude Code CLIClaude
GEMINI_API_KEYAPI key for Gemini CLIGemini
CURSOR_API_KEYAPI key for Cursor Agent CLICursor
For Cursor interactive login: docker exec -it github-webhook-server agent

Health Check Configuration

The container includes a built-in health check:
HEALTHCHECK CMD curl --fail http://127.0.0.1:5000/webhook_server/healthcheck || exit 1
For Docker Compose, you can configure advanced health checks:
healthcheck:
  test:
    [
      "CMD",
      "curl",
      "--fail",
      "http://localhost:5000/webhook_server/healthcheck",
    ]
  interval: 30s
  timeout: 10s
  retries: 3
  start_period: 40s

Building from Source

If you need to build a custom image:
# Clone the repository
git clone https://github.com/myakove/github-webhook-server.git
cd github-webhook-server

# Build with Podman
podman build --format docker -t github-webhook-server .

# Or with Docker
docker build -t github-webhook-server .

Dockerfile Overview

The official Dockerfile is based on quay.io/podman/stable:v5 and includes: Base System:
  • Fedora-based Podman stable image
  • Python 3.10, 3.11, 3.12, 3.13
  • Node.js and npm for AI CLI tools
  • Git, GCC, Cargo, and build tools
Python Environment:
  • UV package manager for fast dependency installation
  • Pre-commit, Poetry, Prek, and Tox tools
AI CLI Tools:
  • Claude Code CLI (~/.local/bin)
  • Cursor Agent CLI (~/.local/bin)
  • Gemini CLI (npm global)
Additional Tools:
  • ROSA CLI for OpenShift
  • Regctl for container registry operations
  • Hub for GitHub CLI operations
Application Setup:
EXPOSE 5000

ENV USERNAME="podman"
ENV HOME_DIR="/home/$USERNAME"
ENV DATA_DIR="$HOME_DIR/data"
ENV APP_DIR="$HOME_DIR/github-webhook-server"

WORKDIR $APP_DIR

ENTRYPOINT ["tini", "--", "uv", "run", "entrypoint.py"]

Running with Podman

podman run -d \
  --name github-webhook-server \
  -p 5000:5000 \
  -v ./data:/home/podman/data:Z \
  -e WEBHOOK_SECRET=your-secret \
  -e VERIFY_GITHUB_IPS=1 \
  -e ENABLE_LOG_SERVER=true \
  ghcr.io/myk-org/github-webhook-server:latest

Running with Docker

docker run -d \
  --name github-webhook-server \
  -p 5000:5000 \
  -v ./data:/home/podman/data:Z \
  -e WEBHOOK_SECRET=your-secret \
  -e VERIFY_GITHUB_IPS=1 \
  -e ENABLE_LOG_SERVER=true \
  ghcr.io/myk-org/github-webhook-server:latest

Privileged Mode

The container requires privileged: true for container building features (build-and-push-container).
If you don’t need container building capabilities, you can run without privileged mode:
privileged: false  # Disable if container building is not needed

Container Logs

View container logs:
# Docker Compose
docker-compose logs -f github-webhook-server

# Docker
docker logs -f github-webhook-server

# Podman
podman logs -f github-webhook-server

Troubleshooting

Permission Issues

If you encounter permission issues with volumes:
# Check volume ownership
ls -la ./webhook_server_data_dir

# Fix ownership (1000:1000 is the podman user in the container)
chown -R 1000:1000 ./webhook_server_data_dir

Health Check Failures

If the health check fails:
# Check if the server is running
curl http://localhost:5000/webhook_server/healthcheck

# Check container logs
docker logs github-webhook-server

SELinux Issues

On SELinux-enabled systems, ensure volume labels are correct:
# Add :Z to volume mounts in docker-compose.yaml
volumes:
  - "./webhook_server_data_dir:/home/podman/data:Z"

Next Steps

Configuration

Configure your webhook server

Kubernetes

Deploy to Kubernetes

Examples

View deployment examples

Security

Security best practices

Build docs developers (and LLMs) love