Files
2026-06-25 19:32:06 +02:00

327 lines
23 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en-us" dir="ltr" itemscope itemtype="http://schema.org/Article" data-r-output-format="html">
<head>
<meta charset="utf-8">
<meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0, minimum-scale=1.0">
<meta name="generator" content="Hugo 0.161.1">
<meta name="generator" content="Relearn 8.2.0+220806ce3ced8264fbdd693f77f28216a8a1b6ae">
<meta name="description" content="With gokrazy, you can deploy one or more Go programs as appliances to a Raspberry Pi, Virtual Machine, embedded or normal PC (see supported platforms).
gokrazy uses its own minimal Go userland instead of a traditional Linux distribution base.
This minimalist approach offers several advantages in terms of security, maintainability and reliability:
The surface area for security vulnerabilities is drastically reduced. The root filesystem is entirely read-only (making persistent malware installation hard) and new versions of the system are installed by overwriting the root file system with the new version. No default shell access: There is neither xz nor OpenSSH on a gokrazy system. Interactive access for debugging is possible, but needs to be explicitly started. Backstory For a long time, we were unhappy about having to spend so much time on each of our various Raspberry Pis, taking care of security updates and other general Linux distribution maintenance.">
<meta name="author" content="">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="gokrazy Go appliances :: gokrazy">
<meta name="twitter:description" content="With gokrazy, you can deploy one or more Go programs as appliances to a Raspberry Pi, Virtual Machine, embedded or normal PC (see supported platforms).
gokrazy uses its own minimal Go userland instead of a traditional Linux distribution base.
This minimalist approach offers several advantages in terms of security, maintainability and reliability:
The surface area for security vulnerabilities is drastically reduced. The root filesystem is entirely read-only (making persistent malware installation hard) and new versions of the system are installed by overwriting the root file system with the new version. No default shell access: There is neither xz nor OpenSSH on a gokrazy system. Interactive access for debugging is possible, but needs to be explicitly started. Backstory For a long time, we were unhappy about having to spend so much time on each of our various Raspberry Pis, taking care of security updates and other general Linux distribution maintenance.">
<meta property="og:url" content="https://gokrazy.org/index.html">
<meta property="og:site_name" content="gokrazy">
<meta property="og:title" content="gokrazy Go appliances :: gokrazy">
<meta property="og:description" content="With gokrazy, you can deploy one or more Go programs as appliances to a Raspberry Pi, Virtual Machine, embedded or normal PC (see supported platforms).
gokrazy uses its own minimal Go userland instead of a traditional Linux distribution base.
This minimalist approach offers several advantages in terms of security, maintainability and reliability:
The surface area for security vulnerabilities is drastically reduced. The root filesystem is entirely read-only (making persistent malware installation hard) and new versions of the system are installed by overwriting the root file system with the new version. No default shell access: There is neither xz nor OpenSSH on a gokrazy system. Interactive access for debugging is possible, but needs to be explicitly started. Backstory For a long time, we were unhappy about having to spend so much time on each of our various Raspberry Pis, taking care of security updates and other general Linux distribution maintenance.">
<meta property="og:locale" content="en_us">
<meta property="og:type" content="website">
<meta itemprop="name" content="gokrazy Go appliances :: gokrazy">
<meta itemprop="description" content="With gokrazy, you can deploy one or more Go programs as appliances to a Raspberry Pi, Virtual Machine, embedded or normal PC (see supported platforms).
gokrazy uses its own minimal Go userland instead of a traditional Linux distribution base.
This minimalist approach offers several advantages in terms of security, maintainability and reliability:
The surface area for security vulnerabilities is drastically reduced. The root filesystem is entirely read-only (making persistent malware installation hard) and new versions of the system are installed by overwriting the root file system with the new version. No default shell access: There is neither xz nor OpenSSH on a gokrazy system. Interactive access for debugging is possible, but needs to be explicitly started. Backstory For a long time, we were unhappy about having to spend so much time on each of our various Raspberry Pis, taking care of security updates and other general Linux distribution maintenance.">
<meta itemprop="wordCount" content="526">
<title>gokrazy Go appliances :: gokrazy</title>
<link href="/index.json" rel="alternate" type="application/json" title="gokrazy Go appliances :: gokrazy">
<link href="/images/favicon.png?1782408721" rel="icon" type="image/png">
<link href="/css/auto-complete/auto-complete.min.css?1782408721" rel="stylesheet">
<script src="/js/auto-complete/auto-complete.min.js?1782408721" defer></script>
<script src="/js/search-lunr.min.js?1782408721" defer></script>
<script src="/js/search.min.js?1782408721" defer></script>
<script>
window.relearn = window.relearn || {};
window.relearn.index_js_url="/searchindex.en.js?1782408721";
</script>
<script src="/js/lunr/lunr.min.js?1782408721" defer></script>
<script src="/js/lunr/lunr.stemmer.support.min.js?1782408721" defer></script>
<script src="/js/lunr/lunr.multi.min.js?1782408721" defer></script>
<script src="/js/lunr/lunr.en.min.js?1782408721" defer></script>
<script>
window.relearn = window.relearn || {};
window.relearn.contentLangs=['en'];
</script>
<link href="/fonts/fontawesome/css/fontawesome-all.min.css?1782408721" rel="stylesheet" media="print" onload="this.media='all';this.onload=null;"><noscript><link href="/fonts/fontawesome/css/fontawesome-all.min.css?1782408721" rel="stylesheet"></noscript>
<link href="/css/perfect-scrollbar/perfect-scrollbar.min.css?1782408721" rel="stylesheet">
<link href="/css/theme.min.css?1782408721" rel="stylesheet">
<link href="/css/format-html.min.css?1782408721" rel="stylesheet" id="R-format-style">
<script>
window.relearn = window.relearn || {};
// configuration
window.relearn.min = `.min`;
window.relearn.path='\/index.html';
window.relearn.relBasePath='.';
window.relearn.relBaseUri='.';
window.relearn.absBaseUri='https:\/\/gokrazy.org';
window.relearn.disableInlineCopyToClipboard=true;
window.relearn.enableBlockCodeWrap=true;
// legal
window.relearn.getItem = (s,n) => {return s.getItem(n)};
window.relearn.setItem = (s,n,v) => {return s.setItem(n,v)};
window.relearn.removeItem = (s,n) => {return s.removeItem(n)};
// translations
window.T_Copy_to_clipboard = `Copy text to clipboard`;
window.T_Copied_to_clipboard = `Text copied to clipboard!`;
window.T_Link_copied_to_clipboard = `Link copied to clipboard!`;
window.T_Reset_view = `Reset view`;
window.T_View_reset = `View reset!`;
window.T_No_results_found = `No results found for "{0}"`;
window.T_N_results_found = `{1} results found for "{0}"`;
window.T_Browser_unsupported_feature = `This browser doesn't support this feature`;
// variant stuff
window.relearn.themevariants = [ 'auto' ];
window.relearn.customvariantname = "my-custom-variant";
window.relearn.changeVariant = function(variant) {
var oldVariant = document.documentElement.dataset.rThemeVariant;
window.relearn.setItem(window.localStorage, window.relearn.absBaseUri + "/variant", variant);
document.documentElement.dataset.rThemeVariant = variant;
if (oldVariant != variant) {
document.dispatchEvent( new CustomEvent('themeVariantLoaded', { detail: { variant, oldVariant } }) );
window.relearn.markVariant();
}
}
window.relearn.markVariant = function() {
var variant = window.relearn.getItem(window.localStorage, window.relearn.absBaseUri + "/variant");
document.querySelectorAll(".R-variantswitcher select").forEach((select) => {select.value = variant;});
}
window.relearn.initVariant = function() {
var variant = window.relearn.getItem(window.localStorage, window.relearn.absBaseUri + "/variant") ?? "";
if( variant == window.relearn.customvariantname ){
}else if( !variant || !window.relearn.themevariants.includes(variant) ){
variant = window.relearn.themevariants[0];
window.relearn.setItem(window.localStorage, window.relearn.absBaseUri + "/variant", variant);
}
document.documentElement.dataset.rThemeVariant = variant;
}
window.relearn.initVariant();
window.relearn.markVariant();
</script>
</head>
<body class="mobile-support html" data-url="/index.html">
<div id="R-body" class="default-animation">
<div id="R-body-overlay"></div>
<nav id="R-topbar">
<div class="topbar-wrapper">
<div class="topbar-sidebar-divider"></div>
<div class="topbar-area topbar-area-start" data-area="start">
<div class="topbar-button topbar-button-sidebar" data-content-empty="disable" data-width-s="show" data-width-m="hide" data-width-l="hide">
<span class="btn cstyle button link noborder notitle interactive"><button onclick="toggleNav()" type="button" title="Menu (CTRL&#43;ALT&#43;n)"><i class="fa-fw fas fa-bars"></i></button></span>
</div>
<div class="topbar-button topbar-button-toc" data-content-empty="hide" data-width-s="show" data-width-m="show" data-width-l="show">
<span class="btn cstyle button link noborder notitle interactive"><button onclick="toggleTopbarFlyout(this)" type="button" title="Table of Contents (CTRL&#43;ALT&#43;t)"><i class="fa-fw fas fa-list-alt"></i></button></span>
<div class="topbar-content">
<div class="topbar-content-wrapper">
<nav class="TableOfContents">
<ul>
<li><a href="#backstory">Backstory</a></li>
<li><a href="#your-apps--only-4-moving-parts">Your app(s) + only 4 moving parts</a></li>
<li><a href="#uniformity">Uniformity</a></li>
<li><a href="#web-status-interface">Web status interface</a></li>
<li><a href="#debugging">Debugging</a></li>
<li><a href="#network-updates">Network updates</a></li>
<li><a href="#minimal-state-and-configuration">Minimal state and configuration</a></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<ol class="topbar-breadcrumbs breadcrumbs highlightable" itemscope itemtype="http://schema.org/BreadcrumbList"><li itemscope itemtype="https://schema.org/ListItem" itemprop="itemListElement" class=""><span itemprop="name">gokrazy Go appliances</span><meta itemprop="position" content="1"></li>
</ol>
<div class="topbar-area topbar-area-end" data-area="end">
<div class="topbar-button topbar-button-edit" data-content-empty="disable" data-width-s="area-more" data-width-m="show" data-width-l="show">
<span class="btn cstyle button link noborder notitle interactive"><a href="https://github.com/gokrazy/gokrazy/tree/master/website/content/_index.markdown" rel="external" title="Edit (CTRL+ALT+w)"><i class="fa-fw fas fa-pen"></i></a></span>
</div>
<div class="topbar-button topbar-button-more" data-content-empty="hide" data-width-s="show" data-width-m="show" data-width-l="show">
<span class="btn cstyle button link noborder notitle interactive"><button onclick="toggleTopbarFlyout(this)" type="button" title="More"><i class="fa-fw fas fa-ellipsis-v"></i></button></span>
<div class="topbar-content">
<div class="topbar-content-wrapper">
<div class="topbar-area topbar-area-more" data-area="more">
</div>
</div>
</div>
</div>
</div>
</div>
</nav>
<div id="R-main-overlay"></div>
<main id="R-body-inner" class="highlightable page" tabindex="-1">
<div class="flex-block-wrapper">
<article class="default">
<header class="headline">
</header>
<h1 id="gokrazy-go-appliances">gokrazy Go appliances</h1>
<p>With gokrazy, you can deploy one or more Go programs as
<a href="https://en.wikipedia.org/wiki/Computer_appliance" rel="external">appliances</a> to a Raspberry
Pi, Virtual Machine, embedded or normal PC (see <a href="/platforms/index.html">supported
platforms</a>).</p>
<p>gokrazy uses its own minimal Go userland instead of a traditional Linux
distribution base.</p>
<p>This minimalist approach offers several advantages in terms of security,
maintainability and reliability:</p>
<ul>
<li>The surface area for security vulnerabilities is drastically reduced.</li>
<li>The root filesystem is entirely read-only (making persistent malware
installation hard) and new versions of the system are installed by overwriting
the root file system with the new version.</li>
<li>No default shell access: There is neither xz nor OpenSSH on a gokrazy
system. Interactive access for debugging is possible, but needs to be
explicitly started.</li>
</ul>
<h2 id="backstory">Backstory<span class="btn cstyle anchor copyanchor scrollanchor link noborder notitle interactive"><button type="button" title="Copy link to clipboard"><i class="fa-fw fas fa-link fa-lg"></i></button></span></h2>
<p>For a long time, we were unhappy about having to spend so much time on each of
our various Raspberry Pis, taking care of security updates and other general
Linux distribution maintenance.</p>
<p>Then, we had a crazy idea: what if we massively reduced the overall system
complexity by getting rid of all software we dont strictly need, and instead
built up a minimal system from scratch entirely in Go, a memory safe programming
language?</p>
<p>Turns out this is feasible. gokrazy is the result. See it in action in <a href="https://www.youtube.com/watch?v=6FBGjdT8ZW4&list=PLxMVx8p-A48A6H-EWqzN-HStDH1dOW5PU" rel="external">this
first installation demo
video</a>:</p>
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube-nocookie.com/embed/6FBGjdT8ZW4?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="gokrazy demo: first installation and adding programs"></iframe>
</div>
<!--<img src="logo.svg" width="50" height="50" alt="gokrazy logo" title="gokrazy logo">-->
<h2 id="your-apps--only-4-moving-parts">Your app(s) + only 4 moving parts<span class="btn cstyle anchor copyanchor scrollanchor link noborder notitle interactive"><button type="button" title="Copy link to clipboard"><i class="fa-fw fas fa-link fa-lg"></i></button></span></h2>
<ol>
<li>the <a href="https://github.com/gokrazy/kernel" rel="external">Linux kernel</a>
<ul>
<li>new versions are typically available &lt; 24h after upstream release!</li>
</ul>
</li>
<li>the <a href="https://github.com/gokrazy/firmware" rel="external">Raspberry Pi firmware files</a></li>
<li>the <a href="https://go.dev/" rel="external">Go</a> compiler and standard library</li>
<li>the gokrazy system (minimal init system, updater, DHCP, NTP, …)</li>
</ol>
<h2 id="uniformity">Uniformity<span class="btn cstyle anchor copyanchor scrollanchor link noborder notitle interactive"><button type="button" title="Copy link to clipboard"><i class="fa-fw fas fa-link fa-lg"></i></button></span></h2>
<p>Whats appealing about building an appliance entirely in Go? You get the same
advantages you get when building Go software elsewhere:</p>
<ul>
<li>All components mentioned above (except for the Go compiler) are managed as Go
modules, using the same tooling youre already familiar with.</li>
<li>Go has very quick compilation times; the <code>gok run</code> command allows for a fast
edit-run loop.</li>
<li>Gos
<a href="https://about.sourcegraph.com/blog/go/an-introduction-to-go-tool-trace-rhys-hiltner" rel="external">tracing</a>
and <a href="https://go.dev/blog/pprof" rel="external">profiling</a> support can be used on the entire
system</li>
<li>With Gos <a href="https://go.dev/wiki/Modules#when-should-i-use-the-replace-directive" rel="external">replace
directive</a>,
you can quickly modify any part of the system with the same workflow.</li>
</ul>
<h2 id="web-status-interface">Web status interface<span class="btn cstyle anchor copyanchor scrollanchor link noborder notitle interactive"><button type="button" title="Copy link to clipboard"><i class="fa-fw fas fa-link fa-lg"></i></button></span></h2>
<p>On a regular Linux distribution, wed largely use systemctls start,
stop, restart and status verbs to manage our applications. gokrazy
comes with a <a href="overview.png">convenient web interface</a> for
seeing process status and stopping/restarting processes.</p>
<h2 id="debugging">Debugging<span class="btn cstyle anchor copyanchor scrollanchor link noborder notitle interactive"><button type="button" title="Copy link to clipboard"><i class="fa-fw fas fa-link fa-lg"></i></button></span></h2>
<p>Sometimes, an interactive <code>busybox</code> session or a quick
<code>tcpdump</code> run are invaluable. <a
href="https://github.com/gokrazy/breakglass">breakglass</a> allows
you to temporarily enable SSH/SCP-based authenticated remote code
execution: scp your statically compiled binary, then run it
interactively via ssh.</p>
<p>Due to no C runtime environment being present, your code must compile
with the environment variable <code>CGO_ENABLED=0</code>. To
cross-compile for the Raspberry Pi 3 or 4,
use <code>GOARCH=arm64</code>. If your program still builds, youre
good to go!</p>
<h2 id="network-updates">Network updates<span class="btn cstyle anchor copyanchor scrollanchor link noborder notitle interactive"><button type="button" title="Copy link to clipboard"><i class="fa-fw fas fa-link fa-lg"></i></button></span></h2>
<p>After building a new gokrazy image on your computer, you can easily
update an existing gokrazy installation in-place thanks to the A/B
partitioning scheme we use. Just use the <code>gok update</code>
command.</p>
<h2 id="minimal-state-and-configuration">Minimal state and configuration<span class="btn cstyle anchor copyanchor scrollanchor link noborder notitle interactive"><button type="button" title="Copy link to clipboard"><i class="fa-fw fas fa-link fa-lg"></i></button></span></h2>
<p>A tiny amount of configuration is built into the images (e.g.
hostname, password, serial console behavior). In general, we prefer
auto-configuration (e.g. DHCP) over config files. If you need more
configurability, you may need to replace some of our programs.</p>
<footer class="footline">
</footer>
</article>
</div>
</main>
</div>
<aside id="R-sidebar" class="default-animation">
<div id="R-header-topbar" class="default-animation"></div>
<div id="R-header-wrapper" class="default-animation">
<div id="R-header" class="default-animation">
<img src="/logo.svg" width="100%" alt="gokrazy logo" title="gokrazy logo">
</div>
<search><form action="/search/index.html" method="get">
<div class="searchbox default-animation">
<button class="search-detail" type="submit" title="Search (CTRL+ALT+f)"><i class="fas fa-search"></i></button>
<label class="a11y-only" for="R-search-by">Search</label>
<input data-search-input id="R-search-by" name="search-by" class="search-by" type="search" placeholder="Search...">
<button class="search-clear" type="button" data-search-clear="" title="Clear search"><i class="fas fa-times" title="Clear search"></i></button>
</div>
</form></search>
</div>
<div id="R-homelinks" class="default-animation homelinks">
<div class="R-menu-divider default-animation">
<hr class="padding">
</div>
<div class="R-sidebarmenu R-shortcutmenu-homelinks">
<ul class="space collapsible-menu">
<li class="active " data-nav-url="/index.html"><a class="padding" href="/index.html"><i class="fa-fw fas fa-home"></i> Home</a></li>
</ul>
</div>
<div class="R-menu-divider default-animation">
<hr class="padding">
</div>
<div class="R-sidebarmenu R-shortcutmenu-headercontrols">
<ul class="">
</ul>
</div>
<div class="R-menu-divider default-animation">
<hr class="padding">
</div>
</div>
<div id="R-content-wrapper" class="highlightable">
<div class="R-sidebarmenu R-shortcutmenu-main">
<ul class="enlarge morespace collapsible-menu">
<li class="" data-nav-url="/quickstart/index.html"><a class="padding" href="/quickstart/index.html"><b>1. </b>Quickstart</a></li>
<li class="" data-nav-url="/platforms/index.html"><a class="padding" href="/platforms/index.html"><b>2. </b>Supported platforms</a></li>
<li class="" data-nav-url="/userguide/index.html"><a class="padding" href="/userguide/index.html"><b>3. </b>Configuration</a><ul id="R-subsections-74b4df3a3d9365853f09e9f1dfe7bbba" class="collapsible-menu"></ul></li>
<li class="" data-nav-url="/packages/index.html"><a class="padding" href="/packages/index.html"><b>4. </b>Available packages</a><ul id="R-subsections-bdf1e8ce92aa8ff6883c617f10480430" class="collapsible-menu"></ul></li>
<li class="" data-nav-url="/development/index.html"><a class="padding" href="/development/index.html"><b>5. </b>Package development</a><ul id="R-subsections-54b0ce3c97b111c8cd4d107325fd580c" class="collapsible-menu"></ul></li>
</ul>
</div>
<div class="R-sidebarmenu R-shortcutmenu-shortcuts">
<div class="nav-title padding">More</div>
<ul class="space collapsible-menu">
<li class="" data-nav-url="https://github.com/gokrazy/gokrazy"><a class="padding" href="https://github.com/gokrazy/gokrazy" rel="external"><i class='fab fa-github'></i> GitHub repo</a></li>
</ul>
</div>
<div id="R-footer-margin"></div>
<div class="R-menu-divider default-animation">
<hr class="padding">
</div>
<div class="R-sidebarmenu R-shortcutmenu-footercontrols">
<ul class="">
</ul>
</div>
<div id="R-footer"><p>Built with <a href="https://github.com/McShelby/hugo-theme-relearn" title="love"><i class="fas fa-heart"></i></a> by <a href="https://gohugo.io/">Hugo</a></p></div>
</div>
</aside>
<script src="/js/perfect-scrollbar/perfect-scrollbar.min.js?1782408721" defer></script>
<script src="/js/theme.min.js?1782408721" defer></script>
<div id="toast-container" role="status" aria-live="polite" aria-atomic="false"></div>
</body>
</html>