{"id":50531771,"url":"https://github.com/pixelkarma/rqstdev","last_synced_at":"2026-06-03T14:03:24.402Z","repository":{"id":357706601,"uuid":"1238200815","full_name":"pixelkarma/rqstdev","owner":"pixelkarma","description":"rqstdev is a lightweight single-host VM platform. It lets users create accounts, launch QEMU-based Linux VMs from a CLI, SSH into those VMs, and expose web services on per-VM subdomains and optional published web ports.","archived":false,"fork":false,"pushed_at":"2026-05-13T23:02:37.000Z","size":84,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-14T01:32:02.150Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pixelkarma.png","metadata":{"files":{"readme":"README.MD","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-13T23:00:15.000Z","updated_at":"2026-05-13T23:02:41.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pixelkarma/rqstdev","commit_stats":null,"previous_names":["pixelkarma/rqstdev"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/pixelkarma/rqstdev","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pixelkarma%2Frqstdev","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pixelkarma%2Frqstdev/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pixelkarma%2Frqstdev/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pixelkarma%2Frqstdev/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pixelkarma","download_url":"https://codeload.github.com/pixelkarma/rqstdev/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pixelkarma%2Frqstdev/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33867833,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-03T14:03:23.071Z","updated_at":"2026-06-03T14:03:24.389Z","avatar_url":"https://github.com/pixelkarma.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rqstdev\n\n`rqstdev` is a lightweight single-host VM platform. It lets users create accounts, launch QEMU-based Linux VMs from a CLI, SSH into those VMs, and expose web services on per-VM subdomains and optional published web ports.\n\n`rqstdev` is a two-part system:\n\n- `api`: the single-host Linux server that manages accounts, QEMU VMs, and web routing\n- `cli`: the user-facing CLI for account management, VM management, SSH access, and published web ports\n\nThis README is the operator/developer setup overview for the current implementation.\n\n## Server Requirements Overview\n\nThe current server target is a single Linux host.\n\nRequired software:\n\n- `qemu-system-x86_64`\n- `qemu-img`\n- a front proxy for `80/443`:\n  - `nginx`, or\n  - Caddy\n\nUseful but not strictly required:\n\n- `sqlite3` for inspecting the database manually\n- `curl` for testing the local API and proxy\n\nRuntime assumptions:\n\n- the host can run QEMU guests\n- the host has a base QCOW2 image available for cloning\n- `rqstdev-api` can bind its configured listen address\n- `rqstdev-api` can also bind additional published web ports on the host when users enable them\n\n## Build Commands\n\nWorkspace build:\n\n```sh\ngo build ./...\n```\n\nBuild the API:\n\n```sh\ncd api\ngo build ./cmd/rqstdev-api\n```\n\nBuild the CLI:\n\n```sh\ncd cli\ngo build ./cmd/rqstdev\n```\n\nCross-compile Linux binaries from macOS or another host:\n\n```sh\ncd api\nGOOS=linux GOARCH=amd64 go build -o /tmp/rqstdev-api-linux ./cmd/rqstdev-api\n\ncd ../cli\nGOOS=linux GOARCH=amd64 go build -o /tmp/rqstdev-cli-linux ./cmd/rqstdev\n```\n\n## Server Configuration\n\nThe server binary reads a JSON config file. The current default flag is:\n\n```sh\nrqstdev-api --config /etc/rqstdev/config.json\n```\n\nExample configuration:\n\n```json\n{\n  \"listen_addr\": \"0.0.0.0:18090\",\n  \"base_url\": \"http://api.rqst.dev\",\n  \"base_domain\": \"rqst.dev\",\n  \"db_path\": \"/home/user/rqstdev/data/rqstdev.sqlite\",\n  \"data_dir\": \"/home/user/rqstdev/data\",\n  \"vms_dir\": \"/home/user/rqstdev/vms\",\n  \"qemu_binary_path\": \"/usr/bin/qemu-system-x86_64\",\n  \"template_file\": \"/home/user/rqstdev/assets/default-disk.qcow2\",\n  \"template_cpu\": 1,\n  \"template_memory_mb\": 1024,\n  \"email_script_path\": \"/home/user/rqstdev/send-email-resend.py\"\n}\n```\n\nField notes:\n\n- `listen_addr` is the API bind address, not the public domain\n- `base_url` should be the URL the CLI uses, usually the front-proxy hostname such as `http://api.rqst.dev` or `https://api.rqst.dev`\n- `base_domain` is the VM hostname suffix, for example `rqst.dev`\n- `db_path` is the SQLite database file\n- `data_dir` is the server data root\n- `vms_dir` is where per-VM runtime directories are created\n- `qemu_binary_path` should point at the `qemu-system-x86_64` executable\n- `template_file` should point at the base QCOW2 image used for cloning new VMs\n- `template_cpu` and `template_memory_mb` are optional and define the single VM profile used for new machines\n- `default_web_port` is optional and defaults to `80`\n- `email_script_path` is optional; when set, it enables email-based login challenges and password reset delivery. See [scripts/send-email-resend.py](/Users/admin/Documents/Projects/rqstdev/scripts/send-email-resend.py)\n\n## Proxy Model\n\nThe current proxy model is:\n\n- `80/443` traffic goes through a front proxy to `rqstdev-api`\n- `rqstdev-api` reads the incoming hostname and routes web requests to the correct VM backend\n- additional published web ports are opened directly by `rqstdev-api` on the host\n\nImportant implication:\n\n- the front proxy is only needed for standard web entry on `80/443`\n- published ports like `vm-name.rqst.dev:3456` are handled by `rqstdev-api` binding port `3456` itself\n\nThat means:\n\n- your proxy must preserve the original `Host`\n- your proxy should send `X-Forwarded-Proto`\n- your proxy should send `X-Forwarded-Port`\n\n## Nginx Example\n\nExample `nginx` config for `80`:\n\n```nginx\nserver {\n    listen 80 default_server;\n    listen [::]:80 default_server;\n    server_name _;\n\n    location / {\n        proxy_pass http://127.0.0.1:18090;\n        proxy_set_header Host $http_host;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n        proxy_set_header X-Forwarded-Port $server_port;\n        proxy_set_header X-Real-IP $remote_addr;\n    }\n}\n```\n\nMinimal HTTPS shape with your own certificate paths:\n\n```nginx\nserver {\n    listen 443 ssl http2;\n    listen [::]:443 ssl http2;\n    server_name api.rqst.dev *.rqst.dev;\n\n    ssl_certificate     /path/to/fullchain.pem;\n    ssl_certificate_key /path/to/privkey.pem;\n\n    location / {\n        proxy_pass http://127.0.0.1:18090;\n        proxy_set_header Host $http_host;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n        proxy_set_header X-Forwarded-Port $server_port;\n        proxy_set_header X-Real-IP $remote_addr;\n    }\n}\n```\n\n## Caddy Example\n\nHTTP:\n\n```caddy\n:80 {\n\treverse_proxy 127.0.0.1:18090 {\n\t\theader_up Host {host}\n\t\theader_up X-Forwarded-Proto {scheme}\n\t\theader_up X-Forwarded-Port {server_port}\n\t}\n}\n```\n\nHTTPS with your own site names:\n\n```caddy\napi.rqst.dev, *.rqst.dev {\n\treverse_proxy 127.0.0.1:18090 {\n\t\theader_up Host {host}\n\t\theader_up X-Forwarded-Proto {scheme}\n\t\theader_up X-Forwarded-Port {server_port}\n\t}\n}\n```\n\nIf you want Caddy to manage certificates automatically, use normal Caddy site addresses and DNS that point at the host.\n\n## Additional Published Ports\n\nPublished ports are explicit and web-only in the current implementation.\n\nExample CLI commands:\n\n```sh\nrqstdev port add myvm 3456:3456\nrqstdev port list myvm\nrqstdev port remove myvm 3456\n```\n\nBehavior:\n\n- the mapping is stored in SQLite\n- `rqstdev-api` opens the public port on the host\n- requests to `vm-name.rqst.dev:3456` are routed to guest port `3456`\n\nThe front proxy does not manage these extra published ports.\n\n## Runtime Layout\n\nEach VM gets a runtime directory under `vms_dir`, for example:\n\n```text\n/home/user/rqstdev/vms/\u003cvm-uuid\u003e/\n```\n\nCurrent runtime files include:\n\n- `disk.qcow2`\n- `qemu.pid`\n- `qmp.sock`\n- `serial.log`\n\n## CLI Usage\n\nGlobal option:\n\n- `--account \u003cname|alias|uuid\u003e` overrides the active account for a single command\n\nTop-level commands:\n\n```sh\nrqstdev\nrqstdev help\nrqstdev signup\nrqstdev login\nrqstdev logout\nrqstdev invites\nrqstdev invites accept \u003cinvite-uuid\u003e\nrqstdev invites refuse \u003cinvite-uuid\u003e\nrqstdev list\nrqstdev add [vm-name] [guest-web-port]\nrqstdev delete [vm-name] [--force]\nrqstdev poweron [vm-name]\nrqstdev poweroff [vm-name]\nrqstdev kill [vm-name]\nrqstdev ssh [user@]vm-name\nrqstdev ssh-copy-id [user@]vm-name\nrqstdev port add [vm-name] \u003cpublic-port\u003e:\u003cguest-port\u003e\nrqstdev port remove [vm-name] \u003cpublic-port\u003e\nrqstdev port list [vm-name]\n```\n\nAccount commands:\n\n```sh\nrqstdev account\nrqstdev account create \u003cname\u003e\nrqstdev account add \u003cremote-account\u003e [local-alias]\nrqstdev account remove \u003calias|name|uuid\u003e\nrqstdev account default \u003calias|name|uuid\u003e\nrqstdev account use \u003calias|name|uuid\u003e\nrqstdev account transfer \u003cemail\u003e\nrqstdev account forgot \u003cemail\u003e\nrqstdev account user invite \u003cemail\u003e [user|admin]\nrqstdev account user revoke \u003cemail|user-uuid\u003e\n```\n\nBehavior notes:\n\n- `rqstdev` with no command opens the interactive root flow\n- when a VM name is omitted for VM, SSH, and port commands, the CLI prompts you to select one\n- `rqstdev add` defaults the guest web port to `80`\n- `rqstdev delete` requires typing `DELETE` unless `--force` is provided\n- `rqstdev ssh vm-name` defaults to `root`\n- `rqstdev ssh-copy-id vm-name` defaults to `root` and lets you choose a public key from the default `~/.ssh` directory or enter a custom path\n- `rqstdev invites` with no subcommand opens the interactive invite list\n- `rqstdev account` with no subcommand lists remote accounts\n- `rqstdev account user invite` defaults the invited role to `user`\n\n## Notes\n\n- VM web services are user-managed inside the guest\n- `rqstdev` does not automatically provision a web server inside the VM\n- SSH access is through the CLI path, for example `rqstdev ssh myvm`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpixelkarma%2Frqstdev","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpixelkarma%2Frqstdev","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpixelkarma%2Frqstdev/lists"}