Custom Images
This page from the Ubuntu Core docs walks through all of the steps necessary to build an image. This guide page will cover the process of creating an image that has the BME280 dashboard preloaded into it.
Images can be created using Ubuntu Server or Desktop 22.04+ OS. The Raspberry Pi that was set up with Ubuntu Server on the Building Snaps page is suitable if it has a large enough SD card. The docs list 10gb requirement for the build machine. The output image file alone is about 3.8gb.
Images are built from models. A model is a JSON file that acts as a recipe for an image. It defines the Snaps built-in to the image, and metadata including a developer ID from a Ubuntu One account.
Retrieve Developer ID
You can find your developer ID using the snapcraft CLI. It's the same CLI used to build Snaps, so if you followed along with that page, you should have it already. If you don't then install it with this command.
sudo snap install snapcraft --classic
Next, use these commands to login and export your credentials to an environment variable that the snapcraft CLI will use.
snapcraft export-login credentials.txt export SNAPCRAFT_STORE_CREDENTIALS=$(cat credentials.txt)
You should see output like this.
Now use snapcraft whoami to find your developer ID.
snapcraft whoami
Look for the row that starts with id:, the value to the right is your developer ID. Copy it and save it somewhere to reference later. The model JSON file will need to have your ID put into it.
Model JSON
This is the model JSON file for an image with ubuntu-frame and wpe-webkit-mir-kiosk built in. To build an image from the model, fill in your developer ID for the authority-id and brand-id values.
{
"type": "model",
"series": "16",
"model": "ubuntu-core-24-pi-arm64",
"architecture": "arm64",
"authority-id": "[developer_id_here]",
"brand-id": "[developer_id_here]",
"timestamp": "[timestamp_here]",
"base": "core24",
"grade": "dangerous",
"snaps": [
{
"name": "pi",
"type": "gadget",
"default-channel": "24/stable",
"id": "YbGa9O3dAXl88YLI6Y1bGG74pwBxZyKg"
},
{
"name": "pi-kernel",
"type": "kernel",
"default-channel": "24/stable",
"id": "jeIuP6tfFrvAdic8DMWqHmoaoukAPNbJ"
},
{
"name": "core24",
"type": "base",
"default-channel": "latest/stable",
"id": "dwTAh7MZZ01zyriOZErqd1JynQLiOGvM"
},
{
"name": "snapd",
"type": "snapd",
"default-channel": "latest/stable",
"id": "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4"
},
{
"name": "console-conf",
"type": "app",
"default-channel": "24/stable",
"id": "ASctKBEHzVt3f1pbZLoekCvcigRjtuqw"
},
{
"name": "mesa-2404",
"type": "app",
"default-channel": "latest/stable",
"id": "HyhSEBPv3vHsW6uOHkQR384NgI7S6zpj"
},
{
"name": "mesa-core22",
"type": "app",
"default-channel": "latest/stable",
"id": "UijXdFgvIKp9ZZ6P4ijPAJHWZLtSKgWm"
},
{
"name": "ubuntu-frame",
"type": "app",
"default-channel": "24/stable",
"id": "BPZbvWzvoMTrpec4goCXlckLe2IhfthK"
},
{
"name": "core22",
"type": "base",
"default-channel": "latest/stable",
"id": "amcUKQILKXHHTlmSa7NMdnXSx02dNeeT"
},
{
"name": "wpe-webkit-mir-kiosk",
"type": "app",
"default-channel": "22/stable",
"id": "01sV9tv4UTUQTU3jYsAF1gJ5qv7ZqGls"
}
]
}
Create & Register Key
Before the image can be made, the model must be signed to turn it into a model assertion. To sign the model, you need to create and register a key in the Ubuntu snapcraft system. This page documents the key set up and signing process.
If you've done any Ubuntu or Snap development before, you can check whether you have a key already with this command.
snapcraft list-keys
If you see "No keys have been registered..." then use the following commands to create and register a key. You can use any name that you like for the key.
# command snapcraft create-key [key-name] # example snapcraft create-key bme280-dashboard-key
You will be prompted for a passphrase to use on the key. This is an extra password that will be required in order to use the key. It can be left blank, but it's best to use a secure passphrase and keep it secret. It serves as a second factor in addition to possession of the key file. Enter the desired passphrase and repeat it again for the confirmation prompt.
# command snapcraft register-key [key-name] # example snapcraft register-key bme280-dashboard-key
You will be prompted for the passphrase in order to register the key, and again when you use it to sign a model.
Update Model Timestamp
Inside of the model JSON, the timestamp field needs to contain a timestamp that is newer than the signing key. So if you just created and registered a key using the steps above, then you must set the timestamp to a more recent value after the key was registered.
You can get a timestamp with suitable syntax using this command.
date -Iseconds --utc
Then update the value in the model JSON file with it.
"timestamp": "[timestamp_here]", # example "timestamp": "2026-06-03T20:27:10+00:00",
# command snap sign -k [key-name] [model-file.json] > [output_model-file.model] # example snap sign -k bme280-dashboard-key bme280_dashboard_core24_model.json > bme280_dashboard_core24_model.model
You will be prompted for the passphrase when you use a key to sign a model.
It will create a new file for the model assertion with the specified output name, bme280_dashboard_core24_model.model in the example above.
Build Image
Building the image is done with the ubuntu-image utility. Install it with this command.
sudo snap install ubuntu-image --classic --edge
Build the image from a model assertion with the following command. The --snap argument is optional. It allows you to specify a custom Snap file, such as one built on the previous page, to be included in the image. For final deployment, snaps would be distributed via the Snap Store instead.
# command ubuntu-image snap --allow-snapd-kernel-mismatch [model-assertion-file.model] --snap [custom.snap] #example ubuntu-image snap --allow-snapd-kernel-mismatch bme280_dashboard_core24_model.model --snap bme280-dashboard_0.1_arm64.snap
If successful, the output will look like this. It will also create a pi.img file as shown by the ls command after the output in the screenshot below.
Copy the resulting pi.img file to a computer with Raspberry Pi imager on it.
Flash this img file to an sdcard with Pi imager app.
Click Use custom on the OS menu and then select the pi.img file.
After flashing the image, follow the same steps from the First Boot Up section on the Install guide page. Once the first boot configuration is complete, you should be able to connect to the device with your SSH key.
Launch Dashboard
The Snaps required by the sensor dashboard demo are preloaded into this image, but the plugs still need to be manually connected to the slots in order for the sensor to function. The kiosk apps need to be set to auto-launch and have the URL configured for the dashboard also. Use the following commands to complete these steps.
# connect plugs for Blinka sudo snap connect bme280-dashboard:i2c pi:i2c-1 sudo snap connect bme280-dashboard:hardware-observe # Enable autolaunch and configure kiosk URL snap set ubuntu-frame daemon=true snap set wpe-webkit-mir-kiosk url=http://localhost:8080/
The sensor dashboard should load onto the screen after a moment.
Page last edited June 08, 2026
Text editor powered by tinymce.