Skip to main content
The Celum appliance ships as a vSphere OVA and, for KVM hypervisors, as a qcow2 disk image. Both carry the same system: Harbor, Authentik, OpenBao, PowerDNS, Omni and Celum, with every container image already inside, so the first boot needs no internet access. On vSphere, the OVA asks its questions in the deploy wizard. A KVM hypervisor has no such form, so the qcow2 takes its whole configuration from cloud-init user-data that writes one file: /etc/celum-appliance/appliance.yaml.
This guide covers Proxmox VE and libvirt/KVM. On vSphere, use Deploy on vSphere (OVA) instead.

Before you start

  • Host resources: 8 vCPU, 16 GB of RAM and room for a 120 GB disk. The disk is thin, so it takes only the space that is written.
  • A static IPv4 address, with its gateway and your DNS servers. DHCP works, but Omni needs a fixed address: Talos nodes dial an endpoint that cannot follow a lease.
  • A domain for the appliance, for example celum.example.com. The appliance serves the names below, and every one of them must resolve to its address. A wildcard record such as *.celum.example.com covers them all. app · api · harbor · auth · omni · vault · pdns · pdns-api · home
  • An SSH public key for root (ssh-ed25519, or ssh-rsa of at least 2048 bits). The appliance allows key login only. Without a key, only the hypervisor console reaches it.
  • Network access to the appliance on these ports:

Deploy

1

Download and check the image

The image comes as celum-appliance-VERSION.qcow2; see Where do I start? The email that brings it gives the release and the file’s SHA-256 checksum. Set both as variables, then check the file before you import it:
A good file prints OK. Anything else means the file is damaged or is not the one the email describes: download it again, and do not import it.
2

Write the user-data

Save this as celum-user-data.yaml and change the domain, network, email and SSH key. Everything under content: is the appliance’s configuration file.
celum-user-data.yaml
  • Only domain and admin.email are required. Every component is on by default.
  • Put the SSH keys in admin.sshKeys, not in cloud-init’s own users or ssh_authorized_keys: the appliance authorises them for root itself.
  • Leave passwords blank to have them generated. They are printed at the end of the first boot.
  • The appliance rejects unknown keys, so a typo stops the first boot with an error that names the key, rather than being silently ignored.
  • Omni is under the Business Source License: production use needs an agreement with Sidero Labs. Set omni.enabled: false if you do not have one.
  • Your own certificate or CA, ACME, update credentials, backups, the Image Library and other names are optional blocks of the same file. See Optional settings, and the appliance.yaml reference for every key.
Anything you put in the user-data stays readable wherever it is stored: the Proxmox snippet, the seed ISO, and /var/lib/cloud/ on the appliance. Prefer generated passwords, and remove the user-data after the first boot (see below).
3

Create the VM

  1. Enable the Snippets content type on a storage (Datacenter → Storage → local → Edit → Content), and copy the user-data to it, for example /var/lib/vz/snippets/celum-user-data.yaml.
  2. Create the VM, import the disk and attach the cloud-init drive:
qm disk import prints the name of the volume it created. Use that name in --scsi0 if it differs, for example on directory storage.
Proxmox’s IP Config for cloud-init has no effect: the appliance manages its own network from network: in the user-data. The image has no QEMU guest agent, so Proxmox does not show its address: read it on the console or with celum-appliance status.
4

Watch the first boot

The appliance configures itself in stages, as a systemd unit. Follow it on the console or over SSH:
Each stage records when it is done. If one fails, fix the cause and run celum-appliance bootstrap again: it resumes where it stopped.When it finishes, the generated credentials are printed on the console and written to /root/celum-appliance-credentials.txt.
5

Remove the user-data

After the first boot, /etc/celum-appliance/appliance.yaml is the configuration, and the user-data has done its job. Detach it, so the secrets leave the hypervisor and a later change to it cannot rewrite the file:
  • Proxmox: qm set $ID --delete ide2, then delete the snippet.
  • libvirt: detach the seed ISO if one is still attached, and delete it.

Sign in

Every password is in /root/celum-appliance-credentials.txt, and celum-appliance status prints them again.
  • Trust the appliance CA. With tls.mode: selfsigned, every certificate is signed by a CA the appliance creates. Copy /etc/celum-appliance/tls/ca.crt and add it to your trust store. Until a client trusts it, it fails before HTTP: curl reports http=000, which looks like a network fault.
  • Turn on IAM once you have signed in to Celum and confirmed you are in celum-admins. Set iamEnabled: true under components.celum in /etc/celum-appliance/appliance.yaml, then render the files again and restart Celum:
  • Talos nodes managed by Omni must trust the appliance CA too, through a TrustedRootsConfig document.

Optional settings

Each block below goes into the same appliance.yaml, under content: in the user-data. Leave a block out to keep its default.
Certificates and keys go into the file as PEM, indented under |. The base64 that the OVA’s form asks for is refused here, with tls.cert: not PEM.

Your own certificate

The certificate must cover every name the appliance serves; a wildcard such as *.celum.example.com covers them all. The first boot checks it before anything starts. If it misses any name other than home, the boot stops and lists the missing names.

Your own CA

The CA signs every certificate the appliance serves, so clients that trust it keep trusting the appliance after a redeploy. To create one, see Use your own CA.

Certificates from ACME (DNS-01)

  • credentials is a map, with one variable per line, not a comma-separated list.
  • Omni is switched off in this mode. Omni serves its own certificate, and ACME certificates stay inside Traefik.

Updates

The registry defaults to registry.celum.io. You can also enter the account later, on the start page.

Off-box backups

Set all four or none. Snapshots are written under celum-appliance/DOMAIN/ unless you set prefix. For an endpoint with a private CA, add its PEM as ca: |.

Image Library source

This is the S3 bucket that Celum’s Image Library imports guest images from. Set all four or none. Supervisor nodes download from the endpoint directly, so it must be reachable from them and serve a certificate they trust.

Other names

The keys are home, celum (the web interface, app by default), api, harbor, auth, omni, vault, pdns-api and pdns.

More DNS zones

These zones are created empty, for external-dns in tenant clusters to fill. The appliance’s own domain is always served.

Several network interfaces

With more than one NIC, name the one the appliance serves on. The first boot stops if it cannot tell them apart.

Change the configuration later

Edit /etc/celum-appliance/appliance.yaml on the appliance, then check it: celum-appliance config shows the configuration as the appliance reads it, with warnings, or the error that would stop it. A plain celum-appliance bootstrap skips every stage that has already finished, so after the first boot it applies nothing. Render the files again from appliance.yaml, then re-run the stage of the component you changed:
This does not cover network and tls: earlier stages, 20 and 40, apply those. To enlarge the disk, resize it in the hypervisor. The filesystem grows at the next boot.

Troubleshooting

The user-data never reached the VM, so the appliance found no configuration. Check that the cloud-init drive or seed ISO is attached, then read cloud-init status --long and /var/log/cloud-init.log. Fix it, reboot, and the bootstrap starts again.
Check DNS first: all the names under Before you start must resolve to the appliance. This is by far the most common cause.
Open the console and run celum-appliance status. Without a network: block, the appliance asks DHCP on its first Ethernet interface. With one, address (as CIDR) and gateway must both be set. SSH accepts only the keys in admin.sshKeys.
IAM was enforced before your group membership was in place. Set iamEnabled: false under components.celum in /etc/celum-appliance/appliance.yaml, then run celum-appliance bootstrap --only 50 --force and celum-appliance bootstrap --only 80 --force.
Omni needs a static address. With a self-signed certificate, the nodes must trust the appliance CA. Nodes behind NAT need omni.wireguardAddress set to an address they can reach. Omni also refuses every call until its EULA is accepted: set omni.eula.name, or accept it in the Omni interface.