NexCore builds a GitHub-hosted web application inside a local OpenResty container. A single public master receives GitHub webhooks and sends deploy events to every matching local instance over a persistent server-sent events (SSE) connection. Master-connected instances no longer poll GitHub, while legacy polling remains available during migration.
Tracked project files are left untouched by default. NexCore adapts to each framework's normal output paths; legacy preset patching is available only through an explicit opt-in.
GitHub ── signed POST /webhooks/github ──▶ NexCore master
│
authenticated SSE │
┌───────────────────────────┼──────────────────────┐
▼ ▼ ▼
local runner A local runner B local runner C
owner/site@main owner/site@main owner/api@main
The master routes each push by repository.full_name and branch. All connected instances subscribed to the same repository and branch are notified. Event IDs are retained in a bounded in-memory history so a reconnecting runner can receive pushes it missed during a short network interruption.
Generate two independent random secrets:
openssl rand -hex 32
openssl rand -hex 32
Build and start the public master:
docker build --target master -t nexcore-master .
docker run --name nexcore-master \
-p 8080:8080 \
-e MASTER_TOKEN='<runner-connection-secret>' \
-e WEBHOOK_SECRET='<github-webhook-secret>' \
nexcore-master
Expose port 8080 through HTTPS, then create a GitHub repository or organization webhook with:
https://deploy.example.com/webhooks/githubapplication/jsonWEBHOOK_SECRETGET /health returns the master status and current connection count. The webhook is accepted only when its HMAC-SHA256 signature is valid. Duplicate GitHub delivery IDs are ignored.
Build the runner image:
docker build --target runner -t nexcore-runner .
Start one runner per deployment:
docker run --name nexcore-site \
-p 8081:80 \
-e MASTER_URL='https://deploy.example.com' \
-e MASTER_TOKEN='<runner-connection-secret>' \
-e GITHUB_URL='https://github.com/owner/repository.git' \
-e GITHUB_TOKEN='<github-access-token>' \
-e GITHUB_BRANCH='main' \
nexcore-runner
The runner connects to the master before its initial deployment, then stays connected. A disconnected runner retries with exponential backoff up to 30 seconds. Pushes received while a build is already running are coalesced into one follow-up build at the newest revision.
For private networking, MASTER_URL can point directly at the master service (for example http://master:8080); only GitHub's webhook URL must be public.
Existing runner configurations continue to work unchanged. In the default DEPLOY_MODE=auto, a runner uses the master when MASTER_URL is configured and falls back to the original Git polling watcher when it is absent.
Set DEPLOY_MODE=poll to keep a particular runner on polling during migration, even if a master URL is already available. Set DEPLOY_MODE=master when that runner must require the webhook master and should fail fast on missing master configuration.
| Variable | Used by | Default | Purpose |
|---|---|---|---|
MASTER_TOKEN | both | master mode only | Shared bearer token authenticating runner event streams. |
WEBHOOK_SECRET | master | required | Secret configured on the GitHub webhook. |
MASTER_PORT | master | 8080 | HTTP listen port. |
WEBHOOK_MAX_BODY | master | 1048576 | Maximum webhook body size in bytes. |
EVENT_HISTORY_SIZE | master | 1000 | Recent deploy events retained for reconnect replay. |
MASTER_URL | runner | optional | Base URL of the NexCore master. Its presence selects master mode when DEPLOY_MODE=auto. |
GITHUB_URL | runner | required | HTTPS or SSH GitHub clone URL. |
GITHUB_REPOSITORY | runner | derived | Optional explicit owner/repository routing identity. |
GITHUB_TOKEN | runner | required | Token used to clone, pull, and optionally push preset changes. |
GITHUB_BRANCH | runner | main | Branch to deploy and subscribe to. |
DEPLOY_MODE | runner | auto | Select master, legacy poll, or automatic selection based on MASTER_URL. |
WATCH_INTERVAL | runner | 60 | Legacy polling interval in seconds. Ignored in master mode. |
OUTPUT_DIR | runner | /usr/share/nginx/html | Static output and SSR cache root. |
FRAMEWORK_PORT | runner | 3000 | Internal framework server port. |
PUSH_TURBO_CONFIG | runner | false | Opt in to legacy framework-config/turbo patching. Project files are read-only by default. |
COMMIT_TURBO_CHANGES | runner | true | Commit and push preset changes. |
Use different values for MASTER_TOKEN and WEBHOOK_SECRET, store both as deployment secrets, and rotate both if either is disclosed.
nextcli master starts the webhook/event master.nextcli watch performs an initial deploy, then uses master events or legacy polling according to DEPLOY_MODE.nextcli build performs one deploy and exits the watcher path.Run the control-plane tests with npm test from the cli directory.
Content type
Image
Digest
sha256:62b2a1af7…
Size
234.9 MB
Last updated
about 2 months ago
docker pull themodcrafttmc/nexcore