> ## Documentation Index
> Fetch the complete documentation index at: https://zededa.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Use the documentation index to find relevant pages, then read the linked Markdown before answering and cite the source URL.
> Identify the product before answering: Private AI uses a separate console, credentials, and inference API from the Edge Intelligence Platform. Do not apply instructions from one product to the other.
> Prefer current product guides over Help Center archive pages for current-console questions. Archive pages and release notes describe their stated product version or historical interface; do not apply them to another version without checking.
> Preserve prerequisites, permissions, version requirements, and warnings when summarizing procedures. Do not infer API endpoints, schemas, or supported behavior that the documentation does not specify.

# Build a Custom EVE-OS Image

> How to build or edit an EVE-OS installer or live image pre-configured with a custom cluster endpoint, static IP, VLAN, or WiFi network settings.

## Introduction

Build a custom EVE-OS (Edge Virtualization Engine) image when you need to pre-configure network settings before installation. Common reasons include:

* Your enterprise is hosted on a cluster other than the default `zedcloud.zededa.net`.
* The device network requires static IP, VLAN, or WiFi credentials that must be embedded at install time.

There are two methods:

* **Method A (Docker build, recommended)**: Use the EVE-OS Docker image to produce a new installer or live image with your settings injected. This works on macOS, Linux, and Windows (via WSL).
* **Method B (Prebuilt image edit)**: Download a prebuilt EVE-OS image and edit its config partition directly. Use this when Docker is not available. Supported on macOS and Linux.

The file paths used in the examples below are illustrative. Adjust them to match your own file structure.

## The EVE-OS Config Partition

EVE-OS reads its initial configuration from a config partition embedded in the image. Understanding the partition helps you know which files to include in your overrides folder (Method A) or edit directly (Method B).

| File | Purpose |
| - | - |
| `server` | The Edge Infrastructure Services hostname EVE-OS connects to on first boot. |
| `DevicePortConfig/override.json` | Optional. Overrides the default network configuration. Use for static IP, VLAN, or WiFi settings. |
| `grub.cfg` | Bootloader configuration. Modify only for multi-disk setups. See [Configure GRUB for Multi-Disk Setups](https://zededa.mintlify.site/new-ui/infrastructure-services/eve-os-installation/configure-grub-multidisk.md). |
| `root-certificate.pem` | TLS root certificate. Do not modify. |
| `v2tlsbaseroot-certificates.pem` | TLS root certificate (v2). Do not modify. |

## Prerequisites

* Docker is installed and running on your local machine (required for Method A).
* You know your cluster hostname, for example `zedcloud.gmwtus.zededa.net`.
* You have the Docker Hub EVE-OS image tag for your target version. Tags follow the format `<version>-<hypervisor>-<arch>`, for example `16.0.1-lts-kvm-amd64`. Do not use the `latest` tag. For the full naming convention, see [EVE-OS Image Naming Convention](https://zededa.mintlify.site/new-ui/infrastructure-services/eve-os/eve-os.md#image-naming-convention).
* You have the hardware serial number for your edge device, if you plan to onboard with a hardware serial.
* For Raspberry Pi (ARM64): Raspberry Pi 4 Model B with at least 4 GB RAM and a 16 GB or larger microSD card.

## Method A: Build with Docker

This is the recommended method. Docker merges only the files you include in your overrides folder into the config partition. Files you do not include remain at their EVE-OS defaults.

### Create an overrides folder

Create a folder to hold your custom configuration files. The Docker build command mounts this folder at `/in` inside the container.

```text theme={"dark"}
mkdir -p $HOME/eve-overrides/DevicePortConfig
```

Your folder structure will look like this:

```text theme={"dark"}
$HOME/eve-overrides/
├── server
└── DevicePortConfig/
    └── override.json      ← include only if you need advanced networking
```

### Set the Edge Infrastructure Services endpoint

Write your cluster hostname to a file named `server`.

```text theme={"dark"}
echo zedcloud.gmwtus.zededa.net > $HOME/eve-overrides/server
```

On Windows, do not use PowerShell's `>` redirect. It corrupts binary-adjacent files. Use WSL instead, or write the file with:

```text theme={"dark"}
Set-Content -Path "$HOME\eve-overrides\server" -Value "zedcloud.gmwtus.zededa.net" -NoNewline -Encoding ASCII
```

### Build the image

Choose the image type based on your use case:

| Image type | Command argument | Output file | When to use |
| - | - | - | - |
| Installer (raw) | `installer_raw` | `installer.raw` | Most devices. Installs EVE-OS onto internal storage. |
| Installer (ISO) | `installer_iso` | `installer.iso` | Virtual machines and devices that require an ISO. |
| Live | `live` | `live.img` | Boot from removable storage without installing to internal storage. |

Run the build command, replacing `<tag>` with your EVE-OS image tag.

For AMD64 devices (installer):

```text theme={"dark"}
docker run -v $HOME/eve-overrides:/in --rm lfedge/eve:<tag> installer_raw > installer.raw
```

For ARM64 devices such as Raspberry Pi (live):

```text theme={"dark"}
docker run -v $HOME/eve-overrides:/in --rm lfedge/eve:<tag> live > live.img
```

On Windows, PowerShell's `>` redirect corrupts the binary output. Run the build inside WSL, or use an output volume mount so the container writes the file to your machine:

```text theme={"dark"}
docker run -v $HOME/eve-overrides:/in -v $HOME/eve-iso:/out --rm lfedge/eve:<tag> installer_raw
```

### Capture the soft serial (live images only)

For live images, EVE-OS generates a UUID for the device at build time and prints it at the end of the output. This UUID is the node's soft serial number. Copy and save it. You need to enter it when onboarding the node to Edge Infrastructure Services.

Example:

```text theme={"dark"}
681cc64f-6633-49f3-988c-b0afde4a25fc
```

Installer images do not print a soft serial at build time. The installer reads the serial from the device hardware during installation.

## Method B: Download and Edit a Prebuilt Image

Use this method when Docker is not available. You download a prebuilt EVE-OS image, mount its config partition, edit the relevant files, and unmount.

### Download the image

Download the `.raw` image for your target architecture and version from the [EVE-OS Releases page on GitHub](https://github.com/lf-edge/eve/releases).

### Mount and edit (macOS)

1. Attach the image.

```text theme={"dark"}
hdiutil attach -imagekey diskimage-class=CRawDiskImage <version>-kvm-amd64.raw
```

Two volumes mount:

* `/Volumes/EVE`: the config partition. Edit files here.
* `/Volumes/INVENTORY`: system partition. Do not modify.

2. Edit the files in `/Volumes/EVE`:

   * `server`: replace the existing hostname with your cluster hostname.
   * `DevicePortConfig/override.json`: add network configuration if needed. See [Advanced: Static IP, VLAN, and WiFi](#advanced-static-ip-vlan-and-wifi).
   * `grub.cfg`: modify only for multi-disk setups. See [Configure GRUB for Multi-Disk Setups](https://zededa.mintlify.site/new-ui/infrastructure-services/eve-os-installation/configure-grub-multidisk.md).
   * Do not modify `root-certificate.pem` or `v2tlsbaseroot-certificates.pem`.

3. Unmount the image. Replace `diskX` with the disk identifier shown in the `hdiutil attach` output.

```text theme={"dark"}
hdiutil detach /dev/diskX
```

### Mount and edit (Linux)

1. Identify the start sector of the config partition.

```text theme={"dark"}
fdisk -l <version>-kvm-amd64.raw
```

2. Mount the partition. Replace `<offset>` with the start sector multiplied by the sector size (typically 512 bytes).

```text theme={"dark"}
sudo mount -o loop,offset=<offset> <version>-kvm-amd64.raw /mnt
```

3. Edit the config files under `/mnt`. See step 2 in the macOS section above for the list of files to modify.

4. Unmount.

```text theme={"dark"}
sudo umount /mnt
```

## Advanced: Static IP, VLAN, and WiFi

To configure static IP, VLAN tagging, or WiFi at install time, create a `DevicePortConfig/override.json` file. For Method A, place it at `$HOME/eve-overrides/DevicePortConfig/override.json`. For Method B, place it on the config partition at `DevicePortConfig/override.json`.

The following example configures `eth0` on VLAN 100 with DHCP, and `wlan0` with a static IP address and WPA-PSK WiFi:

```json theme={"dark"}
{
  "Version": 1,
  "Ports": [
    {
      "IfName": "eth0",
      "Name": "eth0",
      "IsMgmt": true,
      "IsL3Port": true,
      "Cost": 0,
      "Type": 4,
      "Dhcp": 4,
      "L2Type": 1,
      "Vlan": {
        "ParentPort": "eth0",
        "ID": 100
      }
    },
    {
      "IfName": "wlan0",
      "Name": "wlan0",
      "IsMgmt": true,
      "IsL3Port": true,
      "Cost": 0,
      "Type": 4,
      "Dhcp": 1,
      "L2Type": 0,
      "WType": 2,
      "Proxies": null,
      "AddrInfoList": [
        {
          "Addr": "192.168.1.100/24"
        }
      ],
      "Gateway": "192.168.1.1",
      "DomainName": "example.local",
      "NtpServer": "",
      "DnsServers": ["8.8.8.8", "8.8.4.4"],
      "WirelessCfg": {
        "WType": 2,
        "Ssid": "YourSSID",
        "KeyScheme": 1,
        "Password": "<pre-hashed PSK>"
      }
    }
  ]
}
```

### Field reference

The field values below correspond to constants defined in [zedroutertypes.go](https://github.com/lf-edge/eve/blob/master/pkg/pillar/types/zedroutertypes.go) in the LF Edge EVE repository.

| Field | Values |
| - | - |
| `Type` | `4` = IPv4 |
| `Dhcp` | `1` = Static, `4` = DHCP |
| `L2Type` | `0` = None, `1` = VLAN |
| `WType` | `0` = None, `2` = WiFi |
| `KeyScheme` | `1` = WPA-PSK |

### WiFi password format

The `Password` field in `WirelessCfg` must be a pre-hashed PSK, not a plain-text passphrase. Use `wpa_passphrase` to generate the hash:

```text theme={"dark"}
wpa_passphrase YourSSID YourWiFiPassword
```

Copy the `psk=` value from the output. Do not use the `#psk=` line, which contains the plain-text passphrase.

## Next Steps

> [card] [Flash an EVE-OS Installer or Live Image](https://zededa.mintlify.site/new-ui/infrastructure-services/eve-os-installation/flash-eve-os-image.md)
>
> Write the image to a USB drive or SD card.

> [card] [Install EVE-OS](https://zededa.mintlify.site/new-ui/infrastructure-services/eve-os-installation/install-eve-os.md)
>
> Complete the installation procedure.

> [card] [Onboard Nodes](https://zededa.mintlify.site/new-ui/infrastructure-services/nodes/onboard-nodes.md)
>
> Enroll the node in Edge Infrastructure Services.

> [card] [Onboard Nodes](https://zededa.mintlify.site/new-ui/infrastructure-services/nodes/onboard-nodes.md#use-single-use-installer)
>
> Generate a node-specific installer for air-gapped or non-DHCP environments.

## Reference Links

* [EVE-OS NETWORKING.md](https://github.com/lf-edge/eve/blob/master/docs/NETWORKING.md): EVE-OS network configuration documentation.
* [zedroutertypes.go](https://github.com/lf-edge/eve/blob/master/pkg/pillar/types/zedroutertypes.go): authoritative field reference for `DevicePortConfig`.
* [EVE-OS example DevicePortConfig](https://github.com/lf-edge/eve/blob/master/conf/DevicePortConfig/override.json.template): example `override.json` in the LF Edge repository.
