Self-hosted homelab platform · Rust · SwiftUI

One server. Asleep until
you need it.

Everything that runs on my home server, published as it is: Wake-on-LAN from the Mac, a terminal in my pocket, my photos and drive with local AI search, and light shows synced to a song. No cloud, no subscriptions, nothing port-forwarded.

$ cargo install --path cli
$ atlas boot   # wake the server, wait for ssh, drop in
Boot to shell
1
command, from asleep
Idle draw
~0 W
the box sleeps until woken
iOS apps
3
SwiftUI, on the tailnet
Search vectors
2048-d
photos and video
Attack surface
0 ports
forwarded to the internet

Everything meets on the tailnet. The two HTTP services are firewalled to loopback plus tailnet by nftables and take a bearer token on top. sshd and Art-Net stay LAN-only by decision, and public dev URLs ride an outbound Cloudflare Tunnel rather than an open port.

v0.0.1, beta. This is one person’s real homelab published as-is: it runs daily on my hardware, but interfaces may change and sharp edges exist.

One paste

Let your agent set it up

You were going to paste it into Claude anyway. I saved you the typing. It fetches the runbook, works out which parts of Atlas you actually want, and walks the machine-level setup with you.

Paste into your agent
Set me up with Atlas — a self-hosted homelab platform: Wake-on-LAN Rust CLI,
control-plane API, self-hosted photos with local AI search, Hue light shows.
Run this first, then follow it exactly, top to bottom:

    curl -fsSL https://atlas.lukaloehr.com/setup.txt

Ask me its first question before doing anything else. Never print my tokens.
Get started

Three steps

Ah, so you haven’t fallen for the vibe yet. Respect. I still read commands before I run them too.

01

Install the CLI

On the Mac. Then write your machine values into ~/.config/atlas/env — MAC address for the Wake-on-LAN packet, hostnames, tailnet name. The setup guide lists every key.

$ cargo install --path cli
$ mkdir -p ~/.config/atlas && $EDITOR ~/.config/atlas/env
02

Wake the box

atlas boot sends the magic packet, waits for SSH and drops you in. atlas api builds and installs the control-plane server, atlas status checks LAN and tailnet reachability, atlas shutdown puts it back to sleep.

$ atlas boot     # Wake-on-LAN, then ssh
$ atlas api      # build + install the control plane
$ atlas status
03

Bring up the database

On the server. Postgres 17 with pgvector backs the media library, the knowledge graph, the embeddings and the resumable ingest queue. Everything else builds on it.

$ cd backend/docker && cp .env.example .env
$ docker compose up -d

Hardware, Ubuntu, Tailscale, Wake-on-LAN, CUDA, models and iOS builds are all in docs/SETUP.md.

Reference

What is in the repo

Directories

cli/Rust CLI on the Mac: boot, build, dev, secrets, logs
api/atlas-api :8787 — metrics, WebSocket PTY, power
backend/Postgres 17 + pgvector, ingest queue
apps/Atlas Admin, Lightshow, Photos (SwiftUI)
lightshows/song analysis → choreography → Art-Net
builder/pinned universal build image, 3 targets
infra/, scripts/AdGuard DNS, health, firewall, backups

Stack

ServerRust · axum · Docker
DatabasePostgres 17 + pgvector
AI pipelinePython on GPU — faces, embeddings
ClientsSwiftUI, 3 iOS apps
NetworkTailscale tailnet, nftables
Public dev URLsCaddy + named Cloudflare Tunnel
LightsArt-Net → Philips Hue, plus fog