Repository navigation
Expand file tree
/
Copy pathindex.html
More file actions
300 lines (285 loc) · 20.6 KB
/
Copy pathindex.html
File metadata and controls
300 lines (285 loc) · 20.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Linux containers on a rooted Android phone, on its own kernel. systemd or OpenRC as PID 1, boots in 150 to 750 ms, one static 400 KB binary. Docker runs inside.">
<title>Droidspaces: Linux containers on Android</title>
<meta property="og:title" content="Droidspaces: Linux containers on Android">
<meta property="og:description" content="Linux containers on a rooted Android phone, on its own kernel. systemd or OpenRC as PID 1, boots in 150 to 750 ms, one static 400 KB binary. Docker runs inside.">
<meta property="og:url" content="https://www.droidspaces.org/">
<meta property="og:type" content="website">
<meta property="og:site_name" content="Droidspaces">
<meta property="og:image" content="https://www.droidspaces.org/assets/images/og-image.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="The Droidspaces wordmark, the words Linux containers on Android, and a terminal starting an Ubuntu container">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Droidspaces: Linux containers on Android">
<meta name="twitter:description" content="Linux containers on a rooted Android phone, on its own kernel. systemd or OpenRC as PID 1, boots in 150 to 750 ms, one static 400 KB binary. Docker runs inside.">
<meta name="twitter:image" content="https://www.droidspaces.org/assets/images/og-image.png">
<link rel="canonical" href="https://www.droidspaces.org/">
<link rel="stylesheet" href="/assets/css/site.css?v=b310d7c992">
<link rel="icon" href="/favicon.ico">
<link rel="apple-touch-icon" href="/favicon.ico">
<script>
(function () {
const savedTheme = localStorage.getItem('theme');
if (savedTheme) {
document.documentElement.setAttribute('data-theme', savedTheme);
}
})();
</script>
<script type="application/ld+json">
[
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Droidspaces",
"url": "https://www.droidspaces.org/",
"description": "Droidspaces is a Linux container runtime for Android and Linux. It runs full distributions with systemd or OpenRC as PID 1 in their own PID, mount, UTS, IPC and cgroup namespaces. One static binary of about 400 KB built against musl, for aarch64, armhf, x86_64, x86 and riscv64, with a Material 3 app to manage containers.",
"applicationCategory": "DeveloperApplication",
"applicationSubCategory": "Containerization, Virtualization, Android Development Tools",
"operatingSystem": "Android, Linux, Android Recovery, Ramdisk",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD"
},
"downloadUrl": "https://github.com/ravindu644/Droidspaces-OSS/releases/latest",
"featureList": [
"Full namespace isolation (PID, MNT, NET, UTS, IPC, Cgroup)",
"systemd and OpenRC init support as PID 1",
"Single static binary of about 400 KB, no dependencies",
"GPU acceleration with Turnip on Android",
"A monitor process per container, detached from the app",
"Network isolation with NAT, Veth pairs, or air-gapped",
"USB, block device, sensor, serial device access",
"Portable rootfs.img support",
"Material 3 management app with built-in terminal"
],
"fileSize": "400KB",
"softwareVersion": "6.6.0",
"license": "https://github.com/ravindu644/Droidspaces-OSS/blob/main/LICENSE",
"screenshot": "https://www.droidspaces.org/assets/screenshots/containers.webp",
"author": { "@id": "https://www.droidspaces.org/#org" },
"publisher": { "@id": "https://www.droidspaces.org/#org" },
"sameAs": [
"https://github.com/ravindu644/Droidspaces-OSS",
"https://t.me/Droidspaces"
]
},
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Droidspaces",
"url": "https://www.droidspaces.org/",
"description": "Linux containers on a rooted Android phone, on its own kernel. systemd or OpenRC as PID 1, boots in 150 to 750 ms, one static 400 KB binary. Docker runs inside.",
"publisher": { "@id": "https://www.droidspaces.org/#org" }
},
{
"@context": "https://schema.org",
"@type": "Organization",
"@id": "https://www.droidspaces.org/#org",
"name": "Droidspaces",
"url": "https://www.droidspaces.org/",
"logo": "https://www.droidspaces.org/assets/images/og-image.png",
"sameAs": [
"https://github.com/ravindu644/Droidspaces-OSS",
"https://t.me/Droidspaces"
]
}
]
</script>
</head>
<body>
<!--NAV_START-->
<a class="button button-filled skip-link" href="#main">Skip to content</a>
<nav class="nav" aria-label="Main">
<div class="nav-inner">
<a href="/" class="nav-logo"><svg viewBox="8.25 10.35 31.5 27.3" fill="currentColor" aria-hidden="true"><path d="M36.85 30.16H11.15c-0.82 0-1.48 0.68-1.48 1.52v3.05c0 0.84 0.66 1.52 1.48 1.52h25.69c0.82 0 1.48-0.68 1.48-1.52v-3.05c0-0.84-0.66-1.52-1.48-1.52ZM12.58 34.97c-0.95 0-1.73-0.79-1.73-1.77s0.77-1.77 1.73-1.77 1.73 0.79 1.73 1.77-0.77 1.77-1.73 1.77Z"/><path d="M36.85 21.00H11.15c-0.82 0-1.48 0.68-1.48 1.52v3.05c0 0.84 0.66 1.52 1.48 1.52h25.69c0.82 0 1.48-0.68 1.48-1.52v-3.05c0-0.84-0.66-1.52-1.48-1.52ZM12.58 25.82c-0.95 0-1.73-0.79-1.73-1.77s0.77-1.77 1.73-1.77 1.73 0.79 1.73 1.77-0.77 1.77-1.73 1.77Z"/><path d="M36.84 11.74H11.15c-0.82 0-1.48 0.68-1.48 1.52v3.05c0 0.84 0.66 1.52 1.48 1.52h25.69c0.82 0 1.48-0.68 1.48-1.52v-3.05c0-0.84-0.66-1.52-1.48-1.52ZM12.58 16.57c-0.95 0-1.73-0.79-1.73-1.77s0.77-1.77 1.73-1.77 1.73 0.79 1.73 1.77-0.77 1.77-1.73 1.77Z"/></svg> Droidspaces</a>
<div id="nav-drawer" class="nav-drawer" popover>
<button class="icon-button nav-close" popovertarget="nav-drawer" popovertargetaction="hide" aria-label="Close menu"><span class="icon" aria-hidden="true">close</span></button>
<ul class="nav-links">
<li><a href="/downloads.html">Download</a></li>
<li><a href="/docs/">Documentation</a></li>
<li><a href="/docs/community-supported-devices.html">Devices</a></li>
<li><a href="https://github.com/ravindu644/Droidspaces-OSS" rel="noopener noreferrer">GitHub</a></li>
<li><a href="https://t.me/Droidspaces" rel="noopener noreferrer">Telegram</a></li>
</ul>
</div>
<button class="icon-button theme-toggle" id="theme-toggle" aria-label="Toggle theme"><span class="icon" aria-hidden="true"></span></button>
<button class="icon-button nav-menu" popovertarget="nav-drawer" aria-label="Open menu"><span class="icon" aria-hidden="true">menu</span></button>
</div>
</nav>
<!--NAV_END-->
<main id="main">
<section class="section hero split">
<div>
<h1>A homelab that keeps running when the power cuts.</h1>
<p class="title-lg">Your old Android phone has a battery, mobile data and a Linux kernel. <strong>Droidspaces</strong> runs full Linux distributions on that kernel as containers, with systemd or OpenRC as PID 1. No emulation, no virtual machine.</p>
<div class="actions">
<a href="/downloads.html" class="button button-filled"><span class="icon" aria-hidden="true">download</span>Download</a>
<a href="/docs/" class="button button-outlined"><span class="icon" aria-hidden="true">menu_book</span>Documentation</a>
</div>
<p class="body-md">Release <span data-version>v6.6.0</span>, GPLv3. <span data-stars>2,291</span> stars and <span data-contributors>89</span> contributors <a href="https://github.com/ravindu644/Droidspaces-OSS" rel="noopener noreferrer">on GitHub</a>.</p>
</div>
<div class="stage">
<div class="shape arrive" style="--shape: url(/assets/shapes/cookie-12.svg)"></div>
<div class="phone arrive"><div class="phone-screen"><div class="phone-display" data-bar><img src="/assets/screenshots/containers.webp" width="720" height="1428" fetchpriority="high" alt="The Containers screen of the Droidspaces app, listing Alpine, Docmost and OpenWRT containers, each running, with stop and restart buttons"></div></div></div>
</div>
</section>
<section class="section split split-phone-left">
<div class="stage">
<div class="shape arrive" style="--shape: url(/assets/shapes/sunny.svg)"></div>
<div class="phone arrive"><div class="phone-screen"><div class="phone-display"><img src="/assets/screenshots/systemd-services.webp" width="720" height="1428" alt="The Systemd Services screen of a container, with 20 units running, listing act_runner (the Gitea Actions runner), chrony, containerd and cron, each running with stop and disable buttons" loading="lazy" decoding="async"></div></div></div>
</div>
<div>
<h2>Set it up once. Forget it.</h2>
<p class="title-lg">Droidspaces is an alternative to Docker and LXC, built for a phone. Your services run the way they would on a Linux server, and after the first setup nothing needs you.</p>
<ol class="boot-chain">
<li><span class="chain-fill" aria-hidden="true"></span><h3>Your phone boots.</h3><p class="body-md">After an update, a reboot or a flat battery.</p></li>
<li><span class="chain-fill" aria-hidden="true"></span><h3>Droidspaces starts your containers.</h3><p class="body-md">From init.rc or a boot script, before you unlock the phone, while /data is still encrypted.</p></li>
<li><h3>The init system starts your services.</h3><p class="body-md">systemd or OpenRC brings up every enabled unit. No app to open, no command to type.</p></li>
</ol>
<ul class="chip-set" aria-label="Services people run in Droidspaces">
<li class="chip">Gitea</li><li class="chip">Jellyfin</li><li class="chip">Docmost</li><li class="chip">Tailscale</li><li class="chip">Trilium</li><li class="chip">VS Code server</li><li class="chip">Cloudflare Tunnel</li><li class="chip">ntfy</li><li class="chip">Uptime Kuma</li><li class="chip">Immich</li><li class="chip">Nextcloud</li><li class="chip">Vaultwarden</li><li class="chip">Pi-hole</li><li class="chip">Home Assistant</li>
</ul>
</div>
</section>
<section class="section split">
<div class="stage">
<div class="shape shape-secondary arrive" style="--shape: url(/assets/shapes/cookie-9.svg)"></div>
<div class="phone arrive"><div class="phone-screen"><div class="phone-display" data-bar><img src="/assets/screenshots/terminal.webp" width="720" height="1428" alt="The app's built-in terminal inside an Ubuntu container showing fastfetch output and systemctl status with systemd as PID 1 and services such as docker, gitea, jellyfin and ssh running" loading="lazy" decoding="async"></div></div></div>
</div>
<div>
<h2>A real Linux, not an emulation.</h2>
<p class="title-lg">Each container gets its own PID, mount, UTS, IPC, cgroup and network namespace on the phone's kernel, behind NAT by default. systemd boots as PID 1 in 150 to 750 ms.</p>
<ul class="chip-set" aria-label="Init systems and what the kernel gives each container">
<li class="chip">systemd</li><li class="chip">OpenRC</li><li class="chip">runit</li><li class="chip">s6</li><li class="chip">PID namespace</li><li class="chip">Mount namespace</li><li class="chip">Cgroup v1 and v2</li><li class="chip">journald</li>
</ul>
</div>
</section>
<section class="section split split-phone-left">
<div>
<h2>It sits on your network like a server.</h2>
<p class="title-lg">Each container has its own monitor daemon, detached from the app, so closing or uninstalling the app stops nothing. Inside a container you run services the way you would on a Linux server, including nested containers: Docker, Podman and LXC itself.</p>
<ul class="chip-set" aria-label="Networking, and what runs inside a container">
<li class="chip">NAT networking</li><li class="chip">Host networking</li><li class="chip">Port forwarding</li><li class="chip">OpenWRT as a gateway</li><li class="chip">Docker</li><li class="chip">Podman</li><li class="chip">Flatpak</li><li class="chip">bwrap</li>
</ul>
</div>
<div class="stage">
<div class="shape shape-secondary arrive" style="--shape: url(/assets/shapes/clover-4.svg)"></div>
<div class="phone arrive"><div class="phone-screen"><div class="phone-display" data-bar><img src="/assets/screenshots/hardware.webp" width="720" height="1428" alt="Container settings with port forwarding, DNS servers, and switches for Android storage, hardware access, GPU access, Termux:X11 and VirGL" loading="lazy" decoding="async"></div></div></div>
</div>
</section>
<section class="section split">
<div class="stage">
<div class="phone-group">
<figure class="phone" tabindex="0"><div class="phone-screen"><div class="phone-display" data-bar><img src="/assets/screenshots/home.webp" width="720" height="1428" alt="The Home screen showing the backend installed with the daemon running, four containers, kernel version, SELinux enforcing, Android 15 and aarch64" loading="lazy" decoding="async"></div></div><figcaption class="body-md">Home: backend state, kernel and architecture.</figcaption></figure>
<figure class="phone" tabindex="0"><div class="phone-screen"><div class="phone-display"><img src="/assets/screenshots/container-info.webp" width="720" height="1428" alt="Container info for Ubuntu 24.04: distribution, hostname, uptime of 8 days, IP addresses, CPU and RAM usage, disk usage, users and a terminal button" loading="lazy" decoding="async"></div></div><figcaption class="body-md">Container info: addresses, CPU, RAM, disk and users.</figcaption></figure>
<figure class="phone" tabindex="0"><div class="phone-screen"><div class="phone-display" data-bar><img src="/assets/screenshots/panel.webp" width="720" height="1428" alt="The Panel screen with uptime, IP addresses, CPU and RAM for four containers" loading="lazy" decoding="async"></div></div><figcaption class="body-md">Panel: uptime and usage for every container.</figcaption></figure>
</div>
</div>
<div>
<h2>Run it from the app.</h2>
<p class="title-lg">Install, start, stop and edit containers, open a terminal inside one, and watch its CPU, memory and addresses. The phone's hardware is one switch each.</p>
<ul class="chip-set" aria-label="Hardware the app hands to a container">
<li class="chip">Turnip on Adreno</li><li class="chip">VirGL</li><li class="chip">Termux:X11</li><li class="chip">PulseAudio</li><li class="chip">USB</li><li class="chip">Sensors</li>
</ul>
</div>
</section>
<section class="section">
<h2>What each approach costs.</h2>
<p class="title-lg">Linux on Android has several routes: PRoot, chroot, LXC or Docker through Termux, and Droidspaces. Each one pays for something. This is the bill.</p>
<div class="table-wrap">
<table>
<thead>
<tr><th scope="col"></th><th scope="col" class="hl">Droidspaces</th><th scope="col">LXC via Termux</th><th scope="col">Docker via Termux</th><th scope="col">chroot</th><th scope="col">PRoot</th></tr>
</thead>
<tbody>
<tr><td>Technology</td><td class="hl">Namespaces</td><td>Namespaces</td><td>Namespaces</td><td>Path redirection</td><td>Syscall hooking</td></tr>
<tr><td>Performance</td><td class="hl">Native</td><td>Native</td><td>Native</td><td>Native</td><td>Moderate</td></tr>
<tr><td>Boot time</td><td class="hl">150 to 750 ms on systemd</td><td>750 to 2000 ms on systemd</td><td>No init</td><td>No init</td><td>No init</td></tr>
<tr><td>Init support</td><td class="hl">Full</td><td>Full</td><td>None</td><td>None</td><td>None</td></tr>
<tr><td>Persistence</td><td class="hl">A monitor process per container</td><td>Low</td><td>Low</td><td>Low</td><td>Low</td></tr>
<tr><td>Hardware access</td><td class="hl">One switch</td><td>Manual setup</td><td>Manual setup</td><td>Manual setup</td><td>None</td></tr>
<tr><td>GPU access</td><td class="hl">One switch</td><td>Manual setup</td><td>Manual setup</td><td>Manual setup</td><td>Moderate</td></tr>
<tr><td>Termux:X11</td><td class="hl">One switch</td><td>Manual setup</td><td>Manual setup</td><td>Manual setup</td><td>Moderate</td></tr>
<tr><td>Privileged mode</td><td class="hl">Full, configurable (nomask, nocaps, noseccomp)</td><td>Manual setup</td><td>Yes (--privileged)</td><td>Full</td><td>No</td></tr>
<tr><td>Run at boot</td><td class="hl">Yes, from init.rc or service.d</td><td>No</td><td>No</td><td>No</td><td>No</td></tr>
<tr><td>Portable rootfs.img</td><td class="hl">Yes</td><td>No</td><td>No</td><td>No</td><td>No</td></tr>
<tr><td>Binary size</td><td class="hl">400 KB</td><td>10 MB or more</td><td>50 MB or more</td><td>None needed</td><td>10 MB or more</td></tr>
</tbody>
</table>
</div>
</section>
<section class="section">
<h2>Get it running.</h2>
<p class="title-lg">The APK carries the runtime and the app. Linux gets a static tarball.</p>
<div class="columns">
<div>
<h3>Android</h3>
<ul>
<li>Kernel 3.10 or newer</li>
<li>Root through KernelSU, Magisk or APatch</li>
<li>A kernel built with the <a href="/docs/kernel-configuration.html">documented configuration</a></li>
<li>aarch64, armhf, x86_64 or x86</li>
</ul>
</div>
<div>
<h3>Linux</h3>
<ul>
<li>Kernel 3.10 or newer</li>
<li>Root, or a running droidspaces daemon</li>
<li>No custom kernel</li>
<li>aarch64, armhf, x86_64, x86 or riscv64</li>
</ul>
</div>
</div>
<div class="actions">
<a href="/downloads.html" class="button button-filled"><span class="icon" aria-hidden="true">download</span>Download</a>
<a href="/docs/" class="button button-outlined"><span class="icon" aria-hidden="true">menu_book</span>Documentation</a>
<a href="/docs/community-supported-devices.html" class="button button-outlined"><span class="icon" aria-hidden="true">smartphone</span>Supported devices</a>
</div>
</section>
</main>
<!--FOOTER-->
<footer class="footer">
<div class="footer-inner">
<div>
<a href="/" class="nav-logo"><svg viewBox="8.25 10.35 31.5 27.3" fill="currentColor" aria-hidden="true"><path d="M36.85 30.16H11.15c-0.82 0-1.48 0.68-1.48 1.52v3.05c0 0.84 0.66 1.52 1.48 1.52h25.69c0.82 0 1.48-0.68 1.48-1.52v-3.05c0-0.84-0.66-1.52-1.48-1.52ZM12.58 34.97c-0.95 0-1.73-0.79-1.73-1.77s0.77-1.77 1.73-1.77 1.73 0.79 1.73 1.77-0.77 1.77-1.73 1.77Z"/><path d="M36.85 21.00H11.15c-0.82 0-1.48 0.68-1.48 1.52v3.05c0 0.84 0.66 1.52 1.48 1.52h25.69c0.82 0 1.48-0.68 1.48-1.52v-3.05c0-0.84-0.66-1.52-1.48-1.52ZM12.58 25.82c-0.95 0-1.73-0.79-1.73-1.77s0.77-1.77 1.73-1.77 1.73 0.79 1.73 1.77-0.77 1.77-1.73 1.77Z"/><path d="M36.84 11.74H11.15c-0.82 0-1.48 0.68-1.48 1.52v3.05c0 0.84 0.66 1.52 1.48 1.52h25.69c0.82 0 1.48-0.68 1.48-1.52v-3.05c0-0.84-0.66-1.52-1.48-1.52ZM12.58 16.57c-0.95 0-1.73-0.79-1.73-1.77s0.77-1.77 1.73-1.77 1.73 0.79 1.73 1.77-0.77 1.77-1.73 1.77Z"/></svg> Droidspaces</a>
<p>A Linux container runtime for Android. It boots systemd or OpenRC as PID 1 on the phone's own kernel.</p>
</div>
<div>
<h3>Project</h3>
<ul>
<li><a href="/downloads.html">Download</a></li>
<li><a href="/docs/">Documentation</a></li>
<li><a href="/docs/community-supported-devices.html">Devices</a></li>
<li><a href="https://github.com/ravindu644/Droidspaces-OSS" rel="noopener noreferrer">GitHub</a></li>
</ul>
</div>
<div>
<h3>Community</h3>
<ul>
<li><a href="https://t.me/Droidspaces" rel="noopener noreferrer">Telegram</a></li>
<li><a href="https://github.com/ravindu644/Droidspaces-OSS/issues" rel="noopener noreferrer">Issues</a></li>
<li><a href="https://github.com/ravindu644/Droidspaces-OSS/graphs/contributors" rel="noopener noreferrer">Contributors</a></li>
</ul>
</div>
<div>
<h3>Legal</h3>
<ul>
<li><a href="https://github.com/ravindu644/Droidspaces-OSS/blob/main/LICENSE" rel="noopener noreferrer">GPLv3 licence</a></li>
<li><a href="https://github.com/Droidspaces/droidspaces.github.io" rel="noopener noreferrer">This site's source</a>, <a href="https://github.com/Droidspaces/droidspaces.github.io/blob/main/LICENSE" rel="noopener noreferrer">MIT licence</a></li>
<li>Maintained by <a href="https://github.com/ravindu644" rel="noopener noreferrer">ravindu644</a></li>
</ul>
</div>
</div>
</footer>
<a href="#" class="button button-tonal to-top" aria-label="Back to top"><span class="icon" aria-hidden="true">arrow_upward</span></a>
<!--/FOOTER-->
<script src="/assets/js/site.js?v=21a4abed9c" defer></script>
</body>
</html>