{"slug": "how-to-install-truenas-scale-25-10-on-a-partition-instead-of-the-full-disk-boot", "title": "How to install TrueNAS SCALE 25.10 on a partition instead of the full disk + mirror boot and data partition at a later stage", "summary": "This article provides a technical guide for installing TrueNAS SCALE on a 16GB partition of a large NVMe drive, rather than using the entire disk, to conserve storage space. It details how to modify the installer script to create a smaller boot partition, then manually partition the remaining disk space for a data pool using command-line tools like `parted` and `sgdisk`. The guide also explains how to later mirror the boot and data partitions to a second drive by cloning the partition table and creating a ZFS mirror.", "body_md": "The TrueNAS installer doesn’t have a way to use anything less than the full device. This is a waste of capacity when installing to large NVMe which is usually several hundred of GB or even TB. TrueNAS SCALE will use only a few GB for its system files so installing to a 16GB partition is sufficient.\n\nThis guide covers for ***TrueNas Scale 24.04 to 25.10***\n\nYou can to modify the installer script before starting the installation process.\n\n1. Boot TrueNAS Scale installer from USB/ISO\n2. Select shell in the first menu (instead of installing)\n3. While in the shell, find and open the installer and edit using vi\n\n**For TrueNasScale before 24.10** - https://github.com/truenas/truenas-installer/blob/release/24.04.2.5/usr/sbin/truenas-install#L460\nvi /usr/sbin/truenas-install\n\n**For TrueNasScale 24.10+** - https://github.com/truenas/truenas-installer/blob/76a188e9048f26bca1a88f5d46a552742b3db286/truenas_installer/install.py#L81\nvi /usr/lib/python3/dist-packages/truenas_installer/install.py\n\n4. in vi you can use \"set number\" to easily see on what line of code you are\n5. make the changes on line 81 as follows: `await run([\"sgdisk\", \"-n3:0:+16GiB\", \"-t3:BF01\", disk.device])`\n6. exit vi and type exit to return from the shell\n7. Select Install/Upgrade from the Console Setup menu (without rebooting, first) and install to NVMe drive.\n8. Remove the USB and reboot.\n\nNext we re-partition the nvme. You can perform this next setp on console or enable ssh via TrueNas Gui\n\n\n\n1. Login to the linux shell.\n2. Verify the created partition and their alignment\n\n\n```bash\ntruenas_admin@truenas[~]$ sudo fdisk -l /dev/nvme0n1\nDisk /dev/nvme0n1: 931.51 GiB, 1000204886016 bytes, 1953525168 sectors\nDisk model: CT1000P3PSSD8\nUnits: sectors of 1 * 512 = 512 bytes\nSector size (logical/physical): 512 bytes / 512 bytes\nI/O size (minimum/optimal): 512 bytes / 512 bytes\nDisklabel type: gpt\nDisk identifier: 67X88FDC-3A4E-43FC-BA2F-AD279703FBFF\n\nDevice           Start      End  Sectors  Size Type\n/dev/nvme0n1p1    4096     6143     2048    1M BIOS boot\n/dev/nvme0n1p2    6144  1054719  1048576  512M EFI System\n/dev/nvme0n1p3 1054720 34609151 33554432   16G Solaris /usr & Apple ZFS\n\n\ntruenas_admin@truenas[~]$ for p in 1 2 3; do sudo parted /dev/nvme0n1 align-check optimal $p; done\n1 aligned\n2 aligned\n3 aligned\n\n```\n\n\n3. create a partition allocating the rest of the disk.\n\n\n```bash\ntruenas_admin@truenas[~]$ sudo parted\n(parted) name 3 boot-pool\n(parted) unit KiB\n(parted) print\n(parted) mkpart ssd-pool 17304576kiB 100%\n(parted) print\nModel: CT1000P3PSSD8 (nvme)\nDisk /dev/nvme0n1: 976762584kiB\nSector size (logical/physical): 512B/512B\nPartition Table: gpt\nDisk Flags:\n\nNumber  Start        End           Size          File system  Name       Flags\n 1      2048kiB      3072kiB       1024kiB                               bios_grub, legacy_boot\n 2      3072kiB      527360kiB     524288kiB     fat32                   boot, esp\n 3      527360kiB    17304576kiB   16777216kiB   zfs          boot-pool\n 4      17304576kiB  976761856kiB  959457280kiB               ssd-pool\n\ntruenas_admin@truenas[~]$ for p in 1 2 3 4; do sudo parted /dev/nvme0n1 align-check optimal $p; done\n1 aligned\n2 aligned\n3 aligned\n4 aligned\n\n```\n\n4. setup the zpool for the UI to pick it up\n\n`sudo zpool create ssd-pool /dev/nvme0n1p4`\n`sudo zpool export ssd-pool`\n\nNOTE: you can ignore the error message \"cannot mount '/ssd-pool': failed to create mountpoint: Read-only file system\"\n\n\n5. use the TrueNas `Gui` -> Storage Dashboard -> `Import Pool`\n\n\n\n# (Re-) Creating a mirrored Boot and Data Pool:\n\n<u>**IMPORTANT**: zpool replace does not recreate or copy the EFI boot partition!</u>\n\n*This need to be done manually!!!*\n\n\n##### Step 1 — Completely wipe new drive/replacement drive/formerly used drive [eg.: nvme1n1]\n\nThis guarantees no stale metadata. (GPT + ZFS labels)\n\n`\n```language\nsudo zpool labelclear -f /dev/nvme1n1\nsudo wipefs -a /dev/nvme1n1\nsudo sgdisk --zap-all /dev/nvme1n1\n```\n`\nVerify:\n\n`lsblk -f /dev/nvme1n1`\nNo filesystems, no partitions.\n\n##### Step 2 — Clone the partition table\nWe do not use parted here!\nWe use sgdisk, which is what TrueNAS relies on internally.\n\n`sudo sgdisk -R=<newDrive> <existingDrive>`\n`sudo sgdisk -G /dev/nvme1n1`\n\nThis:\n\n*Copies GPT header\nCopies all partition offsets\nPreserves 1 MiB alignment\nMakes layouts identical\nIn addition, regenerate unique disk GUIDs (required)*\n\n\n\n\n```bash\ntruenas_admin@truenas[~]$ sudo sgdisk -R=/dev/nvme1n1 /dev/nvme0n1\nThe operation has completed successfully.\ntruenas_admin@truenas[~]$ sudo sgdisk -G /dev/nvme1n1\nThe operation has completed successfully.\n\ntruenas_admin@truenas[~]$ lsblk -f\nNAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS\nnvme1n1\n├─nvme1n1p1\n├─nvme1n1p2 vfat FAT32 EFI 4E95-56BB\n├─nvme1n1p3 zfs_member 5000 boot-pool 5995343355652310543\n└─nvme1n1p4 zfs_member 5000 ssd-pool 8868205190042146147\nnvme0n1\n├─nvme0n1p1\n├─nvme0n1p2 vfat FAT32 EFI 6165-92D6\n├─nvme0n1p3 zfs_member 5000 boot-pool 3904092570291516174\n└─nvme0n1p4 zfs_member 5000 ssd-pool 7548575174596316953\n```\n\n\n##### Step 3 — Verify layouts match exactly\n\n`sudo sgdisk -p /dev/nvme0n1`\n`sudo sgdisk -p /dev/nvme1n1`\n\nThe start/end sectors must match for:\n\np1 (BIOS_GRUB)\np2 (EFI)\np3 (boot-pool slice)\np4 (data slice)\n\nAlso check:\n \n`lsblk -o NAME,START,SIZE /dev/nvme0n1  /dev/nvme1n1`\n\nThey should now be identical.\n\n\n\n##### Step 4 — Attach nvme1n1p3 to the boot pool (CLI)\n\nLets add the new drives to the pool and create a mirror:\n\n`sudo zpool attach <pool-name> <existingDrive> <newDrive>`\n\nThis creates:\n\n\n```bash\ntruenas_admin@truenas[~]$ sudo zpool attach boot-pool nvme0n1p3 nvme1n1p3\ntruenas_admin@truenas[~]$ zpool status boot-pool\n  pool: boot-pool\n state: ONLINE\n  scan: resilvered 3.23G in 00:00:05 with 0 errors on Wed Mar  4 06:01:53 2026\nconfig:\n\n        NAME           STATE     READ WRITE CKSUM\n        boot-pool      ONLINE       0     0     0\n          mirror-0     ONLINE       0     0     0\n            nvme0n1p3  ONLINE       0     0     0\n            nvme1n1p3  ONLINE       0     0     0\n```\n\nOptional mirror the Data/Application Pool:\n\n\n```bash\ntruenas_admin@truenas[~]$ sudo zpool attach ssd-pool nvme0n1p4 nvme1n1p4\ntruenas_admin@truenas[~]$ zpool status ssd-pool\n  pool: ssd-pool\n state: ONLINE\n  scan: resilvered 2.21M in 00:00:00 with 0 errors on Thu Mar  5 06:14:42 2026\nconfig:\n\n        NAME           STATE     READ WRITE CKSUM\n        ssd-pool       ONLINE       0     0     0\n          mirror-0     ONLINE       0     0     0\n            nvme0n1p4  ONLINE       0     0     0\n            nvme1n1p4  ONLINE       0     0     0\n```\n\n**Recommended dataset layout for apps**\n`sudo zfs set compression=zstd ssd-pool`\n`sudo zfs set atime=off ssd-pool`\n\n##### Step 5 — (IMPORTANT) Install EFI bootloader on nvme1n1\n\nZFS mirror alone is not enough — <u>EFI must exist</u>.\n\nConfirm what /boot/efi really is right now\n\nRun:\n\n\n```bash\ntruenas_admin@truenas[~]$ sudo findmnt /boot/efi || true\ntruenas_admin@truenas[~]$ ls -ld /boot/efi\ndrwxr-xr-x 2 root root 2 Mar  3 23:58 /boot/efi\ntruenas_admin@truenas[~]$ sudo blkid /dev/nvme0n1p2 /dev/nvme1n1p2\n/dev/nvme0n1p2: LABEL_FATBOOT=\"EFI\" LABEL=\"EFI\" UUID=\"6165-92D6\" BLOCK_SIZE=\"512\" TYPE=\"vfat\" PARTUUID=\"24657b7f-2cfa-44dc-842a-498c73e48478\"\n/dev/nvme1n1p2: LABEL_FATBOOT=\"EFI\" LABEL=\"EFI\" UUID=\"4E95-56BB\" BLOCK_SIZE=\"512\" TYPE=\"vfat\" PARTUUID=\"6ebe1b30-0ec9-47a6-82a9-a2cd11a2d2ef\"\n```\n\n\n- If findmnt shows nothing → /boot/efi is not mounted (most likely).\n- blkid should show TYPE=\"vfat\" for the ESP partitions.\n\n\nInstead of running grub-install, do what appliance systems commonly do:\n\nMount ESP on nvme0\nMount ESP on nvme1\nCopy the EFI files\nOptionally add a BIOS/UEFI boot entry for the new drive\n\n\n##### A. Mount both ESPs\n\n\n```bash\ntruenas_admin@truenas[~]$ sudo mkdir -p /mnt/esp0 /mnt/esp1\ntruenas_admin@truenas[~]$ sudo mount -t vfat /dev/nvme0n1p2 /mnt/esp0\ntruenas_admin@truenas[~]$ sudo mount -t vfat /dev/nvme1n1p2 /mnt/esp1\n```\nNOTE: If mounting /dev/nvme1n1p2 fails or it’s not vfat, reformat it (this erases only the esp partion on nvme1):\n\n*sudo mkfs.vfat -F32 -n EFI /dev/nvme1n1p2\nsudo mount -t vfat /dev/nvme1n1p2 /mnt/esp1*\n\n##### B. Copy EFI contents from disk 0 to disk 1\n\n`sudo rsync -aH --delete /mnt/esp0/ /mnt/esp1/\nsync`\n\n##### C. Make sure the “removable media” fallback exists (helps a lot)\n\nMany firmwares will boot \\EFI\\BOOT\\BOOTX64.EFI automatically if no NVRAM entry exists.\n\nCheck what TrueNAS placed on the ESP:\n\n\n```bash\ntruenas_admin@truenas[~]$ sudo find /mnt/esp0/EFI -maxdepth 2 -type f -iname '*.efi' -print\n/mnt/esp1/EFI/boot/bootx64.efi\n/mnt/esp1/EFI/debian/fbx64.efi\n/mnt/esp1/EFI/debian/grubx64.efi\n/mnt/esp1/EFI/debian/mmx64.efi\n/mnt/esp1/EFI/debian/shimx64.efi\n```\n\nIf you see something like /mnt/esp0/EFI/debian/grubx64.efi (example), create the fallback:\n\n\n```bash\ntruenas_admin@truenas[~]$ sudo mkdir -p /mnt/esp1/EFI/BOOT\ntruenas_admin@truenas[~]$ sudo cp -f /mnt/esp0/EFI/*/grubx64.efi /mnt/esp1/EFI/BOOT/BOOTX64.EFI\nsync\n```\n\n(That EFI/*/grubx64.efi glob is deliberate so it works even if the vendor dir isn’t exactly truenas.)\n\n##### D. Add an NVRAM boot entry for newDrive (Optional but recommended)\n\nFirst, see existing entries:\n\n```language\ntruenas_admin@truenas[~]$ sudo efibootmgr -v\nBootCurrent: 0002\nTimeout: 1 seconds\nBootOrder: 0002,0000,0001,0003\nBoot0000  Windows Boot Manager  VenHw(99e275e7-75a0-4b37-a2e6-c5385e6c00cb)WINDOWS.........x...B.C.D.O.B.J.E.C.T.=.{.9.d.e.a.8.6.2.c.-.5.c.d.d.-.4.e.7.0.-.a.c.c.1.-.f.3.2.b.3.4.4.d.4.7.9.5.}...................\nBoot0001  debian        VenHw(99e275e7-75a0-4b37-a2e6-c5385e6c00cb)\nBoot0002* debian        HD(2,GPT,24657b7f-2cfa-44dc-842a-498c73e48478,0x1800,0x100000)/File(\\EFI\\debian\\shimx64.efi)\nBoot0003  TrueNAS (nvme1)       VenHw(99e275e7-75a0-4b37-a2e6-c5385e6c00cb)\n```\n\nThen create a new one pointing to the copied loader (adjust the path to whatever you actually have on the ESP; use the find output you ran above):\n\n\n```language\ntruenas_admin@truenas[~]$ sudo efibootmgr -c -d /dev/nvme0n1 -p 2 -L \"TrueNAS (nvme1)\" -l '\\EFI\\truenas\\grubx64.efi'\nBootCurrent: 0002\nTimeout: 1 seconds\nBootOrder: 0004,0002,0000,0001,0003\nBoot0000  Windows Boot Manager\nBoot0001  debian\nBoot0002* debian\nBoot0003  TrueNAS (nvme1)\nBoot0004* TrueNAS (nvme1)\n```\n\n\n##### E. Unmount\n\n`sudo umount /mnt/esp0 /mnt/esp1`\n\n##### F. Validate EFI Bootmanager\n\n\n```bash\ntruenas_admin@truenas[~]$ sudo efibootmgr -v\nBootCurrent: 0003\nTimeout: 1 seconds\nBootOrder: 0006,0005,0003,0000,0001,0002,0004\nBoot0000  Windows Boot Manager  VenHw(99e275e7-75a0-4b37-a2e6-c5385e6c00cb)WINDOWS.........x...B.C.D.O.B.J.E.C.T.=.{.9.d.e.a.8.6.2.c.-.5.c.d.d.-.4.e.7.0.-.a.c.c.1.-.f.3.2.b.3.4.4.d.4.7.9.5.}...................\nBoot0001  debian        VenHw(99e275e7-75a0-4b37-a2e6-c5385e6c00cb)\nBoot0002  debian        VenHw(99e275e7-75a0-4b37-a2e6-c5385e6c00cb)\nBoot0003* debian        HD(2,GPT,51003091-0620-4c18-868c-ea9dba1f564e,0x1800,0x100000)/File(\\EFI\\debian\\shimx64.efi)\nBoot0004  TrueNAS (nvme1)       VenHw(99e275e7-75a0-4b37-a2e6-c5385e6c00cb)\nBoot0005* TrueNAS (nvme1)       HD(2,GPT,ff4dba6e-93b9-45ea-b546-33c28c63f612,0x1800,0x100000)/File(\\EFI\\truenas\\grubx64.efi)\nBoot0006* TrueNAS (nvme1)       HD(2,GPT,51003091-0620-4c18-868c-ea9dba1f564e,0x1800,0x100000)/File(\\EFI\\truenas\\grubx64.efi)\n```\n\nNOTE: as this is my 3rd iteration, Boot0004 is not a proper file path (it shows VenHw) meaning it's probably stale, so removed it.\n\n\n```bash\ntruenas_admin@truenas[~]$ sudo efibootmgr -b 0003 -B\nBootCurrent: 0002\nTimeout: 1 seconds\nBootOrder: 0004,0002,0000,0001\nBoot0000  Windows Boot Manager\nBoot0001  debian\nBoot0002* debian\nBoot0004* TrueNAS (nvme1)\n```\n\n##### G. Now you can test by removing the a Drive from the Mirror and reboot the system\n\n\nDrive goes into degraded state after pulling Drive2\n\n```language\ntruenas_admin@truenas[~]$ sudo zpool status\n  pool: boot-pool\n state: DEGRADED\n config:\n\n        NAME                      STATE     READ WRITE CKSUM\n        boot-pool                 DEGRADED     0     0     0\n          mirror-0                DEGRADED     0     0     0\n            15318324978903853925  FAULTED      0     0     0  was /dev/nvme0n1p3\n            nvme0n1p3             ONLINE       0     0     0\n\n\n  pool: ssd-pool\n state: DEGRADED\n config:\n\n        NAME                     STATE     READ WRITE CKSUM\n        ssd-pool                 DEGRADED     0     0     0\n          mirror-0               DEGRADED     0     0     0\n            2513775003968519971  FAULTED      0     0     0  was /dev/nvme0n1p4\n            nvme0n1p4            ONLINE       0     0     0\n\n```\n\n\nZFS is switching on how it displays a vdev when the normal device path is missing, so you'll a long number instead of nvme1n1p3\n\nThose long numbers like [2513775003968519971] are ZFS vdev GUIDs.\n\nZFS stores devices internally by GUID. When the OS device node (like /dev/nvme1n1p3) is missing/unavailable, ZFS can’t resolve it to a path, so it shows the GUID instead.\n\nYou would simply de-tach the FAULTY Drives\n\n\n```bash\ntruenas_admin@truenas[~]$ sudo zpool detach ssd-pool 2513775003968519971\ntruenas_admin@truenas[~]$ sudo zpool detach boot-pool 15318324978903853925\ntruenas_admin@truenas[~]$ zpool status\n  pool: boot-pool\n state: ONLINE\n  scan: resilvered 3.23G in 00:00:06 with 0 errors on Thu Mar  5 06:11:03 2026\nconfig:\n\n        NAME         STATE     READ WRITE CKSUM\n        boot-pool    ONLINE       0     0     0\n          nvme0n1p3  ONLINE       0     0     0\n\nerrors: No known data errors\n\n  pool: ssd-pool\n state: ONLINE\n  scan: resilvered 2.21M in 00:00:00 with 0 errors on Thu Mar  5 06:14:42 2026\nconfig:\n\n        NAME         STATE     READ WRITE CKSUM\n        ssd-pool     ONLINE       0     0     0\n          nvme0n1p4  ONLINE       0     0     0\n\n\n```\n\nNOTE: Make sure you identify the device names correctly as they might change, so check your zpool before!\n\nThe correct way to reference disks when running manual ZFS commands you should never rely on /dev/nvmeX.\n\nInstead use stable paths: /dev/disk/by-id/\n\nCheck them:\nls -l /dev/disk/by-id/ | grep -i nvme\nls -l /dev/disk/by-id/ | grep -E 'part3|part4'\n\n\n## After the drive-replacement, start from top again by (Re-) Creating a mirrored Boot and Data Pool", "url": "https://wpnews.pro/news/how-to-install-truenas-scale-25-10-on-a-partition-instead-of-the-full-disk-boot", "canonical_source": "https://gist.github.com/MRi-LE/861a8d4f6850abaed8b89c3ea091d608", "published_at": "2026-03-04 09:18:42+00:00", "updated_at": "2026-05-23 01:05:13.104355+00:00", "lang": "en", "topics": ["open-source", "developer-tools", "data", "products", "enterprise-software"], "entities": ["TrueNAS SCALE", "TrueNAS", "NVMe", "Linux"], "alternates": {"html": "https://wpnews.pro/news/how-to-install-truenas-scale-25-10-on-a-partition-instead-of-the-full-disk-boot", "markdown": "https://wpnews.pro/news/how-to-install-truenas-scale-25-10-on-a-partition-instead-of-the-full-disk-boot.md", "text": "https://wpnews.pro/news/how-to-install-truenas-scale-25-10-on-a-partition-instead-of-the-full-disk-boot.txt", "jsonld": "https://wpnews.pro/news/how-to-install-truenas-scale-25-10-on-a-partition-instead-of-the-full-disk-boot.jsonld"}}