Skip to content

Repository files navigation

Prokestro

Self-hosted deployment platform. Link a GitHub repo, push code, get a live URL. Postgres, Redis, and MongoDB available as on-demand managed services. Everything runs as Docker containers on a single machine you control.

How it works

GitHub push → webhook → build (Dockerfile or Nixpacks) → rolling deploy → Traefik URL

Six Go microservices, each with its own SQLite database:

Service Port Role
gateway 8080 Public REST + SSE API. Bearer-token auth.
control-plane 50051 Projects, services, sealed env vars, orchestration.
github 50052 / 8088 GitHub App tokens, push webhook receiver.
builder 50053 Clone → Dockerfile/Nixpacks detection → docker build → stream logs.
deployer 50054 Rolling container deploys, Traefik label routing, deploy history.
provisioner 50055 Managed Postgres/Redis/Mongo containers on project networks.

Traefik provides automatic TLS (Let's Encrypt) and routes <service>.<project>.<BASE_DOMAIN> to each deployed container.


Prerequisites

  • Docker Engine 24+ with Compose V2 (docker compose)
  • A public domain with DNS pointed at your server (for TLS + webhooks)
  • A GitHub App — optional, only needed for private repos

Quick start

1. Clone and configure

git clone https://github.com/LevantateLabs/Prokestro
cd Prokestro
cp .env.example .env

Edit .env:

BASE_DOMAIN=example.com           # services route as <svc>.<proj>.example.com
ACME_EMAIL=you@example.com        # Let's Encrypt registration email
MASTER_KEY=                       # run `make secret` and paste the output here
PROKESTRO_AUTH_TOKEN=changeme     # bearer token for the API; empty = no auth
LOG_LEVEL=info

Generate a master key:

make secret   # prints a fresh 64-char hex key; paste into MASTER_KEY=

2. GitHub App (optional — skip for public repos)

  1. GitHub → Settings → Developer settings → GitHub Apps → New GitHub App
  2. Set:
    • Webhook URL: https://github.<BASE_DOMAIN>/webhooks/github
    • Permissions: Contents → Read-only
    • Subscribe to events: Push
  3. Generate and download a private key.
  4. Install the App on your repo.
  5. Add to .env:
GITHUB_APP_ID=123456
GITHUB_APP_PRIVATE_KEY="$(cat your-app.2024-01-01.private-key.pem)"
GITHUB_WEBHOOK_SECRET=your-webhook-secret

For public repos leave those three vars empty. Prokestro will clone without a token.

3. Start

make up      # docker compose up --build -d
make logs    # tail all service logs

Verify:

docker compose ps     # 7 containers, all "Up"
curl http://localhost:8080/healthz
# {"status":"ok"}

The gateway is also routed through Traefik at https://api.<BASE_DOMAIN> once DNS resolves.


First deploy

Create a project

TOKEN=changeme
API=http://localhost:8080

curl -X POST $API/v1/projects \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "myapp"}'
{"id":"proj_a1b2c3d4e5f6","name":"myapp","network":"prokestro_proj_a1b2c3d4e5f6",...}

Add a service (git-backed)

curl -X POST $API/v1/projects/<project_id>/services \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "web",
    "repo_full_name": "yourorg/yourrepo",
    "branch": "main",
    "container_port": 3000,
    "github_installation_id": 12345678
  }'

github_installation_id is in the GitHub App installation URL (/settings/installations/<id>). Use 0 for public repos.

Set environment variables

curl -X POST $API/v1/services/<service_id>/env \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"key": "NODE_ENV", "value": "production"}'

Deploy

Automatic: push to the configured branch — the webhook fires and triggers a build.

Manual:

curl -X POST $API/v1/services/<service_id>/build \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
# {"build_id":"bld_...","url":"https://web.myapp.example.com"}

Watch live logs (Server-Sent Events)

curl -N "$API/v1/services/<service_id>/logs" \
  -H "Authorization: Bearer $TOKEN"

Events emitted: log (one build/deploy line), status (PENDING → RUNNING → SUCCEEDED/FAILED), url (final Traefik URL).


Managed services

Add a Postgres database to a project:

curl -X POST $API/v1/projects/<project_id>/managed-services \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "db", "kind": "postgres"}'

Supported kinds: postgres, redis, mongo.

Prokestro automatically injects the connection env vars (DATABASE_URL, POSTGRES_HOST, REDIS_URL, etc.) into every git-backed service in the project. The next deploy picks them up with no manual configuration.

The managed container is only reachable inside the project's private network via its alias (e.g. postgres:5432). It is never published to the host.


API reference

Method Path Description
GET /healthz Health check (no auth)
POST /v1/projects Create project
GET /v1/projects List projects
GET /v1/projects/{id} Get project
POST /v1/projects/{id}/services Create git-backed service
GET /v1/projects/{id}/services List services in project
POST /v1/projects/{id}/managed-services Provision managed datastore
GET /v1/services/{id} Get service
GET /v1/services/{id}/env List env var keys (values never returned)
POST /v1/services/{id}/env Set / update an env var
POST /v1/services/{id}/build Trigger build + deploy
POST /v1/services/{id}/rollback Re-deploy the previous succeeded image
GET /v1/services/{id}/builds Build history (newest first)
GET /v1/services/{id}/deployments Deployment history
GET /v1/services/{id}/logs SSE live log stream (triggers build)
GET /v1/builds/{id}/logs Historical build log lines

Resource limits

Pass cpu_shares and memory_mb in CreateService:

{
  "name": "web",
  "repo_full_name": "yourorg/yourrepo",
  "branch": "main",
  "container_port": 3000,
  "cpu_shares": 512,
  "memory_mb": 256
}

cpu_shares is Docker's relative CPU weight (1024 ≈ 1 core). memory_mb is a hard limit enforced at the cgroup layer.


Operations

make up      # build images and start all services
make down    # stop and remove containers
make logs    # tail all service logs
make secret  # generate a fresh MASTER_KEY value
make test    # unit + integration tests
make build   # compile all binaries into ./bin/
make gen     # regenerate Go from proto/ (requires buf)

Local development (no Docker)

Run individual services against local ports:

export MASTER_KEY=$(make -s secret) \
       PROKESTRO_DATA_DIR=./data \
       BASE_DOMAIN=localhost
go run ./cmd/control-plane

Services dial each other using the defaults in internal/platform/config/config.go (CONTROLPLANE_ADDR, BUILDER_ADDR, etc.). Override to taste.


Architecture notes

Single-host, shared daemon. Builder, deployer, and provisioner mount /var/run/docker.sock and run as root. Containers they create are siblings on the host daemon — no image registry is required.

Socket access is root-equivalent on the host. This is the accepted trade-off for single-host self-hosting. Do not expose the Docker socket to untrusted workloads.

Per-project networks. Each project gets a dedicated Docker bridge network (prokestro_proj_<id>). Managed datastores are unreachable from outside the network; app containers connect by DNS alias (e.g. postgres, redis).

Sealed secrets. Env vars are encrypted with AES-256-GCM at rest using MASTER_KEY. Plaintext is held in memory only during TriggerBuild, passed in-process to the deployer, and never logged or persisted as plaintext.

Build detection. The builder looks for a Dockerfile or Dockerfile.* first. If none is found, it falls back to the Nixpacks CLI — the same auto-detection Railway uses for zero-config builds.

Rolling deploys. Deployer starts the new container, polls ContainerInspect until State.Running is true (up to 60s), then removes the old container. If the new container exits immediately, the old container is left running and the deploy is marked failed.

Rollback. POST /v1/services/{id}/rollback queries deploy history, skips the current running version, and re-deploys the previous succeeded image — no clone or rebuild.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages