[{"data":1,"prerenderedAt":541},["ShallowReactive",2],{"i-lucide:search":3,"i-lucide:sun":8,"i-lucide:menu":10,"release-en-0.1.0":12,"releases-index-en":93,"i-lucide:link":539},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m21 21l-4.34-4.34\"/>\u003Ccircle cx=\"11\" cy=\"11\" r=\"8\"/>\u003C/g>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"4\"/>\u003Cpath d=\"M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32l1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41\"/>\u003C/g>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":11},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 5h16M4 12h16M4 19h16\"/>",{"doc":13,"isFallback":6},{"id":14,"title":15,"body":16,"channel":81,"date":82,"description":83,"extension":84,"meta":85,"navigation":86,"path":87,"seo":88,"seoTitle":89,"stem":90,"version":91,"__hash__":92},"releasesEn/en/releases/0.1.0.md","Maran 0.1.0 — foundation",{"type":17,"value":18,"toc":75},"minimark",[19,23,28,62,66],[20,21,22],"p",{},"Scaffolding rather than a product you would put in front of hosting customers. It is published as a\nrelease anyway, because everything after it is built on the decisions made here.",[24,25,27],"h2",{"id":26},"what-it-contains","What it contains",[29,30,31,39,45,51,57],"ul",{},[32,33,34,38],"li",{},[35,36,37],"strong",{},"The contract"," between the panel and the root agent — the typed operations the two exchange\nover a unix socket.",[32,40,41,44],{},[35,42,43],{},"The Rust agent skeleton",", including peer credential checks on its socket, so the agent knows\nwhich process is asking before it does anything.",[32,46,47,50],{},[35,48,49],{},"The C# modular monolith"," that became the panel.",[32,52,53,56],{},[35,54,55],{},"The Vue shell"," the interface is built in.",[32,58,59],{},[35,60,61],{},"The development environment and CI.",[24,63,65],{"id":64},"what-it-does-not-contain","What it does not contain",[20,67,68,69,74],{},"Any of the hosting features. Accounts, websites, PHP pools, SSL, databases, file transfer, backups,\nthe firewall and monitoring were all built after this tag and are not part of it. They are on the\nway to the first feature release; see ",[70,71,73],"a",{"href":72},"/releases","releases"," for what is published.",{"title":76,"searchDepth":77,"depth":77,"links":78},"",2,[79,80],{"id":26,"depth":77,"text":27},{"id":64,"depth":77,"text":65},"stable","2026-08-29","The first tagged version — the contract, the Rust agent skeleton, the C# monolith, the Vue shell, and the development environment.","md",{},true,"/en/releases/0.1.0",{"title":15,"description":83},"Maran 0.1.0 — the foundation release","en/releases/0.1.0","0.1.0","K0qrS_RMV3hk8akYIqM0vxrUMoPsTTSnYPEogKZzFeY",[94,135],{"id":14,"title":15,"body":95,"channel":81,"date":82,"description":83,"extension":84,"meta":133,"navigation":86,"path":87,"seo":134,"seoTitle":89,"stem":90,"version":91,"__hash__":92},{"type":17,"value":96,"toc":129},[97,99,101,123,125],[20,98,22],{},[24,100,27],{"id":26},[29,102,103,107,111,115,119],{},[32,104,105,38],{},[35,106,37],{},[32,108,109,44],{},[35,110,43],{},[32,112,113,50],{},[35,114,49],{},[32,116,117,56],{},[35,118,55],{},[32,120,121],{},[35,122,61],{},[24,124,65],{"id":64},[20,126,68,127,74],{},[70,128,73],{"href":72},{"title":76,"searchDepth":77,"depth":77,"links":130},[131,132],{"id":26,"depth":77,"text":27},{"id":64,"depth":77,"text":65},{},{"title":15,"description":83},{"id":136,"title":137,"body":138,"channel":530,"date":531,"description":532,"extension":84,"meta":533,"navigation":86,"path":534,"seo":535,"seoTitle":137,"stem":536,"version":537,"__hash__":538},"releasesEn/en/releases/1.0.0-beta.1.md","Maran 1.0.0-beta.1 — the first installable release",{"type":17,"value":139,"toc":522},[140,146,149,153,189,203,206,210,218,298,325,328,372,384,388,450,454,457,461,464,504,507,511,518],[20,141,142,143],{},"The first release that installs on a server and runs a hosting account end to end. It is published\nas a beta, and the word is meant literally: ",[35,144,145],{},"do not put somebody else's customers on it yet.",[20,147,148],{},"The software installs, runs, and does what its screens say. Three things a paid hosting product has\nto be trusted about have been exercised only in this project's own containers — no certificate has\nbeen issued by a real certificate authority, no disk limit has been enforced by a real filesystem,\nand no restore has been run on real hardware. Those are not known bugs; they are claims nobody has\nyet verified in the place that counts.",[24,150,152],{"id":151},"installing-it","Installing it",[154,155,159],"pre",{"className":156,"code":157,"language":158,"meta":76,"style":76},"language-bash shiki shiki-themes github-light github-dark","curl -sSL https://get.maran.innovayse.com | sudo bash\n","bash",[160,161,162],"code",{"__ignoreMap":76},[163,164,167,171,175,179,183,186],"span",{"class":165,"line":166},"line",1,[163,168,170],{"class":169},"sScJk","curl",[163,172,174],{"class":173},"sj4cs"," -sSL",[163,176,178],{"class":177},"sZZnC"," https://get.maran.innovayse.com",[163,180,182],{"class":181},"szBVR"," |",[163,184,185],{"class":169}," sudo",[163,187,188],{"class":177}," bash\n",[20,190,191,192,195,196,202],{},"The installer downloads the artifacts named in a manifest signed with the project's release key,\nand refuses anything whose signature or checksum does not match. The manifest and the artifacts it\nnames are published at ",[160,193,194],{},"releases.maran.innovayse.com",", and the source at the tag this was built\nfrom is on ",[70,197,201],{"href":198,"rel":199},"https://github.com/innovayse/maran",[200],"nofollow","GitHub",".",[20,204,205],{},"Check what the installer will do before running it as root, the same way you would with any script\nthat takes your server: fetch it, read it, then run it.",[24,207,209],{"id":208},"the-files-and-checking-them-yourself","The files, and checking them yourself",[20,211,212,213,217],{},"Everything the installer downloads is published at\n",[70,214,194],{"href":215,"rel":216},"https://releases.maran.innovayse.com",[200],", listed in a manifest signed\nwith the project's release key.",[219,220,221,237],"table",{},[222,223,224],"thead",{},[225,226,227,231,234],"tr",{},[228,229,230],"th",{},"File",[228,232,233],{},"Size",[228,235,236],{},"SHA-256",[238,239,240,260,279],"tbody",{},[225,241,242,252,255],{},[243,244,245],"td",{},[70,246,249],{"href":247,"rel":248},"https://releases.maran.innovayse.com/beta/agent-x86_64.tar.gz",[200],[160,250,251],{},"agent-x86_64.tar.gz",[243,253,254],{},"2.9 MB",[243,256,257],{},[160,258,259],{},"f9a57621ef349cb1bfc2df5f7f812685fb3a5a690834b18bd1ae8df2493fbadc",[225,261,262,271,274],{},[243,263,264],{},[70,265,268],{"href":266,"rel":267},"https://releases.maran.innovayse.com/beta/api-x86_64.tar.gz",[200],[160,269,270],{},"api-x86_64.tar.gz",[243,272,273],{},"25.4 MB",[243,275,276],{},[160,277,278],{},"6f367807e265d06bee9db37d692d0748c5fb815967965c0e59675a0b8468c799",[225,280,281,290,293],{},[243,282,283],{},[70,284,287],{"href":285,"rel":286},"https://releases.maran.innovayse.com/beta/frontend-x86_64.tar.gz",[200],[160,288,289],{},"frontend-x86_64.tar.gz",[243,291,292],{},"340 KB",[243,294,295],{},[160,296,297],{},"27879087ddb1a0d1e05e92b9b0b4dec6da21a99263388a74e122681ada828009",[20,299,300,301,308,309,316,317,324],{},"The signed list is ",[70,302,305],{"href":303,"rel":304},"https://releases.maran.innovayse.com/beta/manifest.json",[200],[160,306,307],{},"manifest.json"," with\n",[70,310,313],{"href":311,"rel":312},"https://releases.maran.innovayse.com/beta/manifest.json.sig",[200],[160,314,315],{},"manifest.json.sig"," beside it, and\n",[70,318,321],{"href":319,"rel":320},"https://releases.maran.innovayse.com/beta/integrity-manifest.json",[200],[160,322,323],{},"integrity-manifest.json","\nrecords every file inside those archives rather than only the archives.",[20,326,327],{},"If you would rather not pipe anything into a root shell, the same install without the pipe:",[154,329,331],{"className":156,"code":330,"language":158,"meta":76,"style":76},"curl -O https://releases.maran.innovayse.com/installer/maran-installer.tar.gz\ntar -xzf maran-installer.tar.gz\nsudo bash installer/install.sh --channel beta\n",[160,332,333,343,354],{"__ignoreMap":76},[163,334,335,337,340],{"class":165,"line":166},[163,336,170],{"class":169},[163,338,339],{"class":173}," -O",[163,341,342],{"class":177}," https://releases.maran.innovayse.com/installer/maran-installer.tar.gz\n",[163,344,345,348,351],{"class":165,"line":77},[163,346,347],{"class":169},"tar",[163,349,350],{"class":173}," -xzf",[163,352,353],{"class":177}," maran-installer.tar.gz\n",[163,355,357,360,363,366,369],{"class":165,"line":356},3,[163,358,359],{"class":169},"sudo",[163,361,362],{"class":177}," bash",[163,364,365],{"class":177}," installer/install.sh",[163,367,368],{"class":173}," --channel",[163,370,371],{"class":177}," beta\n",[20,373,374,375,378,379,202],{},"The public key the installer verifies against ships inside that package at\n",[160,376,377],{},"installer/keys/release-signing.pub",". Worth saying plainly: a signature checked against a key\ndownloaded from the same host proves only that both came from the same place. To do better,\ncompare that key against\n",[70,380,383],{"href":381,"rel":382},"https://github.com/innovayse/maran/blob/main/installer/keys/release-signing.pub",[200],"the copy in the repository",[24,385,387],{"id":386},"what-a-server-gets","What a server gets",[29,389,390,396,402,408,414,420,426,444],{},[32,391,392,395],{},[35,393,394],{},"Hosting accounts that are real Linux users."," Creating one provisions the system user, the\nhome directory and the plan's disk quota on the host; suspend, reactivate and delete reach the\nhost too. The agent acts first and the database row follows, so the panel never claims an\naccount the server does not have.",[32,397,398,401],{},[35,399,400],{},"Websites"," — static, PHP and reverse-proxy — with domain aliases and a document root inside\nthe account's home. The agent renders the configuration, makes the server's own validator check\nthe result, and rolls it back if the validation or the reload refuses, so a bad render cannot\ntake a server's other sites down.",[32,403,404,407],{},[35,405,406],{},"Several PHP versions side by side",", each account with its own pool per version, running as\nthat account's Linux user. Customers may change a whitelisted subset of settings; anything\noutside the list is refused rather than quietly dropped.",[32,409,410,413],{},[35,411,412],{},"SSL"," over ACME with an HTTP-01 challenge, uploads of your own material, and a renewal pass\nthirty days before expiry. Key material is written to a root-only store outside every account's\nhome, because a site's PHP runs as that customer.",[32,415,416,419],{},[35,417,418],{},"Databases"," with a dedicated user each, per-plan limits and a size reading. The password is\ngenerated, shown once and never stored, so recovery is a reset rather than a retrieval.",[32,421,422,425],{},[35,423,424],{},"File transfer"," — SFTP served by the host's own OpenSSH, each login chrooted into a jail with\nthe account's real home mounted inside it, carrying the account's own uid and no shell. FTPS\nships installed but switched off: nothing listens until an administrator turns it on.",[32,427,428,431,432,435,436,439,440,443],{},[35,429,430],{},"Backups",", an append-only ",[35,433,434],{},"audit journal"," of every sign-in and every mutation, live ",[35,437,438],{},"log\ntailing",", the firewall, monitoring, and the ",[160,441,442],{},"maran"," command-line tool.",[32,445,446,449],{},[35,447,448],{},"Panel sign-in"," with Argon2id, short-lived access tokens, refresh rotation where a reused\ntoken revokes the whole family, TOTP with recovery codes, and sessions you can revoke\nindividually or everywhere at once.",[24,451,453],{"id":452},"what-it-deliberately-does-not-do","What it deliberately does not do",[20,455,456],{},"DNS, mail, and a web database manager. Each is absent by decision rather than unfinished: a\ndatabase manager is planned as a separate deployable with its own address and its own\nauthentication rather than half-built here.",[24,458,460],{"id":459},"before-you-install-it-anywhere-that-matters","Before you install it anywhere that matters",[20,462,463],{},"Three limitations are worth knowing in advance, because an operator would otherwise find them out\nthe hard way.",[29,465,466,480,486],{},[32,467,468,471,472,475,476,479],{},[35,469,470],{},"No certificate has been issued by a real authority."," The whole path does run end to end —\nregistration, order, HTTP-01 challenge served and validated, finalise, download — against\n",[160,473,474],{},"pebble",", Let's Encrypt's own test server, with the issued certificate's serial matching the one\nread back out of the PEM. That exercise found a real defect no test had: the client sent no\n",[160,477,478],{},"User-Agent",", which pebble refuses on every request and Let's Encrypt tolerates. What is still\nowed is the authority itself: not their rate limits, not validation from the public internet, not\ntheir chain. The renewal branch is not exercised at all, because the test forces a fresh\nchallenge every run. HTTP-01 only — no wildcards, which arrive with DNS management.",[32,481,482,485],{},[35,483,484],{},"Dropping a database is final."," There is no snapshot, no recycle bin and no delay, and nothing\nin the drop path consults the backup module. A database is restorable only from a backup that\nalready existed.",[32,487,488,491,492,495,496,499,500,503],{},[35,489,490],{},"The SSH daemon's jail configuration is watched, and the watch has a stated edge."," The\ninstaller writes the block that makes a file transfer login a jailed one, and monitoring now\nreads that block back and raises an alert when it drifts — all four directives individually, so\na block whose header survived and whose body was emptied is caught too. It reads the\nconfiguration file rather than asking the daemon, because ",[160,493,494],{},"sshd -T"," never prints the contents of\na ",[160,497,498],{},"Match"," block at all. What it does not do: follow ",[160,501,502],{},"Include"," directives, or prove that a drifted\nhost really grants a shell. It reports that the configuration no longer says what was written.",[20,505,506],{},"The threat notes covering the privileged parts were reviewed and accepted on the release date. That\nsatisfies the project's own second-reviewer rule. It is not an external audit, and this page does\nnot claim one.",[24,508,510],{"id":509},"upgrading-from-010","Upgrading from 0.1.0",[20,512,513,514,517],{},"There is no upgrade path, and none is needed: ",[70,515,91],{"href":516},"/releases/0.1.0"," was scaffolding with no\nhosting features and nothing running on it to preserve.",[519,520,521],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":76,"searchDepth":77,"depth":77,"links":523},[524,525,526,527,528,529],{"id":151,"depth":77,"text":152},{"id":208,"depth":77,"text":209},{"id":386,"depth":77,"text":387},{"id":452,"depth":77,"text":453},{"id":459,"depth":77,"text":460},{"id":509,"depth":77,"text":510},"beta","2026-09-23","The first release you can install on a server: accounts as real Linux users, websites, PHP versions, SSL, databases, file transfer and backups — published as a beta, with the boundary stated.",{},"/en/releases/0.0-beta.1",{"title":137,"description":532},"en/releases/1.0.0-beta.1","1.0.0-beta.1","ew3oTnwiVfC6YTYkcesfkXnoM6P8kvnD11tcUQ3_Jl8",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":540},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/>\u003Cpath d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/>\u003C/g>",1790166380288]