Skip to content

VaalaCat/vorker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vorker

Vorker is a simple and powerful self host cloudflare worker alternative which built with cloudflare's workerd.

Fearues and Issues are welcome!

Features

  • User authentication
  • API control
  • Multi worker routing
  • Woker CRUD Management
  • Web UI & Online Editor
  • Multi Node
  • HA support
  • Cloudflare Durable Objects (experimental)
  • Log
  • Metrics
  • Worker version control
  • Worker Debugging
  • Support KV storage

Usage

Docker

  1. Run by docker command or download the docker-compose.yml from repo and execute docker-compose up -d.

all envs defined in env.go, you can take a look at it for more details.

docker run -dit --name=vorker \
	-e WORKER_URL_SUFFIX=.example.com \
	-e COOKIE_DOMAIN=example.com \
	-e ENABLE_REGISTER=false \
	-e JWT_SECRET=xxxxxxx \
	-e AGENT_SECRET=xxxxxxx \
	-p 8080:8080 \
	-p 8888:8888 \
	-p 18080:18080 \
	-v /tmp/workerd:/workerd \
	vaalacat/vorker:latest

# this is a example, you can change the env to fit your need
# for this example, you can visit http://localhost:8888/admin to access the web ui
# and the worker URL will be: SCHEME://WORKER_NAME.example.com
  1. test your workerd, if your vorker is running on localhost, you can use curl to test it.

visit http://localhost:8888/admin to control your worker.

curl localhost:8080 -H "Host: workername" # replace workername with your worker name
  1. enjoy your untimate self hosted worker!

Examples

Request Proxy Service

This is an example of request proxy service.

You can use it like this:

curl https://worker.example.com/https://google.com
  • Code
addEventListener("fetch", (event) => {
	event.respondWith(handler(event));
});

async function handler(event) {
	try {
		const url = new URL((event.request.url).replace('http','https'));
		const param = url.pathname.substring(1)
		if (param.length==0) {
			return new Response("{\"error\": \"proxy addr nil\"}")
		}
		const newHost = new URL(param);
		
		url.host = newHost.hostname;
		return fetch(new Request(newHost, event.request))
	} catch(e) {
		return new Response(e.stack, { status: 500 })
	}
}

Cloudflare Durable Objects

Note: Currently, vorker can use workerd durable objects config, but worked is not ready yet for on disk object, so this is not really durable, when a worker is restarted or migrated, the durable objects will be lost.

  • Template
using Workerd = import "/workerd/workerd.capnp";

const config :Workerd.Config = (
  services = [
    (name = "{{.UID}}", worker = .v{{.UID}}Worker),
  ],

  sockets = [
    (
      name = "{{.UID}}",
      address = "{{.HostName}}:{{.Port}}",
      http=(),
      service="{{.UID}}"
    ),
  ]
);

const v{{.UID}}Worker :Workerd.Worker = (
  modules = [
    (name = "{{.Entry}}", esModule = embed "src/{{.Entry}}"),
  ],
  compatibilityDate = "2023-04-03",
  durableObjectNamespaces = [
    (className = "counter", uniqueKey = "xxxxxxx", preventEviction = true),
  ],
  durableObjectStorage = (inMemory = void),
  bindings = [
    (name = "tests", durableObjectNamespace = "counter"),
  ],
);
  • Code
export default {
  async fetch(request, env) {
    let ip = request.headers.get("x-forwarded-for") || request.headers.get("x-real-ip") || request.ip
    let id = env.tests.idFromName(ip);

    let test = env.tests.get(id);
    return test.fetch(request)
  }
}

export class counter {
  constructor(controller, env) {
    this.cnt = 0;
  }

  async fetch(request) {
    this.cnt = this.cnt + 1
    return new Response(this.cnt);
  }
}

Use Cloudflare wrangler to build

Run those command in your wrangler project:

wrangler deploy --dry-run --outdir dist

and copy the dist/index.js file content to vorker's editor

modify the template to:

using Workerd = import "/workerd/workerd.capnp";

const config :Workerd.Config = (
  services = [
    (name = "{{.UID}}", worker = .v{{.UID}}Worker),
  ],

  sockets = [
    (
      name = "{{.UID}}",
      address = "{{.HostName}}:{{.Port}}",
      http=(),
      service="{{.UID}}"
    ),
  ]
);

const v{{.UID}}Worker :Workerd.Worker = (
  modules = [
    (name = "{{.Entry}}", esModule = embed "src/{{.Entry}}"),
  ],
  compatibilityDate = "2023-04-03",
);

and click Save, all is done.

Screenshots

  • Admin Page

  • Worker Editor

  • Worker Config

  • Agent Status

  • Worker Execution