|
| 1 | +--- |
| 2 | +title: genesis build |
| 3 | +--- |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +`genesis build` **compiles and packages** your Genesis element into distributable artifacts — images, manifests, and any other resources required for deployment. |
| 8 | + |
| 9 | +The command reads the **`genesis/genesis.yaml`** file — the main configuration file that transforms your application into a platform element. This file contains the `build` section describing: |
| 10 | + |
| 11 | +- **Dependencies** — files, directories or external binary artifacts required for the build |
| 12 | +- **Elements** — a single project can produce multiple elements on output (e.g., separate API and worker services) |
| 13 | +- **Artifacts** — images, binaries, or other build outputs |
| 14 | + |
| 15 | +Running the command performs the following steps: |
| 16 | + |
| 17 | +1. **Resolve dependencies** — fetches dependencies specified in `genesis.yaml`. |
| 18 | +2. **Process manifests** — renders manifest files (supporting raw YAML or Jinja2 templates with built-in variables). |
| 19 | +3. **Build artifacts** — creates images and other build outputs based on the `build` section in `genesis.yaml`. |
| 20 | + |
| 21 | +```bash |
| 22 | +genesis build [OPTIONS] PROJECT_DIR |
| 23 | +``` |
| 24 | + |
| 25 | +Key options: |
| 26 | + |
| 27 | +| Option | Description | |
| 28 | +|---|---| |
| 29 | +| `-c, --genesis-cfg-file TEXT` | Name of the project configuration file (default: `genesis.yaml`) | |
| 30 | +| `--build-dir TEXT` | Directory for temporary build artifacts | |
| 31 | +| `--output-dir TEXT` | Directory where final artifacts are stored | |
| 32 | +| `--deps-dir TEXT` | Directory where dependencies are fetched | |
| 33 | +| `-i, --developer-key-path TEXT` | Path to developer's public key. The key is embedded into the built images for signing and authentication | |
| 34 | +| `-f, --force` | Rebuild even if output already exists | |
| 35 | +| `--inventory` | Build using the inventory format | |
| 36 | + |
| 37 | +--- |
| 38 | + |
| 39 | +## Requirements |
| 40 | + |
| 41 | +Before building, ensure you have the following tools installed: |
| 42 | + |
| 43 | +- [packer](https://www.packer.io/) |
| 44 | +- [qemu](https://www.qemu.org/) |
| 45 | + |
| 46 | +Use the Packer [version 1.9.2](https://hashicorp-releases.yandexcloud.net/packer/1.9.2/) or earlier due to licensing limitation. |
| 47 | + |
| 48 | +### Linux (Ubuntu) |
| 49 | + |
| 50 | +Install packages |
| 51 | + |
| 52 | +```bash |
| 53 | +sudo apt update |
| 54 | +sudo apt install qemu-kvm mkisofs |
| 55 | +``` |
| 56 | + |
| 57 | +Add user to group |
| 58 | + |
| 59 | +```bash |
| 60 | +sudo adduser $USER kvm |
| 61 | +``` |
| 62 | + |
| 63 | +You may need to relogin to apply the changes. Now you are ready to build your element. |
| 64 | + |
| 65 | +## Getting Started |
| 66 | + |
| 67 | +### Basic Build |
| 68 | + |
| 69 | +From your project directory: |
| 70 | + |
| 71 | +```bash |
| 72 | +genesis build . |
| 73 | +``` |
| 74 | + |
| 75 | +### Rebuild with Force |
| 76 | + |
| 77 | +If you need to rebuild even when artifacts already exist: |
| 78 | + |
| 79 | +```bash |
| 80 | +genesis build --force . |
| 81 | +``` |
| 82 | + |
| 83 | +### Build with Custom Variables |
| 84 | + |
| 85 | +Pass additional variables to manifest templates: |
| 86 | + |
| 87 | +```bash |
| 88 | +genesis build --manifest-var commit_hash=$(git rev-parse --short HEAD) . |
| 89 | +``` |
| 90 | + |
| 91 | +### Inventory Build |
| 92 | + |
| 93 | +For advanced deployments, build using the inventory format: |
| 94 | + |
| 95 | +```bash |
| 96 | +genesis build --inventory . |
| 97 | +``` |
| 98 | + |
| 99 | +--- |
| 100 | + |
| 101 | +## Build Process |
| 102 | + |
| 103 | +The build process creates **VM disk images** that run on the Genesis Core platform. Packer starts a virtual machine from a base OS image, copies all resolved dependencies into it, and executes the provisioning script specified in `genesis.yaml`. This script is typically a Bash script that installs packages, configures services, and prepares the image. Once provisioning completes, the VM shuts down and the resulting disk image is packaged for deployment. This process is configured through the `elements` section in `genesis.yaml` where you define the base profile, provisioning script, output format, and any build overrides. |
| 104 | + |
| 105 | +--- |
| 106 | + |
| 107 | +### Dependencies Resolution |
| 108 | + |
| 109 | +Before building, `genesis build` resolves all dependencies declared in the `build.deps` section of `genesis.yaml`. Each dependency specifies a destination path (`dst`) and a source. Dependencies can be local directories, remote artifacts, or optional development resources. |
| 110 | + |
| 111 | +#### Local Project Directory |
| 112 | + |
| 113 | +Include another local project or directory into your build. The source path is relative to the `genesis.yaml` file location. |
| 114 | + |
| 115 | +```yaml |
| 116 | +deps: |
| 117 | + - dst: /opt/genesis_core |
| 118 | + path: |
| 119 | + src: ../../genesis_core |
| 120 | + exclude: |
| 121 | + - .venv |
| 122 | + - .tox |
| 123 | + - build |
| 124 | + - output |
| 125 | +``` |
| 126 | +
|
| 127 | +This copies the `genesis_core` project into `/opt/genesis_core` during the build, excluding development directories. |
| 128 | + |
| 129 | +#### External Binary Artifacts |
| 130 | + |
| 131 | +Fetch remote resources via HTTP/HTTPS. This is useful for kernel images, boot loaders, or pre-compiled binaries. |
| 132 | + |
| 133 | +```yaml |
| 134 | +deps: |
| 135 | + - dst: /opt/genesis_core/artifacts/vmlinuz |
| 136 | + http: |
| 137 | + src: https://repository.genesis-core.tech/seed_os/1.1.0/vmlinuz |
| 138 | +``` |
| 139 | + |
| 140 | +The `vmlinuz` kernel image is downloaded and placed at the specified destination path before the build continues. |
| 141 | + |
| 142 | +#### Optional Dependencies |
| 143 | + |
| 144 | +Mark dependencies as optional to allow builds to proceed even when the source is unavailable. This is useful for development-only resources. |
| 145 | + |
| 146 | +```yaml |
| 147 | +deps: |
| 148 | + - dst: /opt/gcl_sdk |
| 149 | + optional: true |
| 150 | + path: |
| 151 | + env: LOCAL_GENESIS_SDK_PATH |
| 152 | +``` |
| 153 | + |
| 154 | +Here, the SDK is only included if the `LOCAL_GENESIS_SDK_PATH` environment variable is set. If not present, the build continues without this dependency. |
| 155 | + |
| 156 | +--- |
| 157 | + |
| 158 | +### VM Image Build Configuration |
| 159 | + |
| 160 | +Each element in the `elements` list of `genesis.yaml` defines how its VM images are built. An element can produce multiple images (for example, different formats or variants). The following parameters control the image creation process: |
| 161 | + |
| 162 | +| Parameter | Description | |
| 163 | +|---|---| |
| 164 | +| `name` | The name of the output image. Used to identify the image in the build output and registry. | |
| 165 | +| `format` | Disk image format. Supported formats: `raw`, `qcow2`, `gz`. The `gz` format is a compressed `raw` image. Can also reference an environment variable like `GEN_IMG_FORMAT_CORE=qcow2`. | |
| 166 | +| `profile` | Base OS image profile to use as the starting point (e.g., `genesis_base`). This determines the initial operating system and pre-installed packages. | |
| 167 | +| `script` | Path to the provisioning script executed inside the VM. This script performs all application-specific setup: installing dependencies, copying files, configuring services. | |
| 168 | +| `override` | Build-time parameter overrides passed to the underlying tool (e.g., Packer). Common uses include increasing `disk_size`, `cpus`, or `memory` for the build VM. When using the `genesis_custom` profile, specify `base_image_url` and `base_image_checksum` here to use any custom image as the base. | |
| 169 | +| `envs` | List of environment variables to pass into the build process. These become available to the provisioning script and build tools. | |
| 170 | + |
| 171 | +#### Using Environment Variables |
| 172 | + |
| 173 | +Define variables in `genesis.yaml`: |
| 174 | + |
| 175 | +```yaml |
| 176 | +elements: |
| 177 | + - manifest: manifests/core.yaml.j2 |
| 178 | + images: |
| 179 | + - name: my-app |
| 180 | + format: qcow2 |
| 181 | + profile: genesis_base |
| 182 | + script: install.sh |
| 183 | + envs: |
| 184 | + - APP_PORT=8080 |
| 185 | + - LOG_LEVEL=info |
| 186 | + - DATABASE_URL |
| 187 | +``` |
| 188 | + |
| 189 | +Use them in your provisioning script: |
| 190 | + |
| 191 | +```bash |
| 192 | +#!/bin/bash |
| 193 | +# install.sh |
| 194 | +
|
| 195 | +echo "Starting application on port $APP_PORT" |
| 196 | +echo "Log level set to: $LOG_LEVEL" |
| 197 | +
|
| 198 | +# DATABASE_URL will be passed if set in the environment |
| 199 | +if [ -n "$DATABASE_URL" ]; then |
| 200 | + echo "Database configured: $DATABASE_URL" |
| 201 | +fi |
| 202 | +``` |
| 203 | + |
| 204 | +### Manifest Processing |
| 205 | + |
| 206 | +The manifest in your project can be either: |
| 207 | + |
| 208 | +- **Raw YAML** — used as-is during the build |
| 209 | +- **Jinja2 template** — dynamically rendered with built-in variables |
| 210 | + |
| 211 | +For Jinja2 templates, the following variables are available by default: |
| 212 | + |
| 213 | +| Variable | Description | |
| 214 | +|---|---| |
| 215 | +| `{{ version }}` | Version of the element being built | |
| 216 | +| `{{ name }}` | Name of the element | |
| 217 | +| `{{ images }}` | List of images built for this element | |
| 218 | +| `{{ manifests }}` | List of manifest files | |
| 219 | + |
| 220 | +Additional variables can be passed using `--manifest-var key=value`: |
| 221 | + |
| 222 | +```bash |
| 223 | +genesis build --manifest-var environment=production --manifest-var region=europe-east . |
| 224 | +``` |
| 225 | + |
| 226 | +[Full manifest reference →](../misc/manifests.md) |
| 227 | + |
| 228 | +--- |
| 229 | + |
| 230 | +### Output Artifacts |
| 231 | + |
| 232 | +After a successful build with `--inventory`, the following artifacts are created in the `--output-dir` (default: project `output/`): |
| 233 | + |
| 234 | +```text |
| 235 | +output/ |
| 236 | +├── inventory.json # Build manifest listing all produced artifacts |
| 237 | +├── images/ # Built VM disk images |
| 238 | +│ └── <element-name>.<format> |
| 239 | +└── manifests/ # Compiled manifests for each element |
| 240 | + └── <element-name>.yaml |
| 241 | +``` |
| 242 | + |
| 243 | +The `inventory.json` file provides a complete index of the build output, mapping each element to its artifacts: |
| 244 | + |
| 245 | +| Field | Description | |
| 246 | +|---|---| |
| 247 | +| `name` | Element name | |
| 248 | +| `version` | Full version string with timestamp and git hash | |
| 249 | +| `images` | List of built VM disk image paths | |
| 250 | +| `manifests` | List of compiled manifest paths | |
| 251 | +| `artifacts` | Additional build artifacts (if any) | |
| 252 | +| `configs` | Configuration files (if any) | |
| 253 | +| `templates` | Template files used during build (if any) | |
| 254 | + |
| 255 | +The exact contents depend on your project type and `genesis.yaml` configuration. |
| 256 | + |
| 257 | +--- |
| 258 | + |
| 259 | +## Next Steps |
| 260 | + |
| 261 | +After a successful build, your elements are ready for: |
| 262 | + |
| 263 | +- [`genesis push`](push.md) — publish to the ecosystem registry |
| 264 | +- [`genesis deploy`](deploy.md) — deploy to a Genesis installation |
| 265 | + |
| 266 | +--- |
| 267 | + |
| 268 | +## Troubleshooting |
| 269 | + |
| 270 | +If you encounter issues during the build process — such as dependency resolution failures, VM image build errors, or manifest processing problems — refer to the [Troubleshooting Guide](troubleshooting.md) for detailed solutions and common fixes. |
0 commit comments