Cloudron makes it easy to run web apps like WordPress, Nextcloud, GitLab on your server. Find out more or install now.


Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Bookmarks
  • Search
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo

Cloudron Forum

Offical apps | Community apps | Demo | Docs | Install
  1. Cloudron Forum
  2. Community Packages
  3. πŸš€ Unseen Servant: Server for Gopher, Gemini, Spartan, Nex, Finger and HTML - Community package now available

πŸš€ Unseen Servant: Server for Gopher, Gemini, Spartan, Nex, Finger and HTML - Community package now available

Scheduled Pinned Locked Moved Community Packages
unseenservantgophergeminispartannex
1 Posts 1 Posters 61 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L
    L
    LoudLemur
    wrote last edited by LoudLemur
    #1

    TL;DR: Unseen Servant publishes one folder of plain text to Gemini, Gopher, Spartan, Nex and Finger at once, and mirrors the same pages to the web. No build step, and nothing executed, ever. Human architected, AI coded. Packaged for Cloudron; unofficial and community-maintained; built and tested on Cloudron 9.x.

    logo-512.png

    ✨ What it does

    • Six surfaces, one content tree: Gemini on 1965 with Titan uploads on the same listener, the web mirror, and, each off until you switch it on, Gopher, Spartan, Nex and Finger.
    • Rendering happens when a file changes, not per request. Save a page and it is live everywhere a couple of seconds later, with no second copy to keep in step. The rendered HTML tree is a self-contained static site you can copy anywhere.
    • The cleartext protocols cannot leak gated content: anything behind a certificate zone is excluded from the Gopher, Spartan, Nex and Finger trees when they are built, because those protocols cannot authenticate a reader at all.
    • Identity that survives the platform: the certificate is minted once per hostname and never silently replaced, through updates, backups, restores and domain moves, so readers who pinned it stay undisturbed.
    • Agents are first class: an automated publisher presents a client certificate rather than a password or API key, every read-only command emits JSON, and /llms.txt with Markdown siblings serves machine readers.
    • What it refuses, permanently: CGI, scripting, proxying, plugin APIs, an admin panel, and visitor address logging by default. Content is data, never code.
    • The design started by reading the field: Agate's certificate lifecycle, Molly Brown's certificate zones, GmCapsule's Titan handling, gmid's testing discipline and the gopher servers' menu conventions, each credited in the repository with what was declined and why.

    Links

    • 🏠 Project site: https://unseenservant.dev/
    • πŸ“¦ Source and issues: https://forgejo.unseenservant.dev/unseen-servant/unseen-servant
    • πŸͺž GitHub mirror: https://github.com/OrcVole/unseen-servant

    The site is the demonstration: the page you land on is served by the software, from one folder, on every protocol it supports, and its front page opens with the facts (version, licence, packages, networks, lineage) before it asks you to read a word of prose. Swap https:// for gemini:// on the same address and you are reading the same file.

    πŸ“₯ How to install

    Click the Add custom app dropdown (top right in the App Store) and choose Community app, then paste the CloudronVersions.json URL into the box that pops up. Apps installed this way receive automatic updates.

    community-package.jpeg

    cloudronversions.jpeg

    https://raw.githubusercontent.com/OrcVole/unseen-servant/main/CloudronVersions.json
    

    Or with the CLI:

    cloudron install \
      --versions-url https://raw.githubusercontent.com/OrcVole/unseen-servant/main/CloudronVersions.json \
      --location capsule.example.com
    

    Minimums: 256 MiB RAM, localstorage only. No database, no extra subdomain. Cloudron 9.1 or newer.

    First run: there is no login, which is the point: no admin panel means no credential to leak and no login page to probe. The app writes a starter capsule and serves it immediately; you edit the content folder through the dashboard's File Manager. The Gemini port is fixed at 1965 because every client assumes it; the other four protocols are optional ports in the app's settings, served above 1024 because their canonical ports are privileged.

    πŸ‘€ For users

    The small internet is genuinely nice to write for, and the usual barrier is that publishing there means picking one protocol and one server, then maintaining a second copy for people who only have a browser. Here one folder of plain text is the whole workflow: gemtext in, every surface out, within seconds of saving.

    Good fit if you keep a gemlog, or want one, and would rather not run five daemons. Not a fit if you need a general-purpose web server: this one refuses dynamic anything, permanently and by design, and its own site will tell you which of Agate, gmid, Molly Brown or GmCapsule to run instead.

    Cloudron specifics worth having: backups include the server identity, so a restore brings back the same certificate your readers pinned; all state is one directory under /app/data.

    πŸ€– On authorship

    Human architected, AI coded

    What is offered instead of trust: every design decision recorded in writing before the code, the research published, a wire-level test suite, eight fuzzed parsers, and a conformance run against the live deployment. It is a first release and not independently audited; Agate and gmid have years of production hardening this does not, and the project's own comparison page says so.

    🧰 For packagers: what we learned

    What helped: the app is a single static binary with no database and no supervisor, so the whole package is a Dockerfile, a start.sh and the manifest; localstorage covered every persistence need.

    What was tricky: four real ones. The conventional ports for Gopher, Finger and Spartan (70, 79, 300) are privileged and tcpPorts refuses them, so the package publishes 1024, 7979 and 3300 instead. Port 3000 is also refused as reserved, which is not in the manifest documentation and only surfaces as a 400 at install time. tcpPorts entries marked readOnly cannot be moved, which means two installs of this app cannot coexist on one box, correct here but worth knowing. And the health check has to stay green when an admin disables the Gemini port, or the app hangs in "Starting…" because of a protocol-side setting.

    Still rough: the first install from a versions URL onto a fresh subdomain is the path with the least mileage on it, and confirmations from anyone who tries it are welcome.

    πŸ› οΈ For the Cloudron team

    Maintenance burden: light. The package carries no patches, the binary has no runtime dependencies, and the scope is deliberately fixed: new protocols are a versioned decision, not organic growth.

    Why it suits the App Store: the niche, the package is small: 256 MiB and a few megabytes on disk.

    Friction worth knowing: the community-install validator requires iconUrl, mediaLinks and packagerUrl, none of which are in the manifest's own documented field list, and each is discovered as a separate 400 during install. iconUrl additionally forces minBoxVersion to 9.1.0 or newer, a compatibility floor imposed by a metadata field rather than by anything the app does. A single validation pass listing all missing fields at once would have saved several round trips.

    πŸ”“ Unlocks

    A gemlog on your Cloudron that someone in Lagrange, someone in a gopher client from the nineties, and someone who only clicked a link in an email all read from the same files, with no second server and no publishing step.

    πŸ”— Synergies

    Unseen Servant + Forgejo or Gitea: keep the content in a git repository, pull it into the content folder, and the same tree is a website, a capsule and a gopherhole with no build between them.

    Unseen Servant + Miniflux or FreshRSS: it writes Atom, so your own gemlog is subscribable in the reader you already run.

    Unseen Servant + Surfer: if you already publish static HTML with Surfer, this adds the small-network surfaces from the same source files rather than replacing anything.

    Feedback, bug reports, and "works on our install" confirmations all welcome.

    1 Reply Last reply
    2

    Hello! It looks like you're interested in this conversation, but you don't have an account yet.

    Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

    With your input, this post could be even better πŸ’—

    Register Login
    Reply
    • Reply as topic
    Log in to reply
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes


    • Login

    • Don't have an account? Register

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Bookmarks
    • Search