Vorker is a simple and powerful self host cloudflare worker alternative which built with cloudflare's workerd.
Fearues and Issues are welcome!
- 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
- 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
- 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
- enjoy your untimate self hosted worker!
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 })
}
}
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);
}
}
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.
- Admin Page
- Worker Editor
- Worker Config
- Agent Status
- Worker Execution