[{"data":1,"prerenderedAt":474},["ShallowReactive",2],{"navigation_docs":3,"-docs-getting-started-installation":130,"-docs-getting-started-installation-surround":469},[4,25,70,90,115],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting started",false,"\u002Fdocs\u002Fgetting-started","docs\u002F1.getting-started",[10,15,20],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fdocs\u002Fgetting-started\u002Fintroduction","docs\u002F1.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","docs\u002F1.getting-started\u002F2.installation","i-lucide-terminal",{"title":21,"path":22,"stem":23,"icon":24},"Quickstart","\u002Fdocs\u002Fgetting-started\u002Fquickstart","docs\u002F1.getting-started\u002F3.quickstart","i-lucide-rocket",{"title":26,"icon":6,"path":27,"stem":28,"children":29,"page":6},"Deploy","\u002Fdocs\u002Fdeploy","docs\u002F2.deploy",[30,35,40,45,50,55,60,65],{"title":31,"path":32,"stem":33,"icon":34},"Projects and services","\u002Fdocs\u002Fdeploy\u002Fprojects-and-services","docs\u002F2.deploy\u002F1.projects-and-services","i-lucide-folder-kanban",{"title":36,"path":37,"stem":38,"icon":39},"Docker images","\u002Fdocs\u002Fdeploy\u002Fdocker-images","docs\u002F2.deploy\u002F2.docker-images","i-lucide-container",{"title":41,"path":42,"stem":43,"icon":44},"Git repositories","\u002Fdocs\u002Fdeploy\u002Fgit-repositories","docs\u002F2.deploy\u002F3.git-repositories","i-lucide-git-branch",{"title":46,"path":47,"stem":48,"icon":49},"Databases","\u002Fdocs\u002Fdeploy\u002Fdatabases","docs\u002F2.deploy\u002F4.databases","i-lucide-database",{"title":51,"path":52,"stem":53,"icon":54},"Environment variables","\u002Fdocs\u002Fdeploy\u002Fenvironment-variables","docs\u002F2.deploy\u002F5.environment-variables","i-lucide-key-round",{"title":56,"path":57,"stem":58,"icon":59},"Deployments and logs","\u002Fdocs\u002Fdeploy\u002Fdeployments","docs\u002F2.deploy\u002F6.deployments","i-lucide-scroll-text",{"title":61,"path":62,"stem":63,"icon":64},"Deploy hooks","\u002Fdocs\u002Fdeploy\u002Fdeploy-hooks","docs\u002F2.deploy\u002F7.deploy-hooks","i-lucide-webhook",{"title":66,"path":67,"stem":68,"icon":69},"Domains and HTTPS","\u002Fdocs\u002Fdeploy\u002Fdomains","docs\u002F2.deploy\u002F8.domains","i-lucide-lock",{"title":71,"icon":6,"path":72,"stem":73,"children":74,"page":6},"Backups","\u002Fdocs\u002Fbackups","docs\u002F3.backups",[75,80,85],{"title":76,"path":77,"stem":78,"icon":79},"Backup destinations","\u002Fdocs\u002Fbackups\u002Fbackup-destinations","docs\u002F3.backups\u002F1.backup-destinations","i-lucide-hard-drive-upload",{"title":81,"path":82,"stem":83,"icon":84},"Database backups","\u002Fdocs\u002Fbackups\u002Fdatabase-backups","docs\u002F3.backups\u002F2.database-backups","i-lucide-archive-restore",{"title":86,"path":87,"stem":88,"icon":89},"Backing up Harblet","\u002Fdocs\u002Fbackups\u002Fharblet-backups","docs\u002F3.backups\u002F3.harblet-backups","i-lucide-shield-check",{"title":91,"icon":6,"path":92,"stem":93,"children":94,"page":6},"Administration","\u002Fdocs\u002Fadministration","docs\u002F4.administration",[95,100,105,110],{"title":96,"path":97,"stem":98,"icon":99},"Harblet's domain","\u002Fdocs\u002Fadministration\u002Fharblet-domain","docs\u002F4.administration\u002F1.harblet-domain","i-lucide-globe",{"title":101,"path":102,"stem":103,"icon":104},"Servers","\u002Fdocs\u002Fadministration\u002Fservers","docs\u002F4.administration\u002F2.servers","i-lucide-server",{"title":106,"path":107,"stem":108,"icon":109},"Team and account","\u002Fdocs\u002Fadministration\u002Fteam","docs\u002F4.administration\u002F3.team","i-lucide-users",{"title":111,"path":112,"stem":113,"icon":114},"Updates","\u002Fdocs\u002Fadministration\u002Fupdates","docs\u002F4.administration\u002F4.updates","i-lucide-refresh-cw",{"title":116,"icon":6,"path":117,"stem":118,"children":119,"page":6},"Reference","\u002Fdocs\u002Freference","docs\u002F5.reference",[120,125],{"title":121,"path":122,"stem":123,"icon":124},"Troubleshooting","\u002Fdocs\u002Freference\u002Ftroubleshooting","docs\u002F5.reference\u002F1.troubleshooting","i-lucide-life-buoy",{"title":126,"path":127,"stem":128,"icon":129},"License","\u002Fdocs\u002Freference\u002Flicense","docs\u002F5.reference\u002F2.license","i-lucide-scale",{"id":131,"title":16,"body":132,"description":462,"extension":463,"links":464,"meta":465,"navigation":466,"path":17,"seo":467,"stem":18,"__hash__":468},"docs\u002Fdocs\u002F1.getting-started\u002F2.installation.md",{"type":133,"value":134,"toc":451},"minimark",[135,140,172,208,212,216,220,223,260,271,279,283,293,299,303,307,314,336,340,343,377,381,410,413,417,420,426,433,437,447],[136,137,139],"h2",{"id":138},"requirements","Requirements",[141,142,143,156,163,169],"ul",{},[144,145,146,147,151,152,155],"li",{},"A ",[148,149,150],"strong",{},"fresh server"," with ",[148,153,154],{},"Ubuntu 24.04 or 26.04"," and root access. The install script stops if k3s is already installed.",[144,157,158,159,162],{},"At least ",[148,160,161],{},"2 CPUs and 4 GB of memory",".",[144,164,165,168],{},[148,166,167],{},"Internet access"," from the server.",[144,170,171],{},"These ports open in the server's firewall:",[173,174,175,188],"table",{},[176,177,178],"thead",{},[179,180,181,185],"tr",{},[182,183,184],"th",{},"Port",[182,186,187],{},"For",[189,190,191,200],"tbody",{},[179,192,193,197],{},[194,195,196],"td",{},"TCP 80 and 443",[194,198,199],{},"Your services' domains, and Harblet's own domain later",[179,201,202,205],{},[194,203,204],{},"TCP 3000",[194,206,207],{},"Harblet, until it has its own domain",[209,210,211],"p",{},"Harblet runs on x86_64 and arm64 servers.",[213,214,215],"tip",{},"Most cloud providers offer Ubuntu 24.04 images. A small VPS with 2 CPUs and 4 GB is enough to start. Harblet and k3s take part of the memory, the rest is for your services, so pick a larger server if you plan to run many of them.",[136,217,219],{"id":218},"install","Install",[209,221,222],{},"Log in to the server and run:",[224,225,231],"pre",{"className":226,"code":227,"filename":228,"language":229,"meta":230,"style":230},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","curl -fsSL https:\u002F\u002Fraw.githubusercontent.com\u002Fharblet\u002Fharblet\u002Fmain\u002Finstall.sh | sudo sh\n","Server","bash","",[232,233,234],"code",{"__ignoreMap":230},[235,236,239,243,247,250,254,257],"span",{"class":237,"line":238},"line",1,[235,240,242],{"class":241},"sBMFI","curl",[235,244,246],{"class":245},"sfazB"," -fsSL",[235,248,249],{"class":245}," https:\u002F\u002Fraw.githubusercontent.com\u002Fharblet\u002Fharblet\u002Fmain\u002Finstall.sh",[235,251,253],{"class":252},"sMK4o"," |",[235,255,256],{"class":241}," sudo",[235,258,259],{"class":245}," sh\n",[209,261,262,263,270],{},"The script installs ",[264,265,269],"a",{"href":266,"rel":267},"https:\u002F\u002Fk3s.io",[268],"nofollow","k3s"," and Harblet. This takes a few minutes. When Harblet is ready, it prints its address:",[224,272,277],{"className":273,"code":275,"language":276,"meta":230},[274],"language-text","Harblet is ready. Open http:\u002F\u002F203.0.113.10:3000 to create the first account.\n","text",[232,278,275],{"__ignoreMap":230},[136,280,282],{"id":281},"create-the-first-account","Create the first account",[209,284,285,286,289,290,162],{},"Open the address in your browser. Harblet asks you to ",[148,287,288],{},"Set up Harblet",": enter your name, email and a password of at least 8 characters, then click ",[148,291,292],{},"Create account",[209,294,295,296,162],{},"This first account is an admin. Everyone else joins through an ",[264,297,298],{"href":107},"invitation",[300,301,302],"warning",{},"Create the first account right after the install. Until then, anyone who opens the address can create it.",[136,304,306],{"id":305},"servers-behind-nat","Servers behind NAT",[209,308,309,310,313],{},"Harblet accepts logins only at the address the script prints. The script uses the IPv4 address the server reaches the internet with. If your browser reaches the server at another address, for example because the server is behind NAT, pass that address as ",[232,311,312],{},"HARBLET_URL",":",[224,315,317],{"className":226,"code":316,"filename":228,"language":229,"meta":230,"style":230},"curl -fsSL https:\u002F\u002Fraw.githubusercontent.com\u002Fharblet\u002Fharblet\u002Fmain\u002Finstall.sh | sudo HARBLET_URL=http:\u002F\u002F203.0.113.10:3000 sh\n",[232,318,319],{"__ignoreMap":230},[235,320,321,323,325,327,329,331,334],{"class":237,"line":238},[235,322,242],{"class":241},[235,324,246],{"class":245},[235,326,249],{"class":245},[235,328,253],{"class":252},[235,330,256],{"class":241},[235,332,333],{"class":245}," HARBLET_URL=http:\u002F\u002F203.0.113.10:3000",[235,335,259],{"class":245},[136,337,339],{"id":338},"options","Options",[209,341,342],{},"The install script reads these environment variables:",[344,345,346,359,374],"field-group",{},[347,348,350,351,354,355,358],"field",{"name":312,"type":349},"string","The address your browser reaches Harblet at, with ",[232,352,353],{},"http:\u002F\u002F"," and port ",[232,356,357],{},"3000",". Defaults to the server's IPv4 address.",[347,360,362,363,366,367,370,371,162],{"name":361,"type":349},"HARBLET_BACKUP","The path to a backup of Harblet's database to restore, the ",[232,364,365],{},".dump"," file from your backup destination. Needs ",[232,368,369],{},"HARBLET_APP_SECRET",". See ",[264,372,86],{"href":373},"\u002Fdocs\u002Fbackups\u002Fharblet-backups#restore-harblet-onto-a-new-server",[347,375,376],{"name":369,"type":349},"The app secret of the install the backup comes from. Generated when not set.",[136,378,380],{"id":379},"what-the-script-sets-up","What the script sets up",[141,382,383,388,394,400],{},[144,384,385,387],{},[148,386,269],{},", the lightweight Kubernetes distribution, at the version this Harblet release was tested with. Traffic between servers is encrypted with WireGuard, and Kubernetes secrets are encrypted at rest.",[144,389,390,393],{},[148,391,392],{},"Traefik",", which comes with k3s, on ports 80 and 443. It redirects HTTP to HTTPS and routes your domains to your services.",[144,395,396,399],{},[148,397,398],{},"Harblet"," and its own PostgreSQL database.",[144,401,402,405,406,409],{},[148,403,404],{},"A container registry"," inside the cluster for the images Harblet builds, and ",[148,407,408],{},"BuildKit"," to build them without root. Harblet sets both up when it starts.",[209,411,412],{},"Everything after that happens in Harblet's browser interface.",[136,414,416],{"id":415},"if-the-install-fails","If the install fails",[209,418,419],{},"The script stops with a message that says what went wrong. Once k3s is being installed, a failure prints:",[224,421,424],{"className":422,"code":423,"language":276,"meta":230},[274],"Installing Harblet failed. To start over, run \u002Fusr\u002Flocal\u002Fbin\u002Fk3s-uninstall.sh and then this script again.\n",[232,425,423],{"__ignoreMap":230},[209,427,428,429,432],{},"Run ",[232,430,431],{},"sudo \u002Fusr\u002Flocal\u002Fbin\u002Fk3s-uninstall.sh",", fix the cause, and run the install command again.",[136,434,436],{"id":435},"next-steps","Next steps",[438,439,440,444],"card-group",{},[441,442,443],"card",{"icon":24,"title":21,"to":22},"Deploy your first service and put it on your domain.",[441,445,446],{"icon":99,"title":96,"to":97},"Reach Harblet at your own domain over HTTPS.",[448,449,450],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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":230,"searchDepth":452,"depth":452,"links":453},2,[454,455,456,457,458,459,460,461],{"id":138,"depth":452,"text":139},{"id":218,"depth":452,"text":219},{"id":281,"depth":452,"text":282},{"id":305,"depth":452,"text":306},{"id":338,"depth":452,"text":339},{"id":379,"depth":452,"text":380},{"id":415,"depth":452,"text":416},{"id":435,"depth":452,"text":436},"Install Harblet on a fresh Ubuntu server with one command.","md",null,{},{"icon":19},{"title":16,"description":462},"l03C4CjFsU4PXyKpQ3T4qQb1TOGbN-lRdpJNwJbvj64",[470,472],{"title":11,"path":12,"stem":13,"description":471,"icon":14,"children":-1},"Harblet is a deploy platform you host on your own servers, as an alternative to Vercel, Render and Heroku.",{"title":21,"path":22,"stem":23,"description":473,"icon":24,"children":-1},"From a fresh install to a service with a database on your own domain.",1794744116397]