Skip to main content
  1. All Posts/

pi-gen

Tools Shell

pi-gen

Tool used to create Raspberry Pi OS images. (Previously known as Raspbian).

Dependencies

pi-gen runs on Debian-based operating systems. Currently it is only supported on
either Debian Buster or Ubuntu Xenial and is known to have issues building on
earlier releases of these systems. On other Linux distributions it may be possible
to use the Docker build described below.
To install the required dependencies for pi-gen you should run:

apt-get install coreutils quilt parted qemu-user-static debootstrap zerofree zip 
dosfstools libarchive-tools libcap2-bin grep rsync xz-utils file git curl bc 
qemu-utils kpartx gpg pigz

The file depends contains a list of tools needed. The format of this
package is <tool>[:<debian-package>].

Getting started with building your images

Getting started is as simple as cloning this repository on your build machine. You
can do so with:

git clone https://github.com/RPI-Distro/pi-gen.git

--depth 1 can be added afer git clone to create a shallow clone, only containing
the latest revision of the repository. Do not do this on your development machine.
Also, be careful to clone the repository to a base path NOT containing spaces.
This configuration is not supported by debootstrap and will lead to pi-gen not
running.
After cloning the repository, you can move to the next step and start configuring
your build.

Config

Upon execution, build.sh will source the file config in the current
working directory. This bash shell fragment is intended to set needed
environment variables.
The following environment variables are supported:

  • IMG_NAME required (Default: unset)
    The name of the image to build with the current stage directories. Setting
    IMG_NAME=Raspbian is logical for an unmodified RPi-Distro/pi-gen build,
    but you should use something else for a customized version. Export files
    in stages may add suffixes to IMG_NAME.
  • USE_QCOW2 EXPERIMENTAL (Default: )
    Instead of using traditional way of building the rootfs of every stage in
    single subdirectories and copying over the previous one to the next one,
    qcow2 based virtual disks with backing images are used in every stage.
    This speeds up the build process and reduces overall space consumption
    significantly.
    Additional optional parameters regarding qcow2 build:

    • BASE_QCOW2_SIZE (Default: 12G)
      Size of the virtual qcow2 disk.
      Note: it will not actually use that much of space at once but defines the
      maximum size of the virtual disk. If you change the build process by adding
      a lot of bigger packages or additional build stages, it can be necessary to
      increase the value because the virtual disk can run out of space like a normal
      hard drive would.
    <p>
      <strong>CAUTION:</strong> Although the qcow2 build mechanism will run fine inside Docker, it can happen<br /> that the network block device is not disconnected correctly after the Docker process has<br /> ended abnormally. In that case see <a rel="nofollow noopener" target="_blank" href="#Disconnect-an-image-if-something-went-wrong">Disconnect an image if something went wrong</a> </li> 
      
      <li>
        <code>RELEASE</code> (Default: bullseye)<br /> The release version to build images against. Valid values are any supported<br /> Debian release. However, since different releases will have different sets of<br /> packages available, you&#8217;ll need to either modify your stages accordingly, or<br /> checkout the appropriate branch. For example, if you&#8217;d like to build a<br /> <code>buster</code> image, you should do so from the <code>buster</code> branch.
      </li>
      <li>
        <code>APT_PROXY</code> (Default: unset)<br /> If you require the use of an apt proxy, set it here. This proxy setting<br /> will not be included in the image, making it safe to use an <code>apt-cacher</code> or<br /> similar package for development.<br /> If you have Docker installed, you can set up a local apt caching proxy to<br /> like speed up subsequent builds like this:</p> <pre class="notranslate"><code>docker-compose up -d
    

    echo ‘APT_PROXY=http://172.17.0.1:3142’ >> config

  •   <li>
        <code>BASE_DIR</code> (Default: location of <code>build.sh</code>)<br /> <strong>CAUTION</strong>: Currently, changing this value will probably break build.sh<br /> Top-level directory for <code>pi-gen</code>. Contains stage directories, build<br /> scripts, and by default both work and deployment directories.
      </li>
      <li>
        <code>WORK_DIR</code> (Default: <code>"$BASE_DIR/work"</code>)<br /> Directory in which <code>pi-gen</code> builds the target system. This value can be<br /> changed if you have a suitably large, fast storage location for stages to<br /> be built and cached. Note, <code>WORK_DIR</code> stores a complete copy of the target<br /> system for each build stage, amounting to tens of gigabytes in the case of<br /> Raspbian.<br /> <strong>CAUTION</strong>: If your working directory is on an NTFS partition you probably won&#8217;t be able to build: make sure this is a proper Linux filesystem.
      </li>
      <li>
        <code>DEPLOY_DIR</code> (Default: <code>"$BASE_DIR/deploy"</code>)<br /> Output directory for target system images and NOOBS bundles.
      </li>
      <li>
        <code>DEPLOY_COMPRESSION</code> (Default: <code>zip</code>)<br /> Set to:</p> <ul dir="auto">
          <li>
            <code>none</code> to deploy the actual image (<code>.img</code>).
          </li>
          <li>
            <code>zip</code> to deploy a zipped image (<code>.zip</code>).
          </li>
          <li>
            <code>gz</code> to deploy a gzipped image (<code>.img.gz</code>).
          </li>
          <li>
            <code>xz</code> to deploy a xzipped image (<code>.img.xz</code>).
          </li>
        </ul>
      </li>
      
      <li>
        <code>DEPLOY_ZIP</code> (Deprecated)<br /> This option has been deprecated in favor of <code>DEPLOY_COMPRESSION</code>.<br /> If <code>DEPLOY_ZIP=0</code> is still present in your config file, the behavior is the<br /> same as with <code>DEPLOY_COMPRESSION=none</code>.
      </li>
      <li>
        <code>COMPRESSION_LEVEL</code> (Default: <code>6</code>)<br /> Compression level to be used when using <code>zip</code>, <code>gz</code> or <code>xz</code> for<br /> <code>DEPLOY_COMPRESSION</code>. From 0 to 9 (refer to the tool man page for more<br /> information on this. Usually 0 is no compression but very fast, up to 9 with<br /> the best compression but very slow ).
      </li>
      <li>
        <code>USE_QEMU</code> (Default: <code>"0"</code>)<br /> Setting to &#8216;1&#8217; enables the QEMU mode &#8211; creating an image that can be mounted via QEMU for an emulated<br /> environment. These images include &#8220;-qemu&#8221; in the image file name.
      </li>
      <li>
        <code>LOCALE_DEFAULT</code> (Default: &#8220;en_GB.UTF-8&#8221; )<br /> Default system locale.
      </li>
      <li>
        <code>TARGET_HOSTNAME</code> (Default: &#8220;raspberrypi&#8221; )<br /> Setting the hostname to the specified value.
      </li>
      <li>
        <code>KEYBOARD_KEYMAP</code> (Default: &#8220;gb&#8221; )<br /> Default keyboard keymap.<br /> To get the current value from a running system, run <code>debconf-show keyboard-configuration</code> and look at the<br /> <code>keyboard-configuration/xkb-keymap</code> value.
      </li>
      <li>
        <code>KEYBOARD_LAYOUT</code> (Default: &#8220;English (UK)&#8221; )<br /> Default keyboard layout.<br /> To get the current value from a running system, run <code>debconf-show keyboard-configuration</code> and look at the<br /> <code>keyboard-configuration/variant</code> value.
      </li>
      <li>
        <code>TIMEZONE_DEFAULT</code> (Default: &#8220;Europe/London&#8221; )<br /> Default keyboard layout.<br /> To get the current value from a running system, look in<br /> <code>/etc/timezone</code>.
      </li>
      <li>
        <code>FIRST_USER_NAME</code> (Default: <code>pi</code>)<br /> Username for the first user. This user only exists during the image creation process. Unless<br /> <code>DISABLE_FIRST_BOOT_USER_RENAME</code> is set to <code>1</code>, this user will be renamed on the first boot with<br /> a name chosen by the final user. This security feature is designed to prevent shipping images<br /> with a default username and help prevent malicious actors from taking over your devices.
      </li>
      <li>
        <code>FIRST_USER_PASS</code> (Default: unset)<br /> Password for the first user. If unset, the account is locked.
      </li>
      <li>
        <code>DISABLE_FIRST_BOOT_USER_RENAME</code> (Default: <code></code>)<br /> Disable the renaming of the first user during the first boot. This make it so <code>FIRST_USER_NAME</code><br /> stays activated. <code>FIRST_USER_PASS</code> must be set for this to work. Please be aware of the implied<br /> security risk of defining a default username and password for your devices.
      </li>
      <li>
        <code>WPA_ESSID</code>, <code>WPA_PASSWORD</code> and <code>WPA_COUNTRY</code> (Default: unset)<br /> If these are set, they are use to configure <code>wpa_supplicant.conf</code>, so that the Raspberry Pi can automatically connect to a wireless network on first boot. If <code>WPA_ESSID</code> is set and <code>WPA_PASSWORD</code> is unset an unprotected wireless network will be configured. If set, <code>WPA_PASSWORD</code> must be between 8 and 63 characters. <code>WPA_COUNTRY</code> is a 2-letter ISO/IEC 3166 country Code, i.e. <code>GB</code>
      </li>
      <li>
        <code>ENABLE_SSH</code> (Default: <code></code>)<br /> Setting to <code>1</code> will enable ssh server for remote log in. Note that if you are using a common password such as the defaults there is a high risk of attackers taking over you Raspberry Pi.
      </li>
      <li>
        <code>PUBKEY_SSH_FIRST_USER</code> (Default: unset)
      </li></ul> 
      
      <p>
        Setting this to a value will make that value the contents of the FIRST_USER_NAME&#8217;s ~/.ssh/authorized_keys. Obviously the value should<br /> therefore be a valid authorized_keys file. Note that this does not<br /> automatically enable SSH.
      </p>
      
      <ul dir="auto">
        <li>
          <code>PUBKEY_ONLY_SSH</code> (Default: <code></code>)
        </li>
        <li>
          Setting to <code>1</code> will disable password authentication for SSH and enable<br /> public key authentication. Note that if&#8230;
        </li>
      </ul>