Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

12 Commits

Repository files navigation

Deployer

A lightweight, high-performance CI/CD webhook server written in Racket. Designed as a self-hosted alternative for Obsidian Digital Garden users who want to move off Vercel and deploy on their own VPS.

RacketLicense

English · 中文

Features

  • Self-hosted — full control over your deployment pipeline, no vendor lock-in
  • Built for Obsidian Digital Garden — optimized for the plugin's publish workflow
  • Asynchronous builds — responds to GitHub immediately while processing builds in the background
  • Concurrency safety — semaphore-based locking prevents simultaneous builds; rebuilds are queued if a new push arrives mid-build
  • HMAC-SHA256 verification — validates GitHub webhook signatures
  • Flexible deployment — serve directly over HTTP, or place behind an Nginx reverse proxy for HTTPS
  • Remote deploy via rsync — optionally sync build output to a separate web server
  • Health endpoint/health returns current build status and time since last build
  • Retry logic — automatic git pull retry with configurable attempts

Requirements

ToolPurpose
Racket 8.0+Runtime
Node.js & npmBuilding the site
GitSource control
OpenSSLSignature verification
rsyncRemote deploy (optional)
NginxHTTPS reverse proxy (optional)

Quick Start

1. Clone

git clone https://github.com/turinglambdaai/deployer.git
cd deployer

2. Configure

cp config.example.json config.json

Minimal configuration (direct HTTP):

{
"github-secret": "your-webhook-secret",
"port": 8080,
"listen-ip": "0.0.0.0",
"repo-path": "/var/www/blog",
"repo-url": "https://github.com/username/repo.git",
"build-output": "/var/www/blog/dist"
}

Production configuration (Nginx + remote deploy):

{
"github-secret": "your-webhook-secret",
"port": 8080,
"listen-ip": "127.0.0.1",
"repo-path": "/var/www/blog",
"repo-url": "https://github.com/username/repo.git",
"build-output": "/var/www/blog/dist",
"deploy": {
"enabled": true,
"remote-host": "user@web-server-ip",
"remote-path": "/var/www/blog/dist",
"ssh-key": "/home/user/.ssh/id_rsa",
"rsync-options": "-avz --delete"
}
}

3. Prepare the Blog Repository

sudo mkdir -p /var/www/blog
sudo chown -R $USER:$USER /var/www/blog
git clone https://github.com/username/your-blog.git /var/www/blog
cd /var/www/blog && npm install && npm run build

4. Run

cd deployer
racket main.rkt

5. Configure the GitHub Webhook

In your repository settings, add a webhook:

FieldDirect HTTPNginx HTTPS
Payload URLhttp://your-server:8080/https://webhook.example.com:8443/
Content typeapplication/jsonapplication/json
Secretyour github-secretyour github-secret
SSL verificationDisabledEnabled

Project Structure

deployer/
├── main.rkt Entry point, starts the HTTP server
├── config.example.json Sample configuration
└── src/
├── config.rkt JSON config loader and accessors
├── webhook.rkt Webhook handler, signature verification, async build
├── build.rkt npm install and build orchestration
├── deploy.rkt rsync-based remote deployment
└── git.rkt Git clone and pull with retry

Configuration Reference

OptionDescriptionDefaultRequired
github-secretGitHub webhook secret--Yes
portHTTP server port8080Yes
listen-ip0.0.0.0 (all interfaces) or 127.0.0.1 (localhost)127.0.0.1Yes
repo-pathLocal repository path--Yes
repo-urlGitHub repository URL--Yes
build-outputBuild output directory--Yes
deploy.enabledEnable remote deploymentfalseNo
deploy.remote-hostRemote server (user@host)--If deploy enabled
deploy.remote-pathRemote directory--If deploy enabled
deploy.ssh-keySSH private key path--If deploy enabled
deploy.rsync-optionsrsync flags-avz --deleteNo

API Endpoints

EndpointMethodDescription
/GETService status
/healthGETBuild status and seconds since last build
/POSTGitHub webhook receiver
# Status check
curl http://localhost:8080
# Health check
curl http://localhost:8080/health

Running as a systemd Service

[Unit]Description=Deployer Webhook Server
After=network.target
[Service]Type=simple
User=youruser
WorkingDirectory=/home/youruser/deployer
ExecStart=/usr/bin/racket /home/youruser/deployer/main.rkt
Restart=always
RestartSec=10
[Install]WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable deployer
sudo systemctl start deployer

License

Licensed under the Apache License 2.0.

About

A lightweight, high-performance CI/CD webhook server in Racket, built for Obsidian Digital Garden deployments.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages