J—P

Currently accepting new projects and available for hire.

PHP Git Deploy

I’ve open‑sourced a tiny deployment system built in PHP that brings GitHub webhook deployments to even the most constrained shared hosting environments — no daemons, no long‑running services, and no vendor lock‑in.

Meet PHP Git Deploy: a single _deploy/ folder you drop into your site that securely pulls your GitHub repo on each push and can run post‑deploy tasks like Composer. It’s designed to be simple, auditable, and production‑ready for small sites and personal projects.

Why

Most deployment tools assume you control the server, can install services, or have SSH access with a writable ~/.ssh. Many shared hosts don’t. I wanted something that:

  • Works anywhere PHP runs (even restricted hosting)
  • Uses GitHub webhooks securely (HMAC SHA‑256 verification)
  • Supports private repos over SSH with keys stored inside the project
  • Stays minimal: just PHP files, no frameworks, no databases

Highlights

  • Secure GitHub webhooks: Validates X-Hub-Signature-256 and handles push/ping cleanly
  • Private repo support: SSH key from _deploy/keys/ with correct permissions
  • Smart Git operations:
    • Empty target dir → git clone
    • Non‑empty target dir → git initgit remote add origingit pull
  • Post‑deploy commands: Run Composer or any shell commands you need
  • Clear logs: Plain, timestamped logging; optional file logging
  • Safe by default: No manual URL triggers; only signed GitHub webhooks

How it works

The webhook endpoint lives at _deploy/webhook.php. On a GitHub push event:

  1. Validates the request HMAC with your shared secret
  2. Resolves paths safely (absolute paths for SSH keys and target dir)
  3. Performs the correct Git action based on the target directory state
  4. Runs any configured post‑deploy commands (e.g., Composer)
  5. Logs what happened and returns appropriate HTTP status codes

ping events receive a friendly 200 response; unsupported events are acknowledged and skipped.

Security first

  • HMAC‑SHA256 signature validation with X-Hub-Signature-256
  • Early exits with proper HTTP error codes on any auth/config failures
  • SSH keys stored in _deploy/keys/ with strict permissions
  • No query‑param tokens or manual triggers

Quick start

  1. Copy the _deploy/ folder into your web root (or a subdirectory next to it)
  2. Duplicate _deploy/config.example.php to _deploy/config.php and edit:
    • repository.url (SSH URL, e.g., git@github.com:username/your-website.git)
    • repository.branch (e.g., main)
    • deployment.target_directory (usually the parent dir of _deploy)
    • ssh.key_path (path to your private key inside _deploy/keys/)
    • security.deploy_token (your GitHub webhook secret)
  3. In GitHub, add a webhook:
    • URL: https://your-domain.tld/_deploy/webhook.php
    • Content type: application/json (or x-www-form-urlencoded)
    • Secret: the same as deploy_token
    • Events: just push (GitHub will send an initial ping)
  4. Push to your repo — your site updates automatically.

Optional: Add post‑deploy commands in config.php, e.g. run Composer and clear cache:

'post_commands' => [
    __DIR__ . '/composer.phar install --no-dev --optimize-autoloader --no-interaction',
    'find {DIR}/site/cache -mindepth 1 -delete',
],

Compatibility

  • Works with typical shared hosting constraints (limited PATH, no ~/.ssh writes)
  • Handles both application/json and x-www-form-urlencoded webhook payloads
  • Composer is optional; you can run a local composer.phar if needed

Roadmap

  • Optional Git LFS support (where available)
  • Better multi‑repo support per host
  • Optional e‑mail/Slack notifications on deploy

Try it

If you maintain a small site and want reproducible, push‑to‑deploy releases without serverside complexity, give it a spin: lemmon/php-git-deploy.

Tablog Svelte

An open-source demo blog application showcasing the Tablo theme built with SvelteKit. Features Markdown processing with mdsvex, Tailwind CSS styling, and modern web development best practices for creating fast, beautiful blogs.

Svelte 47 3

clsx

A tiny PHP library inspired by the popular JavaScript clsx, making it easy to build clean, dynamic class attributes for your HTML. Write neater templates and keep your code readable, no matter how complex your CSS logic gets.

PHP