Laptop installation script/guide

Having to have access to reinstall my laptop, I’m putting this up. Mirrored Encrypted ZFS configuration.

Verify actual disks by doing ls -l on the $DISK Variable. May switch between reboots. 

DISK1=/dev/disk/by-id/nvme-CT4000P3PSSD8_2252E6966FC3
DISK2=/dev/disk/by-id/nvme-CT4000P3PSSD8_2240E671E0D3


DISK2=/dev/disk/by-id/nvme-CT4000P3PSSD8_2252E6966FC3
DISK1=/dev/disk/by-id/nvme-CT4000P3PSSD8_2240E671E0D3

HOST=fafnir
USER=alan
POOL=UbuntuZFS

blkdiscard -f $DISK1

sgdisk --zap-all $DISK1
sgdisk -n1:1M:+127M -t1:EF00 -c1:EFI $DISK1
sgdisk -n2:0:+1920M -t2:8300 -c2:Boot $DISK1
sgdisk -n3:0:+64G -t3:8200 -c3:Swap $DISK1
sgdisk -n4:0:0 -t4:BF00 -c4:Pool $DISK1
sgdisk --print $DISK1

PART1UUID='blkid -s PARTUUID -o value $DISK1-part1'
PART2UUID='blkid -s PARTUUID -o value $DISK1-part2'

blkdiscard -f $DISK2 2>/dev/null
sgdisk --zap-all $DISK2
sgdisk -n1:1M:+127M -t1:EF00 -c1:EFI -u1:$PART1UUID $DISK2
sgdisk -n2:0:+1920M -t2:8300 -c2:Boot -u2:$PART2UUID $DISK2
sgdisk -n3:0:+64G -t3:8200 -c3:Swap -u3:R $DISK2
sgdisk -n4:0:0 -t4:BF00 -c4:POOL -u4:R $DISK2


For a non-mirrored boot configuration
. Making the partitions size match to ZFS doesn't complain on the mirror creation.


blkdiscard -f $DISK2 2>/dev/null
sgdisk --zap-all $DISK2
sgdisk -n1:1M:+127M -t1:EF00 -c1:EFI -u1:R $DISK2
sgdisk -n2:0:+1920M -t2:8300 -c2:Boot -u2:R $DISK2
sgdisk -n3:0:+64G -t3:8200 -c3:Swap -u3:R $DISK2
sgdisk -n4:0:0 -t4:BF00 -c4:POOL -u4:R $DISK2


zpool create -o ashift=12 -o autotrim=on \
-O compression=lz4 -O normalization=formD \
-O acltype=posixacl -O xattr=sa -O dnodesize=auto -O atime=off \
-O encryption=aes-256-gcm -O keylocation=prompt -O keyformat=passphrase \
-O canmount=off -O mountpoint=none -R /mnt/install $POOL mirror $DISK1-part4 $DISK2-part4





zfs create -o canmount=noauto -o mountpoint=/ $POOL/root
zfs mount $POOL/root

zfs create -o canmount=noauto -o mountpoint=/home $POOL/home
zfs mount $POOL/home
zfs set canmount=on $POOL/home

zfs create -o canmount=noauto -o mountpoint=/var $POOL/var
zfs mount $POOL/var
zfs set canmount=on $POOL/var

zfs create -o canmount=noauto -o mountpoint=/var/lib $POOL/var/lib
zfs mount $POOL/var/lib
zfs set canmount=on $POOL/var/lib


replicant data sets are for data that is replicated elsewhere (e.g. Dropbox or Nextcloud) or not desired to be in the home directory

zfs create -o canmount=noauto -o mountpoint=/mnt/replicant $POOL/replicant
zfs mount $POOL/replicant
zfs set canmount=on $POOL/replicant

zfs create -o canmount=noauto -o mountpoint=/mnt/replicant/Dropbox $POOL/replicant/Dropbox
zfs mount $POOL/replicant/Dropbox
zfs set canmount=on $POOL/replicant/Dropbox

zfs create -o canmount=noauto -o mountpoint=/mnt/replicant/Nextcloud $POOL/replicant/Nextcloud
zfs mount $POOL/replicant/Nextcloud
zfs set canmount=on $POOL/replicant/Nextcloud

zfs create -o canmount=noauto -o mountpoint=/mnt/replicant/storage $POOL/replicant/storage
zfs mount $POOL/replicant/storage
zfs set canmount=on $POOL/replicant/storage

yes | mkfs.ext4 $DISK1-part2
mkdir /mnt/install/boot

mount $DISK1-part2 /mnt/install/boot/

mkfs.msdos -F 32 -n EFI -i 4d65646f $DISK1-part1
mkdir /mnt/install/boot/efi

mount $DISK1-part1 /mnt/install/boot/efi

apt update
apt install --yes debootstrap
debootstrap noble /mnt/install/

echo $HOST > /mnt/install/etc/hostname
sed "s/ubuntu/$HOST/" /etc/hosts > /mnt/install/etc/hosts
cp /etc/netplan/*.yaml /mnt/install/etc/netplan/

mount --rbind /dev /mnt/install/dev
mount --rbind /proc /mnt/install/proc
mount --rbind /sys /mnt/install/sys
chroot /mnt/install /usr/bin/env \
DISK1=$DISK1 DISK2=$DISK2 HOST=$HOST USER=$USER \
bash --login


Inside CHROOT

locale-gen --purge "en_US.UTF-8"
update-locale LANG=en_US.UTF-8 LANGUAGE=en_US
dpkg-reconfigure --frontend noninteractive locales

ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime
dpkg-reconfigure -f noninteractive tzdata

apt update
apt install --yes --no-install-recommends \
linux-image-generic linux-headers-generic \
zfs-initramfs \
cryptsetup \
keyutils \
grub-efi-amd64-signed \
shim-signed \
zstd

echo "swap $DISK1-part3 /dev/urandom \
swap,cipher=aes-xts-plain64,size=256,plain" >> /etc/crypttab

echo "swap $DISK2-part3 /dev/urandom \
swap,cipher=aes-xts-plain64,size=256,plain" >> /etc/crypttab

cat /etc/crypttab


echo "PARTUUID=$(blkid -s PARTUUID -o value $DISK1-part2) /boot ext4 noatime,nofail,x-systemd.device-timeout=5s 0 1" >> /etc/fstab
echo "PARTUUID=$(blkid -s PARTUUID -o value $DISK1-part1) \
/boot/efi vfat noatime,nofail,x-systemd.device-timeout=5s 0 1" >> /etc/fstab
echo "/dev/mapper/swap none swap defaults 0 0" >> /etc/fstab


cat /etc/fstab


/etc/init.d/cryptdisks restart && sleep 5
swapon -a

echo "vm.swappiness=10" >> /etc/sysctl.conf
echo "vm.min_free_kbytes=1048576" >> /etc/sysctl.conf

echo "fs.inotify.max_user_watches = 524288" >> /etc/sysctl.conf
echo "
HandleLidSwitch=ignore" >> /etc/systemd/logind.conf
update-initramfs -c -k all

update-grub
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=Ubuntu \
--recheck --no-floppy


We need to install the Desktop first to be able to add the repo:

apt install ubuntu-desktop



Add a couple essential tools:


add-apt-repository universe
add-apt-repository restricted
add-apt-repository multiverse
apt update
bash-completion \
nano \
curl \
gparted \
smartmontools \
sanoid \
plocate


apt dist-upgrade --yes

mkdir /etc/sanoid
wget -O /etc/sanoid/sanoid.defaults.conf https://github.com/jimsalterjrs/sanoid/blob/master/sanoid.defaults.conf
wget -O /etc/sanoid/sanoid.conf https://github.com/jimsalterjrs/sanoid/blob/master/sanoid.conf


adduser --disabled-password --gecos '' $USER
usermod -a -G adm,cdrom,dip,lpadmin,plugdev,sudo $USER
echo "$USER ALL=NOPASSWD:ALL" > /etc/sudoers.d/$USER
passwd $USER




wget -O- http://packages.medo64.com/keys/medo64.asc | sudo tee /etc/apt/trusted.gpg.d/medo64.asc
echo "deb http://packages.medo64.com/deb stable main" | sudo tee /etc/apt/sources.list.d/medo64.list
apt update
apt install -y syncbootpart
syncbootpart

dd if=$DISK1-part1 of=$DISK2-part1
dd if=$DISK1-part2 of=$DISK2-part2
update-grub


exit

Out of CHROOT

sync
umount /mnt/install/boot/efi
umount /mnt/install/boot
mount | grep -v zfs | tac | awk '/\/mnt/ {print $3}' | xargs -i{} umount -lf {}
zpool export -a

reboot

Post install setup:

wget -O dropbox.deb https://www.dropbox.com/download?dl=packages/ubuntu/dropbox_2025.05.20_amd64.deb

sudo dpkg -i dropbox.deb
rm dropbox.deb


wget -O vivaldi.deb https://downloads.vivaldi.com/stable/vivaldi-stable_7.5.3735.62-1_amd64.deb
sudo dpkg -i vivaldi.deb
rm vivaldi.deb

wget -O ~/Appimages/nextcloud.AppImage https://download.nextcloud.com/desktop/releases/Linux/Nextcloud-3.17.0-x86_64.AppImage
chmod +x ~/Appimages/nextcloud.AppImage

After recovering the .ssh folder, run
ssh-add
to import identities.

Signal Messenger:

wget -O- https://updates.signal.org/desktop/apt/keys.asc | gpg --dearmor > signal-desktop-keyring.gpg;
cat signal-desktop-keyring.gpg | sudo tee /usr/share/keyrings/signal-desktop-keyring.gpg > /dev/null

# 2. Add our repository to your list of repositories:
echo 'deb [arch=amd64 signed-by=/usr/share/keyrings/signal-desktop-keyring.gpg] https://updates.signal.org/desktop/apt xenial main' |\
sudo tee /etc/apt/sources.list.d/signal-xenial.list

# 3. Update your package database and install Signal:
sudo apt update && sudo apt install signal-desktop

#Mattermost Desktop
curl -fsS -o- https://deb.packages.mattermost.com/setup-repo.sh | sudo bash
sudo apt update && sudo apt install mattermost-desktop

SuperMicro IMPI View
IMPI View
https://www.supermicro.com/en/support/resources/downloadcenter/smsdownload?category=IPMI



Master PDF:

Dungeon Draft
Wonder Draft

Zoom

sudo apt install keepassxc evolution vlc gimp imagemagick nautilus-nextcloud nautilus-image-converter plocate libfuse2

Nomachine
https://www.nomachine.com

Fix wireplumber issue:

sudo apt install libcamera-ipa pipewire-libcamera

Leave a Comment

Leave the field below empty!

This site uses Akismet to reduce spam. Learn how your comment data is processed.