BYOI (Bring Your Own Image)
Create custom VM images with your tools pre-installed for faster CI builds on Harness Cloud.
Prerequisites
- Harness CI Enterprise license
CI_ENABLE_BYOI_HOSTEDfeature flag enabled (contact Harness support)- Harness Cloud infrastructure (not self-hosted runners)
Quick Start
1. Create a Packer File
Add a .pkr.hcl file to your repository with your customizations:
# packer/my-image.pkr.hcl
# Optional: Define variables for reusability
variable "node_version" {
type = string
default = "20"
}
# Install your tools
provisioner "shell" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y nodejs npm python3",
"sudo npm install -g typescript yarn"
]
}
# Copy config files (optional)
provisioner "file" {
source = "configs/settings.json"
destination = "/tmp/settings.json"
}
provisioner "shell" {
inline = ["sudo mv /tmp/settings.json /etc/myapp/"]
}
2. Build the Image
Add this step to your pipeline:
- step:
type: Plugin
name: Build Image
spec:
connectorRef: account.dockerhub
image: harness/byoi-builder:1.0.0
settings:
mode: build
packerFilePath: packer/my-image.pkr.hcl
targetOs: linux
targetArch: amd64
imageName: my-dev-image
imageVersion: v1
baseImage: ubuntu/22.04
3. Use the Image
Reference it in your stage configuration:
- stage:
type: CI
spec:
platform:
os: Linux
arch: Amd64
runtime:
type: Cloud
spec:
imageSpec:
imageName: my-dev-image:v1
execution:
steps:
- step:
type: Run
spec:
command: node --version # Pre-installed!
Reference the image by imageName:imageVersion only. Linux and Windows BYOI do not support supplying a custom image connector (for example, the Override Image Connector stage infrastructure setting) to pull the VM image from your own registry. The image must be built with the Harness BYOI builder plugin and served from Harness-managed storage to be used with Linux or Windows BYOI.
Plugin Settings
Build Mode
| Setting | Required | Default | Description |
|---|---|---|---|
mode | No | build | Operation mode: build or delete |
packerFilePath | Yes | - | Path to your Packer file (relative to repo root) |
imageName | Yes | - | Image name (3-30 chars, lowercase letters, numbers, hyphens) |
imageVersion | Yes | - | Version tag (1-20 chars, alphanumeric and hyphens) |
targetOs | No | linux | Target operating system: linux or windows |
targetArch | No | amd64 | Target architecture: amd64 or arm64. Windows supports amd64 only. |
baseImage | No | ubuntu/22.04 | Base image to build from (see Supported Base Images) |
dockerVersion | No | 28 | Docker version to pre-install (e.g., 28, 27) |
debug | No | false | Enable verbose Packer logging |
Delete Mode
To rebuild with the same version, delete the existing image first:
- step:
type: Plugin
name: Delete Image
spec:
connectorRef: account.dockerhub
image: harness/byoi-builder:1.0.1
settings:
mode: delete
imageName: my-dev-image
imageVersion: v1
Supported Base Images
Linux
| Base Image | Architectures |
|---|---|
ubuntu/24.04 | amd64, arm64 |
ubuntu/22.04 | amd64, arm64 |
Windows
| Base Image | Architectures |
|---|---|
windows-server/2022 | amd64 |
The BYOI builder plugin also accepts windows-server/2019 and windows-server/2025, but these versions are not yet qualified to run as CI VMs on Harness Cloud. Use windows-server/2022 for Windows BYOI images intended to run on Harness Cloud.
Advanced options:
| Type | Format | Example |
|---|---|---|
| Harness pre-configured | {name} | ubuntu-v1-hosted-amd64 |
| Your previous BYOI image | byoi-{sanitizedAccountId}-{imageName}-{version} | byoi-abc123-my-base-v1 |
To use a previous BYOI image, specify the full image name (as shown in build output), not imageName:version.
Note: Account IDs are sanitized in image names: lowercase, _ becomes -, and special characters are removed. For example, if your account ID is My_Account_123, your images are stored as byoi-my-account-123-....
Writing Your Packer File
You provide variables and provisioners. Harness handles source configuration, authentication, and cleanup automatically.
Example with Variables
# Define reusable variables
variable "java_version" {
type = string
default = "17"
}
variable "maven_version" {
type = string
default = "3.9.6"
}
# Install Java
provisioner "shell" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y openjdk-${var.java_version}-jdk"
]
}
# Install Maven
provisioner "shell" {
inline = [
"wget -q https://archive.apache.org/dist/maven/maven-3/${var.maven_version}/binaries/apache-maven-${var.maven_version}-bin.tar.gz",
"sudo tar -xzf apache-maven-${var.maven_version}-bin.tar.gz -C /opt",
"sudo ln -s /opt/apache-maven-${var.maven_version} /opt/maven",
"rm apache-maven-${var.maven_version}-bin.tar.gz"
]
}
Copying Files
# Copy files from your repo into the image
provisioner "file" {
source = "configs/app.conf"
destination = "/tmp/app.conf"
}
provisioner "shell" {
inline = ["sudo mv /tmp/app.conf /etc/myapp/app.conf"]
}
What Harness Adds Automatically
Linux:
- Git, Git LFS, wget, curl, CA certificates
- Docker (configurable version)
git safe.directory *configuration- HOME environment variable
- Cleanup (apt cache, logs) to reduce image size
What Gets Ignored
If your Packer file contains source or build blocks, they will be ignored. Harness uses its own secure configuration. Only your variable and provisioner blocks are used.
Limitations
Image Naming
imageName: 3-30 characters, must start with lowercase letterimageVersion: 1-20 characters, must start/end with alphanumeric- Combined length of
imageName+imageVersionshould not exceed ~35 characters (the full name includes your account ID)
Platform
- Linux: Ubuntu (amd64 and arm64)
- Windows: Windows Server 2022 (amd64 only). The builder plugin also accepts
windows-server/2019andwindows-server/2025, but those versions are not yet qualified to run as CI VMs on Harness Cloud. - macOS: Coming soon
- Harness Cloud only. Self-hosted runners are not supported.
Image storage and registry
- Linux and Windows BYOI images must be built with the Harness BYOI builder plugin and are stored in Harness-managed storage.
- Linux and Windows BYOI do not support supplying a custom image connector. The Override Image Connector stage infrastructure setting does not apply to the Linux or Windows BYOI VM image, so you cannot point Linux or Windows BYOI at an image hosted in your own registry.
- Reference Linux and Windows BYOI images by
imageName:imageVersiononly. To build on top of an existing image, go to Supported Base Images to use the full Harness-managed image name asbaseImage. - This restriction applies only to the BYOI VM image. Step-level
image:fields inside your pipeline (for example, on a Run step) continue to honor their ownconnectorRefand can pull from any registry as usual.
Build Process
- Maximum build time: 3 hours (bounded by authentication token lifetime)
- Automatic retries: 3 attempts on transient failures
- Disk size: 100GB
- Cannot build same image name/version concurrently
Security
Do not include credentials in your Packer file. The following patterns will cause the build to fail:
credentials = "..."account_file = "..."access_token = "..."
Harness injects credentials securely.
Troubleshooting
| Issue | Solution |
|---|---|
| Build fails | Set debug: "true" to see detailed Packer output |
| "Image name too long" error | Shorten imageName or imageVersion |
| "Image already exists" error | Use mode: delete first, or use a different version |
| Packer file not found | Check packerFilePath is relative to repo root |
| Authentication error | Contact Harness support |
| Build times out | The maximum build time is 3 hours. |
FAQ
Can I use my image across all projects? Yes, BYOI images are available to all projects in your account.
Can I build on ARM64?
Yes, set targetArch: arm64 in your plugin settings (Linux only).
Can I build on top of a previous BYOI image?
Yes. Use the full image name from your previous build output as baseImage. For example: baseImage: byoi-abc123-my-base-v1 (not my-base:v1). Note that the account ID in the image name is sanitized (lowercase, _ → -, special chars removed). You can only use your own account's BYOI images.
Can I host my Linux or Windows BYOI image in my own registry and pull it with an image connector?
No. Linux and Windows BYOI do not support supplying a custom image connector, and the Override Image Connector stage infrastructure setting does not apply to the Linux or Windows BYOI VM image. The image must be built with the Harness BYOI builder plugin and served from Harness-managed storage. Reference it by imageName:imageVersion.
Do I need to set mode to build?
No, build is the default mode. You only need to explicitly set mode: delete when deleting an image.
What is the maximum build time? 3 hours, bounded by the GCP authentication token lifetime. If your build needs more time, optimize your Packer provisioners.
Support
If you encounter issues:
- Enable
debug: "true"for verbose logs - Check the error message against the troubleshooting table above
- Contact Harness support