Forward
This guide covers the initial setup and configuration needed to build a new Debian system. Some of the commands may assume a specific device name and should be changed to match the device name of your hardware.
Prerequisites
- A 64-bit CPU compatible with Debian 10.
- One or more storage devices (SAS, SATA, NVMe) for the root volume.
- A CD or USB drive with the Debian 10 Live image.
- An Internet connection attached to the primary network interface.
- Optionally, a FAT-formatted USB drive with
shellx64.eficopied to the/EFI/BOOT/folder. (For hardware without a working EFI shell. Some systems require this file to be renamed tobootx64.efito boot from it.)
Installation Setup
Boot from the Debian 10 live image and log in with the default username user and password live then become root using the sudo su - command. Since the initial setup of a ZFS root involves a lot of commands you may find it beneficial to configure ssh on the live image so you can run the commands remotely. To do this run apt-get update && apt-get install openssh-server && service sshd start which will install and start sshd. The command ip addr will show you which IP address was picked up by the live image from your DHCP server.
ZFS Root Disk Partitioning (EFI)
As root, run the following commands to configure apt and install the ZFS packages in the live environment:
echo -e '# debian-buster'\\n\
'deb http://ftp.us.debian.org/debian/ buster main contrib non-free'\\n\
'deb-src http://ftp.us.debian.org/debian/ buster main contrib non-free'\\n\
> /etc/apt/sources.list
apt-get update
apt-get install -y debootstrap parted gdisk linux-headers-amd64 zfs-dkms zfs-initramfs
Now that ZFS is installed you'll need to create your root pool. Almost any block device can be used for ZFS beyond the two examples below. First you'll need to create partitions and define a ZFS pool on your storage media. Use lsblk to list available storage devices and edit the commands below as necessary. Items in red should be customized for your installation.
For a single disk with the EFI partition on the same disk use the following commands:
# Single disk with EFI boot partition:
parted -a optimal /dev/sda mklabel gpt
parted -a optimal /dev/sda mkpart ESP fat32 1MB 500M
parted -a optimal /dev/sda set 1 boot on
parted -a optimal /dev/sda mkpart ZFS zfs 500M 100%
partprobe
/sbin/modprobe zfs
zpool create -f -o ashift=12 -o altroot=/mnt \
-m none -O atime=off -O relatime=on -O dedup=off \
rpool sda2
For multiple disks with a separate boot device (sda in the example below) use the following commands:
# Single disk with just the EFI boot partition:
parted -a optimal /dev/sda mklabel gpt
parted -a optimal /dev/sda mkpart ESP fat32 1MB 500M
parted -a optimal /dev/sda set 1 boot on
# Disks used for ZFS with no boot partition:
parted -a optimal /dev/sdb mklabel gpt
parted -a optimal /dev/sdb mkpart ZFS zfs 1MB 100%
parted -a optimal /dev/sdc mklabel gpt
parted -a optimal /dev/sdc mkpart ZFS zfs 1MB 100%
partprobe
/sbin/modprobe zfs
zpool create -f -o ashift=12 -o altroot=/mnt \
-m none -O atime=off -O relatime=on -O dedup=off \
rpool mirror sdb1 sdc1
After creating the ZFS pool run zpool list and zpool status to verify that you've created a root pool with the correct volumes that is the size you expect.
ZFS Root Disk Partitioning (BIOS)
Run the following commands to configure apt and install the ZFS packages in the live environment:
echo -e '# debian-buster'\\n\
'deb http://ftp.us.debian.org/debian/ buster main contrib non-free'\\n\
'deb-src http://ftp.us.debian.org/debian/ buster main contrib non-free'\\n\
> /etc/apt/sources.list
apt-get update
apt-get install -y debootstrap parted gdisk linux-headers-amd64 zfs-dkms zfs-initramfs
Now that ZFS is installed you'll need to create your root pool. Almost any block device can be used for ZFS beyond the two examples below. First you'll need to create partitions and define a ZFS pool on your storage media. Use lsblk to list available storage devices and edit the commands below as necessary. Items in red should be customized for your installation.
For a single disk use the following commands:
sgdisk --zap-all /dev/sda
sgdisk -a1 -n2:34:2047 -t2:EF02 /dev/sda
sgdisk -n1:0:0 -t1:BF01 /dev/sda
partprobe
/sbin/modprobe zfs
zpool create -f -o ashift=12 -o altroot=/mnt \
-m none -O atime=off -O relatime=on -O dedup=off \
rpool sda1
For multiple disks use the following commands:
sgdisk --zap-all /dev/sda
sgdisk -a1 -n2:34:2047 -t2:EF02 /dev/sda
sgdisk -n1:0:0 -t1:BF01 /dev/sda
sgdisk --zap-all /dev/sdb
sgdisk -a1 -n2:34:2047 -t2:EF02 /dev/sdb
sgdisk -n1:0:0 -t1:BF01 /dev/sdb
partprobe
/sbin/modprobe zfs
zpool create -f -o ashift=12 -o altroot=/mnt \
-m none -O atime=off -O relatime=on -O dedup=off \
rpool mirror sda1 sdb1
After creating the ZFS pool run zpool list and zpool status to verify that you've created a root pool with the correct volumes that is the size you expect.
Prepare ZFS Root for Installation
The following commands will create a 64GB ZVOL used for swap. This can be changed later without repartitioning. 64GB is recommended for systems with 128GB or more of memory. If your system has 16GB to 128GB a 32GB swap area is often sufficient.
zfs create -V 64G -b $(getconf PAGESIZE) -o compression=zle \
-o logbias=throughput -o sync=always \
-o primarycache=metadata -o secondarycache=none \
-o com.sun:auto-snapshot=false rpool/swap
mkswap -L swap /dev/zvol/rpool/swap
Next create the root dataset. Re-import the pool to use "by-id" device names, and mount it at /mnt to install the root filesystem.
zfs create -o mountpoint=none rpool/ROOT
zfs create -o mountpoint=/ rpool/ROOT/debian
zpool set bootfs=rpool/ROOT/debian rpool
zpool export rpool
zpool import -d /dev/disk/by-id -R /mnt rpool
mkdir -p /mnt/etc/zfs
zpool set cachefile=/mnt/etc/zfs/zpool.cache rpool
Install Debian Base System
The following commands will install Debian to /mnt using debootstrap and create some basic configuration files. Change the environment variables to suit before running.
export IHNAME=myhostname
export IDNAME=mydomainame.com
debootstrap --arch=amd64 buster /mnt http://httpredir.debian.org/debian/
echo $IHNAME > /mnt/etc/hostname
sed -i -Ee "s#(127.+)#\1 $IHNAME.$IDNAME $IHNAME#" /mnt/etc/hosts
echo /dev/zvol/rpool/swap none swap defaults 0 0 > /mnt/etc/fstab
echo -e \
'# This file describes the network interfaces available on your system'\\n\
'# and how to activate them. For more information, see interfaces(5).'\\n\
''\\n\
'source /etc/network/interfaces.d/*'\\n\
''\\n\
'# The loopback network interface'\\n\
'auto lo'\\n\
'iface lo inet loopback'\
> /mnt/etc/network/interfaces
echo -e '# buster-main'\\n\
'deb http://ftp.us.debian.org/debian/ buster main contrib non-free'\\n\
'deb-src http://ftp.us.debian.org/debian/ buster main contrib non-free'\\n\
\\n\
'# buster-security'\\n\
'deb http://security.debian.org/ buster/updates main contrib non-free'\\n\
'deb-src http://security.debian.org/ buster/updates main contrib non-free'\\n\
\\n\
'# buster-updates'\\n\
'deb http://ftp.us.debian.org/debian/ buster-updates main contrib non-free'\\n\
'deb-src http://ftp.us.debian.org/debian/ buster-updates main contrib non-free'\\n\
\\n\
'# buster-backports'\\n\
'deb http://ftp.us.debian.org/debian/ buster-backports main contrib non-free'\\n\
'deb-src http://ftp.us.debian.org/debian/ buster-backports main contrib non-free'\
> /mnt/etc/apt/sources.list
for f in dev dev/pts proc sys; do mount -v --bind {,/mnt}/$f; done
chroot /mnt /bin/bash --login
apt-get update
apt-get install -y debootstrap parted linux-headers-amd64 \
linux-image-amd64 sudo gdisk locales dosfstools curl
sed -i -Ee 's/# (en_US.UTF+)/\1/' /etc/locale.gen && locale-gen
apt-get install -y zfs-dkms zfs-initramfs
# If this is a server run:
echo -e \\n\
'# The primary network interface'\\n\
'allow-hotplug eno1'\\n\
'iface eno1 inet dhcp'\
>> /etc/network/interfaces
tasksel install ssh-server standard
# If this is a desktop run:
tasksel install desktop gnome-desktop print-server ssh-server standard
# If this is a laptop run:
tasksel install desktop gnome-desktop print-server ssh-server laptop standard
Configure Grub (EFI)
Now you can set up grub-efi. Verify your storage devices using lsblk and change the commands below as necessary.
mkdir /boot/efi
mkdosfs -F 32 -n EFI /dev/sda1
echo UUID=$(blkid -s UUID -o value /dev/sda1) \
/boot/efi vfat defaults 0 1 >> /etc/fstab
mount /boot/efi
apt-get install -y grub-efi-amd64
grub-probe /boot/efi/
grub-probe /
update-initramfs -u -k all
update-grub
grub-install --target=x86_64-efi --efi-directory=/boot/efi \
--bootloader-id=debian --recheck --no-floppy
find /boot/efi -type f
ls /boot/grub/*/zfs.mod
Configure Grub (BIOS)
Now you can set up grub-pc. Verify your storage devices using lsblk and change the commands below as necessary. During this process you will be prompted to select your "GRUB install devices", you should select all disks which are a member of your root pool.
mkdir /boot/dos
apt-get install -y grub-pc
grub-probe /
update-initramfs -u -k all
update-grub
grub-install /dev/sda
# Run for each additional disk:
grub-install /dev/sdb
ls /boot/grub/*/zfs.mod
Complete Installation and Reboot
Add a local user account and reboot into the new Debian installation.
export INNEWNAME="user"
export INCOMMENT="First Lastname"
export NEWUID="1000"
export NEWGID="1000"
groupadd -g $NEWGID $INNEWNAME
useradd -g $INNEWNAME -G 24,25,27,29,30,44,46,108 \
-u $NEWUID $INNEWNAME -d /home/$INNEWNAME -m -s /bin/bash -c "$INCOMMENT"
passwd $INNEWNAME
exit
mount | grep -v zfs | tac | awk '/\/mnt/ {print $3}' | xargs -i{} umount -lf {}
zpool export rpool
reboot