Docs / Cloud-init and machine images

Cloud-init and machine images

Two ways to skip the manual install: paste a cloud-init template when you create a VPS, or build a machine image that already has everything installed.

Cloud-init (one server at a time)

panel/deploy/cloud-init.yaml is a user-data template. Edit the few settings at the top, paste it into your provider's "user data" box when creating the server, and the panel is up when the server finishes booting. Progress and any failure land in /var/log/nimbopanel-provision.log.

Do not treat user data as a secret store

This is the part worth reading twice. On every major provider, user data stays retrievable from inside the running instance over HTTP at 169.254.169.254 — and that address is reachable by any process on the machine, including a hosting customer's PHP script.

So a licence key pasted into user data is readable by every customer you host, unless something stops it. The template stops it in two steps, in this order:

  1. it closes the metadata service to everyone except root, before the key reaches disk;
  2. after the installer has stored the key in root-only configuration, it shreds the on-disk copy of the user data.

If you would rather not put the key there at all, leave it blank and enter it from the panel afterwards. The server runs unlicensed until you do, which is a supported state.

Machine images (many servers from one build)

panel/deploy/packer/nimbopanel.pkr.hcl builds an image with the whole stack installed. That is where the minutes go — packages, PHP, mail, DNS, the database — and none of it differs between servers.

The mistake that makes every clone the same server

An image must contain no identity. If it does, every server built from it shares that identity:

Baked in by mistake What happens on every clone
SSH host keys They all present the same key. Anyone positioned between a customer and their server can impersonate it, on all of them, with no warning shown
The Nimbopanel instance-id The licence fingerprint derives from it, and the installer never re-seeds an id that already exists — so a thousand servers look like one activation
/etc/machine-id systemd, DHCP leases and journald identity collide
The panel database and config Admin password, licence key and every account ship inside a file strangers download
DKIM keys, TLS certificates Issued for the build machine; meaningless on a clone, and leaked to everyone who has the image

None of these announce themselves. They are found later, by somebody else.

panel/deploy/image-deidentify.sh removes all of it, and the Packer build runs it as the last step and then re-runs it with --check, so a build fails rather than producing a snapshot that only looks clean. Everything removed is recreated on the clone's first boot: sshd generates new host keys, systemd writes a new machine-id, the installer seeds a fresh instance-id.

/etc/machine-id is left empty, not deleted — systemd reads an empty file as "generate one at boot", while a missing file stops some images booting at all.

Verify before you publish

sudo ./image-deidentify.sh          # remove
sudo ./image-deidentify.sh --check  # confirm, exits non-zero if anything survives

Run the check on a booted clone too, not just at build time. If it reports anything, do not publish the image.

Marketplace listings

Provider "1-click app" programmes (Vultr, DigitalOcean, Linode, Contabo) each have their own submission format and review. The image above is the artefact they ask for; the paperwork is per-provider and is not something this tooling can do for you.