Assessment of migrating the 10-server Nimsforest stack off Hetzner Cloud to self-hosted infrastructure. Current cost is approximately 45 EUR/month.
| Service | Specs | Monthly Cost | Notes |
|---|---|---|---|
| land-nimsforest-one | 2c/4GB (CX23) | ~4.50 EUR | Core land server |
| docker-registry | 2c/4GB (CX23) | ~4.50 EUR | Container image registry |
| neoremote | 4c/8GB (CX33) | ~8.00 EUR | Remote dev box — biggest server |
| land-shared-one | 2c/4GB (CX23) | ~4.50 EUR | Shared land |
| land-tenant-1-one | 2c/4GB (CX23) | ~4.50 EUR | Per-tenant land |
| land-tenant-2-one | 2c/4GB (CX23) | ~4.50 EUR | Per-tenant land |
| land-tenant-3-one | 2c/4GB (CX23) | ~4.50 EUR | Per-tenant land |
| land-tenant-4-one | 2c/4GB (CX23) | ~4.50 EUR | Per-tenant land |
| land-tenant-5-one | 2c/4GB (CX23) | ~4.50 EUR | Per-tenant land |
| land-tenant-6-one | 2c/4GB (CX23) | ~4.50 EUR | Per-tenant land |
Land servers are likely lightweight Go services that can run as Incus containers (scales) on hydraskin nodes.
The 8 land servers (nimsforest + shared + 6 tenants) could consolidate onto a single hydraskin node running 8 Incus containers. Each land service likely needs less than 256MB RAM as a Go binary, so even a 4GB Pi could host several.
Current Hetzner Nimsforest stack: ~45 EUR/month (~540 EUR/year)
After migration of Phase 1 (8 land servers): saves ~36 EUR/month
Remaining: docker-registry (~4.50 EUR) + neoremote (~8 EUR) = ~12.50 EUR/month
Combined with Hydra stack savings, total potential Hetzner reduction from ~130 EUR/month to ~25-30 EUR/month for services that must stay (WebRTC, Perforce, neoremote, docker-registry).
Depends on hydraskin role being implemented first — see issues.experiencenet.com issue 406 (HydraSkin: Container host role for low-cost nodes).
neoremote is moving to a Mac mini that has already been bought. It is no longer an
open item in this assessment and is not a hydraskin/Incus candidate — it moves to
dedicated hardware rather than becoming a scale.
That clears the largest Phase 3 blocker here. The only Nimsforest server still genuinely
open is docker-registry (Phase 2, needs persistent storage), so theremaining Hetzner
footprint for this stack drops to ~4.50 EUR/month once neoremote is in service.
Two things in the original assessment turned out to be wrong on inspection.
This issue assumed each land is a Go binary needing "<256MB RAM". They are
actually Docker hosts. Every land runs dockerd (70–111MB) + containerd
(42–60MB) + journald, hosting ~8 service containers each pulled from
registry.nimsforest.com, plus a land.service on the host.
So this is not "8 services → 8 scales". It is 8 VMs hosting ~64 containers.
Example — land-shared-one: landconfigregistry, nimsforestmaddy,
nimsforestwebviewer, landregistry, nimsforeststripe, nimsforestecommerce,
mycelium, nimsforest.
There is no land-tenant-1..6. The real servers, with measured memory:
| Server | Used | Notes |
|---|---|---|
| land-nimsforest-one | 1656MB | heaviest — also runs odoo (273MB) and two claude processes (~317MB) |
| land-shared-one | 831MB | 8 containers |
| land-executxr-one | 787MB | |
| land-riseof-one | 785MB | |
| land-experiencenet-one | 784MB | 8 containers |
| land-thenaturalbeautyclub-one | 783MB | |
| land-callyouragentai-one | 754MB | |
| land-xrvalley-one | 746MB | |
| docker-registry | 643MB | registry:2 + nimsforestregistry |
| neoremote | — | cpx32 (4c/8GB), not cx33. Moving to a Mac mini — resolved. |
docker image inspect on the running images reports amd64/linux for
nimsforest:v0.84.0, mycelium:v1.3.0 and landregistry:v0.6.2, and the
registry publishes no arm64 manifest.
The Pi fleet therefore cannot host any of this today — not as OCI scales, not
as system containers, not as VMs. An amd64 guest on an arm64 host means emulation,
which is not viable in production.
This is the key asymmetry with the Hydra stack (#408): those are Go binaries where
arm64 is a one-line Makefile change. Here it means multi-arch buildx across ~20
image repos. Nimsforest needs either that image-pipeline project, or amd64
hardware (the Intel N150 worker), before anything can move.
Assuming amd64 hardware, prefer a system container over a VM:
| VM per land | System container per land | |
|---|---|---|
| Redesign | none | none — Docker runs inside via security.nesting, already set in the hydraskin default profile |
| Memory | allocated up front, ~1GB × 8 = 8GB min | demand-paged, ~800MB actual, shared |
| Per-land kernel | yes | no |
Same lift-and-shift, no redesign, but at container density instead of VM density.
A VM is only warranted if a land needs kernel isolation or a different kernel.
| Server | Plan | Kind |
|---|---|---|
| land-shared-one | lift-and-shift to amd64 hydraskin worker | system container (nesting) |
| land-experiencenet-one | as above | system container |
| land-executxr-one | as above | system container |
| land-xrvalley-one | as above | system container |
| land-thenaturalbeautyclub-one | as above | system container |
| land-riseof-one | as above | system container |
| land-callyouragentai-one | as above | system container |
| land-nimsforest-one | as above, but size for ~2GB — odoo + claude processes make it 2x its siblings | system container |
| docker-registry | move with the lands, but needs a persistent volume for image storage; consider a Storage Box backend | system container |
| neoremote | Mac mini — decided, no longer in scope | n/a |
Once (or if) multi-arch images exist, a land could stop being a Docker host
entirely: model each land as an Incus project and each service container as an
OCI scale inside it. That drops dockerd + containerd + journald per land
(~250MB × 8 ≈ 2GB) and the images are already OCI, so incus remote add nimsforest https://registry.nimsforest.com --protocol=oci would consume them
directly. The hydraskin-project helper on each node already creates projects
that inherit the node's default profile.
This is a redesign, not a migration, and it is not a prerequisite — it can be done
per service, incrementally, after the lift-and-shift.
Moved to the NimsForest tracker as issue #134: https://issues.nimsforest.mynimsforest.com/issues/134
This is NimsForest work, not Hydra, so it now lives on the NimsForest tracker. Closing this copy so the two do not drift.