Dev : Using Qubes Builder v2

First guide : how to build your first package with Qubes Builder v2

This guide will help you to build your first packages with Qubes Builder v2.

Context

Three years ago I used Qubes Builder v1 regularly for building ArchLinux/Fedora/Debian packages.
Then Qubes Builder v2 replaced it, and I tried using it four or five times by following the qubes-builderv2 README. And each time it failed with errors I couldn’t solve without a very large investment.
Last week, the need to use the Qubes Builder v2 becomes more important for me while trying to solve a Gentoo template issue. Then I found the Qubes Builder v2 dev guide (qubes-builder-v2) which is much simpler for a first usage. By following this guide I found some minor inaccuracies, so I write two simple scripts to automate the building of the required qubes. My main goal was to re-create easily this environment.

What we will do?

We will :

  1. create a template (tpl-f42-builder) with the required dependencies.
  2. create an app qube (qbuilder) used to build the packages from the source (git clone)
  3. build two first core-admin-client packages for dom0

Create the tpl-f42-builder template

Rewrite or copy the create_builder_template.sh script to dom0:

#! /bin/bash
# create $VM as the qubes-builder template
# qubes-builderv2, based on Augsch123's salt recipe (8774 issue)
set -o errexit
set -o nounset

TPL=fedora-42-xfce
VM=tpl-f42-builder-$(date +"%N")

qvm-clone $TPL $VM
# dependencies-fedora.txt
qvm-run --pass-io --no-gui $VM 'sudo dnf -y install asciidoc createrepo_c devscripts docker gpg m4 mock openssl pacman podman python3-click python3-docker python3-jinja2-cli python3-lxml python3-packaging python3-pathspec python3-podman python3-pyyaml rb_libtorrent-examples reprepro rpm rpm-sign rsync sequoia-chameleon-gnupg sequoia-sq sequoia-sqv tree'
# dependencies-fedora-qubes-executor.txt
qvm-run --pass-io --no-gui $VM 'sudo dnf -y install createrepo_c debootstrap devscripts dnf-plugins-core dpkg-dev git mock pbuilder perl-Digest-MD5 perl-Digest-SHA pykickstart python3-debian python3-pyyaml python3-sh reprepro rpm-build rpmdevtools systemd-udev wget which'

# Init docker env
qvm-run --pass-io --no-gui $VM 'sudo usermod -aG docker user'
qvm-shutdown --wait $VM
qvm-run --pass-io --no-gui $VM 'docker ps'

echo $VM created
qvm-shutdown $VM
echo $VM stopped

Steps:

  • replace the TPL variable value with your reference fedora template
  • execute the script
  • rename the tpl-f42-builder-xxxxxx template to tpl-f42-builder

Create the qbuilder app qube

Rewrite or copy the create_builder_qube.sh script to dom0:

#! /bin/bash
# create $VM as a builderv2 qube
# qbuilder v2, based on www.qubes-os.org/doc/qubes-builder-v2/
set -o errexit
set -o nounset

VM=qbuilder-$(date +"%N")
TPL=tpl-f42-builder

qvm-create $VM --class=AppVM --label=red --template=$TPL --prop=memory=600 --prop=maxmem=6000 
qvm-volume resize $VM:private 60GB
# persistent docker directory
qvm-run --pass-io --no-gui $VM 'sudo mkdir /rw/config/qubes-bind-dirs.d; echo "binds=( '/var/lib/docker' )" | sudo tee /rw/config/qubes-bind-dirs.d/docker.conf'
qvm-shutdown --wait $VM
sleep 2
qvm-start $VM
# qubes-builderv2 repo
qvm-run --pass-io --no-gui $VM 'cd /home/user ; git clone https://github.com/QubesOS/qubes-builderv2'
qvm-run --pass-io --no-gui $VM 'cd /home/user/qubes-builderv2 ; git submodule update --init'
# verify docker with an example
qvm-run --pass-io --no-gui $VM 'docker run hello-world'
qvm-shutdown --wait $VM
sleep 2
qvm-start $VM
# validate /var/lib/docker persistence
qvm-run --pass-io --no-gui $VM 'docker images'

echo $VM created

Steps:

  • execute the script
  • rename the qbuilder-xxxxxxx app qube to qbuilder

Build a package

For the next, follow the qubes-builder-v2 guide:

  • Open a terminal in qbuilder, then
cd qubes-builderv2/
tools/generate-container-image.sh docker
  • tools/generate-container-image.sh docker will create a qubes-builder-fedora docker image. This is your Qubes builder executor (fetch, build the packages). The docker images command should list it.
  • Create the builder.yml configuration file, from the Configuration section of qubes-builder-v2. This YAML file configures the above qubes-builder-fedora docker as an executor
  • Build your first packages
./qb -c core-admin-client -d host-fc37 package fetch prep build

Your built packages for dom0 (host-fc37) are :

[user@qbuilder qubes-builderv2]$ ls -lh artifacts/components/core-admin-client/4.2.17-1.1/host-fc37/build/rpm/*.noarch.rpm 
-rw-rw-r--. 2 user user 631K Jul 22 22:38 artifacts/components/core-admin-client/4.2.17-1.1/host-fc37/build/rpm/python3-qubesadmin-4.2.17-1.1.fc37.noarch.rpm
-rw-rw-r--. 2 user user  72K Jul 22 22:38 artifacts/components/core-admin-client/4.2.17-1.1/host-fc37/build/rpm/qubes-core-admin-client-4.2.17-1.1.fc37.noarch.rpm

What’s next ?

Now you will be able to build the Qubes OS packages/templates/iso, so you can more easily test contributor PRs, fix Qubes OS issues or test your new features, then do Pull Requests to the official git repositories.

Resources :

  • Read the 8774 issue with the Augsch123’s Salt formulas
  • Read the qubes-builderv2 README
  • Read the recipe examples in the QubesOS git repositories (.qubesbuilder, CI .gitlab-ci.yml)
  • Read the qb documentation
  • Try the other executors (disposable, podman, local, windows, …)
8 Likes

Second guide : build and install your first template

In this guide, you will learn how to build the debian-12-minimal template with Qubes Builder 2.

You will use the qbuilder app vm as a docker executor to build the packages for the vm-bookworm distribution, then build the rpm debian-12-minimal template.

Configuration

In the qbuilder app qube, go to the ~/qubes-builderv2 directory, then update your Qubes Builder v2 configuraton file (builder.yml). I didn’t change the builder.yml, I changed directly the example-configs/qubes-os-r4.2.yml file to use the docker executor and added the debian-12-minimal template :

diff --git a/example-configs/qubes-os-r4.2.yml b/example-configs/qubes-os-r4.2.yml
index f2e391e..96135f8 100644
--- a/example-configs/qubes-os-r4.2.yml
+++ b/example-configs/qubes-os-r4.2.yml
@@ -29,6 +29,11 @@ templates:
       flavor: xfce
       options:
         - firmware
+  - debian-12-minimal:
+      dist: bookworm
+      flavor: minimal
+      options:
+        - firmware
   - whonix-gateway-17:
       dist: bookworm
       flavor: whonix-gateway
@@ -187,15 +192,15 @@ components:
   - openssh
 
 
-#executor:
-#  type: docker
-#  options:
-#    image: "qubes-builder-fedora:latest"
-
 executor:
-  type: qubes
+  type: docker
   options:
-    dispvm: "@dispvm"
+    image: "qubes-builder-fedora:latest"
+
+#executor:
+#  type: qubes
+#  options:
+#    dispvm: "@dispvm"
 
 stages:
   - fetch

And I used this file with the qb’s --builder-conf option.

You can also get inspiration from the official builder.yaml, see the below first resources.

Build

  1. Get (fetch) the git repositories for the packages of the builder-debian component (i.e. all the debian components) with ./qb package fetch :
./qb --debug --verbose --builder-conf example-configs/qubes-os-r4.2.yml --log-file pfetch.log -c builder-debian package fetch
ls -l artifacts/sources/
  1. Build all the packages for the vm-bookworm distribution (bookworm is the debian-12 release name) with ./qb package all :
./qb --debug --verbose --builder-conf example-configs/qubes-os-r4.2.yml --log-file pall.log -d vm-bookworm package all
find artifacts/components/ -name "*.deb"

The built packages are in the artifacts/components/<component>/<package version>/vm-bookworm/ directories.

  1. Build the debian-12-minimal template
    The template delivery container is a rpm.
./qb --debug --verbose --builder-conf example-configs/qubes-os-r4.2.yml --log-file tpl.log -t debian-12-minimal template all

Note: this process use some disk storage, I updated my qbuilder app qube private disk storage to 60GB (I updated the first guide).

Inspect the template rpm file

Result file:

[user@qbuilder qubes-builderv2]$ ls -alh artifacts/templates/rpm/qubes-template-debian-12-minimal-4.2.0-202508062221.noarch.rpm 
-rw-r--r--. 1 user user 755M Aug  6 22:51 artifacts/templates/rpm/qubes-template-debian-12-minimal-4.2.0-202508062221.noarch.rpm

The rpm metadata:

Summary
[user@qbuilder qubes-builderv2]$ rpm -qi artifacts/templates/rpm/qubes-template-debian-12-minimal-4.2.0-202508062221.noarch.rpm 
Name        : qubes-template-debian-12-minimal
Version     : 4.2.0
Release     : 202508062221
Architecture: noarch
Install Date: (not installed)
Group       : Unspecified
Size        : 3157176383
License     : GPLv3+
Signature   : (none)
Source RPM  : qubes-template-debian-12-minimal-4.2.0-202508062221.src.rpm
Build Date  : Wed Aug  6 22:31:31 2025
Build Host  : a9e72c0ced94
URL         : http://www.qubes-os.org
Summary     : Qubes OS template for debian-12-minimal
Description :
Qubes OS template for debian-12-minimal.

The rpm content :

Summary
[user@qbuilder qubes-builderv2]$ rpm -ql artifacts/templates/rpm/qubes-template-debian-12-minimal-4.2.0-202508062221.noarch.rpm 
/var/lib/qubes/vm-templates/debian-12-minimal
/var/lib/qubes/vm-templates/debian-12-minimal/apps
/var/lib/qubes/vm-templates/debian-12-minimal/apps.tempicons
/var/lib/qubes/vm-templates/debian-12-minimal/apps.templates
/var/lib/qubes/vm-templates/debian-12-minimal/clean-volatile.img.tar
/var/lib/qubes/vm-templates/debian-12-minimal/netvm-whitelisted-appmenus.list
/var/lib/qubes/vm-templates/debian-12-minimal/private.img
/var/lib/qubes/vm-templates/debian-12-minimal/root.img
/var/lib/qubes/vm-templates/debian-12-minimal/root.img.part.00
/var/lib/qubes/vm-templates/debian-12-minimal/root.img.part.01
/var/lib/qubes/vm-templates/debian-12-minimal/root.img.part.02
/var/lib/qubes/vm-templates/debian-12-minimal/template.conf
/var/lib/qubes/vm-templates/debian-12-minimal/vm-whitelisted-appmenus.list
/var/lib/qubes/vm-templates/debian-12-minimal/volatile.img
/var/lib/qubes/vm-templates/debian-12-minimal/whitelisted-appmenus.list

Install

Copy the template rpm to dom0, then install it with qvm-template:

[user@dom0 Templates]$ qvm-template install --nogpgcheck ./qubes-template-debian-12-minimal-4.2.0-202508062221.noarch.rpm 
Installing template 'debian-12-minimal'...
debian-12-minimal: Importing data

And test it :

[user@dom0 Templates]$ qvm-ls | grep debian-12-minimal
debian-12-minimal          Halted   TemplateVM    black   -                       -
test-d12-min-diy           Running  AppVM         red     debian-12-minimal       sys-firewall

What’s next ?

Now that you know how to build a template, you can

  • read the official builder.yml files to understand them
  • understand the official Qubes Builder v2 documentation
  • customize the template, or test with a specific package or package list
  • experiment to build and test a debian-13 (vm-trixie distribution).
  • build a dom0 (host-fc37 distribution)
  • build a r4.2 install iso

Resources:

3 Likes