I regularly have the need to try things out on Linux. Sometimes a virtual machine won't cut it for me typically due to memory, disk and performance limitations. Moreover, a decent, up-to-date, bootable Linux environment is a great backup in case all of my other computers are broken, infected or stolen. That entails having the Linux installation on an external, USB-attached hard disk drive which can boot with relative ease on any UEFI-enabled PC (driver compatibility notwithstanding). Moreover, all the preparatory work has to be performed using a single-boot Windows computer without ending up having a dual boot system. It sounds tough. It is tough, but I'm writing this from my portable Ubuntu Linux installation running off a USB-attached SSD!

What you need

  • An empty external (USB) hard drive. I used a USB 3 drive enclosure with a cheap 256Gb SSD. For those of you worrying about performance, the USB 3.0 port is faster than the maximum transfer rate of any SSD I've seen to this date.
  • Ubuntu Linux bootable USB drive. Very easy to create using Rufus on Windows. I used a cheap, promotional flash drive. Reduce, reuse, recycle FTW.
  • Windows System Repair Disc (a bootable USB drive with Windows recovery tools which you can make yourself) or a Windows installation or rescue CD-ROM / DVD-ROM. I used another promotional flash drive.

Remember to take backups of all your critical files and folders before continuing. You are going to make changes to your computer. If it breaks don't cry, I warned you. Also test both your bootable media. Twice. You will need them both!

Caveats

Having a dual- or multi-boot system isn't as straightforward as it used to be a decade ago. Nowadays, in the interest of security, performance and backwards compatibility, there are many semi-hidden options and features which can get in your way. Given enough experience and patience you can work around them. Below is a selection of problems that got me moderately stumped along the way.

Secure boot caveat

I have only tested these instructions with Secure Boot turned off. Even though Ubuntu does support Secure Boot (it comes with signed bootloaders) I have no idea if my method uses the signed bootloaders or not. I suggest turning off Secure Boot if possible.

FastBoot caveats

Many boards come with some sort of "fast boot" or "boot optimization" options. For example, my Intel NUC has an option called Fast Boot which won't let me choose an alternative boot device at startup. It also has an option to support Intel Rapid Start Technology which does get in the way of booting to multiple OS. I had to disable both.

It's worth noting that Windows 8 and 10 have an Fast Startup or Fast Boot feature. This feature takes some shortcuts when it comes to booting and also makes the NTFS filesystem remain in a dirty state, making it unwriteable from Linux. It's best to understand what it does and disable it if you plan on writing to your Windows drive from Linux.

USB host controller caveat

Some firmwares will present the USB host controller as UHCI (USB 1.1) at boot time. When Linux probes for an xHCI (USB 3) host controller during the boot process they will respond positively. At this time Linux loads the xHCI driver and the USB host controller resets itself.

However, your root filesystem is inside a device attached to this USB controller. Therefore the controller resetting means that Linux can no longer communicate with the USB-attached hard drive. Therefore the Linux boot will hang forever without any further indication as to what went wrong.

Most affected boards (including my Intel NUC) have an option to enable the xHCI host controller interface by default. Enabling the xHCI option in the BIOS fixes the hanging boot issue. If you are only using modern operating systems with USB 3 support (anything newer than and including Windows 8.1 and Ubuntu Linux 15.04) you can safely enable that option.

Installing Linux

Boot your computer from the Ubuntu Linux bootable USB drive. Remember that you may have to enter your computer's boot manager to do that (on my Intel NUC I have to press F10; on most other BIOS I've seen it's F9; consult your BIOS documentation).

Install Ubuntu Linux regularly. When it prompts you about the disk layout choose Something Else and partition your external HDD the way you want. I chose to create a modestly sized root partition (about 40Gb), a swap partition that's as big as the biggest RAM configuration I am going to be using this installation with plus one Gb (my computers max out at 16Gb so I made a 17Gb swap partition) and the rest of the disk went to a massive /home partition.

Caveat: I chose to use btrfs which – as I learned along the way – makes things a bit more complicated down the line. For your sanity's sake I recommend using ext4. This guide assumes the use of btrfs and will point out the caveats with this approach.

Fix Windows 10 boot

Unfortunately the Ubuntu Installer assumes that you want a dual booting configuration alongside Windows. Therefore it adds itself (actually, the bootloader it uses, GRUB2) to your computer's UEFI configuration. This causes two problems. For starters, the external HDD is not portable as you cannot boot with it on another computer.

Secondly, if you remove this external HDD your Windows won't boot. Bummer. We have to fix that.

  • Shut down your computer.
  • Disconnect the Ubuntu HDD
  • Boot from the Windows system repair disc USB drive (or a Windows installation or rescue CD-ROM / DVD-ROM).
  • Select Repair your computer.
  • Select the operating system and click Next.
  • Choose Command Prompt.
  • In the command prompt run
    diskpart
    sel disk 0
    list vol
  • Verify that the EFI partition is using the FAT32 file system. It will have a volume ID, let's say 99. Now we need to assign a drive letter to it. Back in the command prompt type:
    sel vol 99
    assign letter=z:
    exit
  • Now we need to fix the boot record. Again in the command prompt type:
    z:
    cd EFI/Microsoft/Boot
    bootrec /FixBoot
  • Finally, we need to re-create the BCD store which tells the Microsoft boot loader where to find Windows so it can boot it. From our trusted command prompt:
    ren BCD BCD.old
    bcdboot c:\Windows /l en-us /s z: All
  • If this didn't work try
    ren BCD BCD.old
    bootrec /RebuildBcd

At this point exit the command prompt and shut down your computer.

Create an ESP on the Ubuntu HDD

A hard drive is not bootable with UEFI unless it has an ESP (EFI System Partition). An ESP is simply a FAT32 partition with a special flag that tells the EFI BIOS to look inside it for boot information. We have to create one on your hard drive.

  • Plug in your external HDD and the Ubuntu Linux bootable USB stick.
  • Boot with the Ubuntu Linux bootable USB stick using the option to try Ubuntu before installing.
  • Open a Terminal (CTRL-ALT-T)
  • Run sudo fdisk -l to get a list of partitions.
  • Identify from them the drive that has the Linux partitions, in my case /dev/sdb. I'll call it /dev/sdX from now on.
  • Also identify the partition that contains the root filesystem. I will call it /dev/sdXY from now on.
  • Launch GParted from the Terminal:
    sudo gparted /dev/sdX
    Why not just click on GParted on your desktop? Well, I kept receiving errors about the Ubuntu Linux bootable USB stick because it was already in use. Of course it is, I am using it to run the computer off it, duh!
  • Resize the first partition on disk to have another 200 Mb of free space after it.
  • Create a new partition on the free space, changing the file system to fat32.
  • Apply operations. You need to do that now for the next step to be possible.
  • Right click the new partition.
  • Click on Manage Flags.
  • Set the boot and esp flags. This is what makes the partition "special" to the EFI BIOS.
  • One more thing! Note down the the partition that contains the ESP filesystem. I will call it /dev/sdXZ from now on.

Make sure the Ubuntu installation on the external HDD can see the ESP

The new ESP on the external drive must be visible by the Ubuntu installation in the HDD. Otherwise GRUB2, the Linux bootloader, won't be able to update itself, making your system unbootable after the next kernel update at the latest.

  • Launch GParted from the Terminal, as we saw above:
    sudo gparted /dev/sdX
  • Double click the partition with your Linux root (/) filesystem on the external HDD
  • Note down the UUID, e.g. 01234567-89ab-cdef-0123-4567890abcde
  • Double click the new FAT32 partition and note down the UUID, e.g. 0123-ABCD
  • Close GParted
  • Open a Terminal

The process is different depending on the format of your root partition on the external hard disk.

If you DID NOT use btrfs (e.g. you used ext4)

sudo umount /media/ubuntu/01234567-89ab-cdef-0123-4567890abcde 
sudo mount /dev/sdXY /mnt

If you DID use btrfs

If you DID use btrfs, you made your life complicated. We need to mount the btrfs subvolume containing the root partition instead of the entire partition. Otherwise you'll never be able to install GRUB and you'll probably lose an entire day, like me.

btrfs subvolume list /media/ubuntu/01234567-89ab-cdef-0123-4567890abcde

This will give you a line with a numeric ID. Let's say 123. Note it down.

umount /media/ubuntu/01234567-89ab-cdef-0123-4567890abcde
mount /dev/sdXY -o subvolid=123 /mnt

The rest of the instructions are common, no matter if used btrfs, ext4 or something else

  • sudo nano /mnt/etc/fstab
  • There is a line with /boot/efi already in this file. Comment it by placing a # in front of it.
  • Add the following line:
    UUID=0123-ABCD /boot/efi vfat defaults 0 1

Install GRUB2 on the external drive's EFI System Partition

Right now our external drive has an empty ESP. We need to put a bootloader in it to make it actually, well, bootable.

First caveat: all the instructions you find on-line assume you are using a dual boot system with Windows or macOS. When you have an external drive it is critical that you use the --removable option in the last step. This installs the EFI bootloader under the special "fallback path" EFI\Boot\bootx64.efi in the ESP. Normally this not supposed to be used for permanently installed Operating Systems. It's the mechanism used by EFI BIOS to boot arbitrary external media. Technically, that's exactly what our external hard drive is: arbitrary external media!

Second caveat: installing the bootloader is only possible from inside the Linux installation we want to boot. However, we need the bootloader to boot that installation, leading to a Catch-22 issue. The solution is to run the bootloader installation through a chroot jail. The actual caveat that got me stumped for a day comes from the fact that I am using btrfs (because it's so much better for SSDs!). btrfs has subvolumes. If you mount the entire partition instead of a subvolume the grub-install script can't figure out the mapping between paths and devices, therefore failing to install itself on the ESP, returning the cryptic error

/usr/sbin/grub-probe: error: cannot find a device for / (is /dev mounted?).

The error is misleading! /dev is mounted if you follow my instructions below. The actual problem, as I understand it, is that there is a discrepancy between the mounted device and the path to the chroot root. That's why I had you mount only the subvolume containing the root filesystem in the steps above. If you were not paying attention, you are not following the instructions step-by-step, you rebooted before this step or just came here directly looking for a solution to your problem about GRUB not installing look above for instructions on mounting the correct btrfs subvolume.

  • We need to prepare the chroot environment. The ESP must be mounted in the correct place and we have to bind system mount point for some special trees (most notably /dev). Moreover, we will copy the resolv.conf file to let the chroot environment have network access should it need it.
    mount /dev/sdXZ /mnt/boot/efi
    for i in /dev /dev/pts /proc /sys; do sudo mount -B $i /mnt/$i; done
    cp /etc/resolv.conf /mnt/etc/
    modprobe efivars
  • Finally we enter the chroot environment and install Grub in a way suitable for a removable device (see the first caveat above).
    sudo chroot /mnt
    grub-install -d /usr/lib/grub/x86_64-efi --efi-directory=/boot/efi/ --removable /dev/sdX

Now your external HDD is bootable. Reboot your computer, select it from the boot media selection of your UEFI BIOS and you're done!

201 comments

      • Hi Nicholas,
        Thank you very much for the clear instructions.
        I still have a couple of questions, IMHO related to the Dom's post above.
        1. From the original document, I got impression that the EFI partition should be created after the root partition (/dev/sdXY): "Resize the first partition on disk to have another 200 Mb of free space after it." (located in chapter "Create an ESP on the Ubuntu HDD"). But now you say that the EFI partition shall be the first one. I have created EFI after root partition according to the documentation, but my external 1Tb SSD is not visible among bootable ones, so I am thinking about moving things around and making EFI the first partition.
        2. "Bootrec /Fixboot" also throws an exception "Access is denied" for me. I think they may improve something recently (my current OS is Windows 10 1803, installed on Lenovo Y50) causing "access denied" as a side effect. As a temporary workaround, I have moved the "ubuntu" on a second place in boot order in UEFI, and that allowed Windows to start ok.
        • 1. You are right. You can create it anywhere on the disk. As long as it has the correct flags the UEFI firmware will be able to find it. I got confused with the MBR partitions. Long day, not enough coffee :)

          2. Last Windows 10 I tried this with was the April 2018 update. But I think that is unrelated. 10 second web search led to that: https://answers.microsoft.com/en-us/windows/forum/windows_10-update/windows-10-bootrec-fixboot-access-is-denied/747c4180-7ff3-4bc2-b6cc-81e572d546df?auth=1
  • Hey Nicholas,
    I loved this tutorial, and completely installed 17.04 ubuntu on my usb. But it's a bit slow, I tried running it on multiple computers, and it's pretty slow on each one. I was just wondering if You had similar issues maybe or is it because of the portable installation?
    P.S I used 3.0 usb flash drive, on 3.0 port and also tried it on i7 6th gen and 16GBs of RAM
    Thanks!
    • Yeah, it has happened to me. Most USB 3 flash drives (USB sticks) have a fairly decent read speed and a low write speed. In fact, they are only USB 3 at the connector level; the speed they get is not even high enough to saturate USB 2.

      Use a USB 3 connected SSD. That is, a regular SSD in an enclosure that connects to your computer via USB 3. This is really fast in most cases.

      I say most cases because I have an ADATA SSD which is blazing fast unless you connect it to a Microsoft Surface Book. There's a bug in the SSD's firmware and a quirk in Surface Book's firmware that makes performance abysmally slow.
  • Amazing tutorial!!

    I managed to clone my entire HDD to external drive and boot from it.
    Linux/Ubuntu should make Linux/Ubuntu to Go easier.

    Thank you.
  • Thanks. I'll try to repair boot from my usb ssd after kernel update. Possibly the tutorial will be helpfull. To avoid problems with windows boot you can try to install ubuntu from virtual box. Actually I installed ubuntu from virtual box (it abble to avoid your problems with windows boot).
  • Your instructions are clear, but I still ran into problems. Probably because I am newish to Linux. I am trying to create a portable Ubuntu Mate 18.04 install. All went well, until your last two paragraphs where you are creating and entering the chroot system. I got many errors I don't understand.

    mount /dev/sda1 /mnt/boot/efi
    failed, mount point does not exist, so I created it.
    for i in /dev /dev/pts /proc /sys; do sudo mount -B $i /mnt/$i; done
    again, failed with mount points not existing, so I created them and ran again
    The is no /bin
    cp /etc/resolv.conf /mnt/etc/
    This fails because the target is not a file (/mnt/etc does not exist). Then
    sudo chroot /mnt
    fails, because /bin/bash is not available. and
    grub-install -d /usr/lib/grub/x86_64-efi --efi-directory=/boot/efi/ --removable /dev/sdb
    fails with the following messages...
    Installing for x86_64-efi platform.
    grub-install: warning: disk does not exist, so falling back to partition device /dev/sda1.
    grub-install: warning: disk does not exist, so falling back to partition device /dev/sda1.
    grub-install: warning: disk does not exist, so falling back to partition device /dev/sda1.
    grub-install: error: disk `hostdisk//dev/sda1' not found.

    Help. Something has gone wrong, and I don't know how to proceed.
  • Sorted some of the problem...
    /boot only contained /boot/grub so copied the other files from the live system on /sda
    Then progressed to entering the chroot.

    The error when entering the chroot is a very miss-leading "chroot: failed to run command ‘/bin/bash’: No such file or directory", although /mnt/bin/bash does exist!

    It turns out that the libraries need3ed by /bin/bash are missing! In fact the directories are empty!

    I think I need to find out why my install failed to fill those directories, and yet produced no error message.

    Regards
    Ian
    • Help!
      I have now been through the tutorial twice, each time with no errors. (/dev/sda and /dev/sdb were getting swapped about before, and I did not notise). Did have to run the last but one paragraphs as su, but other wise no problems.
      However, no result.
      Now, when I boot off the USB drive, it starts from there, and finally ends up running the installation on the internal drive. Yes - I am sure - gparted shows which partition is mounted where.

      I am left wondering what has changed since the tutorial was written.
      Regds
      Ian
      • Nothing has changed. However, it is very important that the EFI partition is the first partition on your external drive, it has the correct filesystem type (FAT32, not VFAT) and flags (exactly two: BOOT and ESP). Also, did you update the external drive's /etc/fstab to point to the correct ESP partition? Finally, did you use the chroot environment to install GRUB?

        Considering your previous comments, you have either not created an ESP on the external drive, have not updated your /etc/fstab on the external drive or have not run grub-install through a chroot environment bound to the external drive. Nothing else justifies having the problems you describe.
  • great tut...thanks
    couple questions
    does UEFI need to be enabled in bios
    i have several configs such as:
    UEFI
    legacy
    UEFI and legacy
    legacy first
    UEFI first
    does the efi need to be primary, but can be located any where on disk such as 1,2,3...
    do you still need to repair windows bcd, i am on windows 7, this is for a windows 10 repair and i didn't seem to have a need to repair when i rebooted without/with external drive, windows 7 loads correctly
    but when i boot to Ubuntu all i get is black screen with flashing promt
    i do have this:
    mount /dev/sdc9 /mnt/boot/efi
    failed, mount point does not exist
    fstab added correct uuid, it was not listed in fstab, but /; /home; swap was
    noted: it was installed in sdd which was # commented out
    not btrfs is ext4
    sudo umount /media/ubuntu/01234567-89ab-cdef-0123-4567890abcde
    no media mounted
    sudo mount /dev/sdXY /mnt
    no mount point
    do i need to follow install grub2 it seems to be for btrfs?
    my biggest question is about the UEFI, should i change bios to UEFI and legacy and make the efi partition primary? is this gona affect my windows install?
    • Um, if UEFI is not enabled in your firmware then, clearly, you cannot have UEFI boot. You can have the EFI partition anywhere on disk. You still need to repair Windows BCD if booting into Windows doesn't work. No, I don't know how it works on Windows 7 -- I haven't used it since circa 2011. Regarding the mount failure, you should NOT be seeing a device name such as /dev/sdc9. I think you've edited /etc/fstab yourself or have an ancient Ubuntu distro from at least half a decade ago.
  • I intended to follow this tutorial, but when I saw "Fix Windows 10 boot" using a Windows system repair disk, it just dissuaded me from doing so. I know from experience that the less you touch to that huge labyrinthine system, the better you are.
    So, I went back wandering on the net and I found this : (MODERATOR NOTE: LINK REDACTED)
    In this tutorial, the most easy, simple and elegant solution is the unflag/reflag method : boot on the live USB, use GParted to unflag the internal drive's EFI partition, install Linux on the USB drive, then restore the internal drive boot flags.
    • If that works for you, great. However, my 2013 vintage Intel NUC's EFI firmware stores the EFI boot order in NVRAM. The only way I could fix it is what I described.

      In case it's not absolutely clear, THIS BLOG POST FROM JANUARY 2017 IS MY PERSONAL EXPERIENCE, ON MY 2013 VINTAGE INTEL NUC, INSTALLING A VERSION OF UBUNTU THAT'S LONG BEEN OBSOLETE. But yeah, please go on and make snide remarks about why I couldn't easily Google and include information that was published months or years AFTER my blog post. For crying out loud...

  • Couldn't Linux install / update the existing UEFI by installing GRUB2 to the Windows drive during installation, then if the external drive is connected and selected during a boot, you're good.
     
    If removable Linux is selected during boot but the removable drive isn't physically connected I would expect to get an error, but no biggie....  Just boot Windows or go find the USB drive and cable.......
    • That's one of the two reasons my instructions above tell you to create an EFI partition in the external drive and install GRUB2 on it. I don't want you to go hunting for that drive.
      The other reason is that I set out to create a portable installation, meaning that I wanted this to boot on any computer, not just the computer I used to install it. I have successfully used my removable SSD to boot the same Linux installation on five different computers over the last 2 ½ years 🙃
  • Greetings;
     
    So I was successful in that I was able to create the removable install of Linux on a USB3.0 1TB drive that boots selectively by pressing F12 at boot time, or otherwise the Laptop boots directly to Windows so, success there...
    I did run into a glitch where it initially worked, but after a shutdown it wouldn't boot.  When I went back in and looked at gParted, the efi partition was missing.  I simply re-created it and edited the fstab on the installed root partition to update the new UUID of the efi partition.  I did not:
    mount /dev/sdXZ /mnt/boot/efi
    for i in /dev /dev/pts /proc /sys; do sudo mount -B $i /mnt/$i; done
    cp /etc/resolv.conf /mnt/etc/ 
    nor did I:
    sudo chroot /mnt
    grub-install -d /usr/lib/grub/x86_64-efi --efi-directory=/boot/efi/ --removable /dev/sdX
     
    but it was working fine, survived shutdowns and reboots so happiness set in.
     
    However;
     
    Trying to bring that portable installation to my Tower PC though, but it won't boot, was wondering if you had a guess as to why that may be ?  The motherboard Gigabyte x99-ud3p rev 1.0  BIOS ver F23 which is only 3 years old.  Tried to update it but that's not working for whatever reason.
     
    I will say that on my TowerPC, the selecive boot option is simply listed 'Toshiba3.0 drive' but on the laptop where it works fine, the selective listing simply states Ubuntu...
     
    Great post, over my head for sure but very interested it getting it to work....
    • The problem is in what you did when your EFI partition disappeared.

      Since you never run the grub-install -d /usr/lib/grub/x86_64-efi --efi-directory=/boot/efi/ --removable /dev/sdX command your EFI partition does not have the boot loader in the fallback path. Therefore it only boots on the same device it was created on.

      1. Boot into Ubuntu first.
      2. Become root, i.e. sudo su
      3. Run the grub-install -d /usr/lib/grub/x86_64-efi --efi-directory=/boot/efi/ --removable /dev/sdX command where /dev/sdX is the device for your external hard drive.

      This will install the additional files required to make your drive bootable everywhere.

  • It works perfect.

     

    Interestingly enough, I performed this entire task on a laptop with an Intel graphics card.

    Also coincidentally did a clean install of the exact same distro and version on my tower which happens to have a Nvidia graphics card.

     

    My portable drive boots on either machine, no issues whatsoever.   No password required after booting, everything works fine.

     

    My clean install on the PC though, because of the Nvidia video card which causes havoc not unfamiliar to Linux users wheres it interferes with launching the desktop environment, especially if you want to boot into Linux without entering the user password...  You end up in an endless logon loop and are forced to workaround it..

     

    Question is, how can that be.   

     

    I will be looking for a way to install intel graphics drivers on that machine but, great post.

     

    Thanks for the time and effort....... 

    • It's been a while since I had an Nvidia graphics card. I can't tell you within any degree of certainty what is going on but I'd suspect that you're using the closed source Nvidia drivers. Have you tried using the open source ones? They work great unless you do heavy gaming. In the latter case you shouldn't be using a portable installation anyway :)

      FWIW you don't need to install Intel integrated graphics drivers. They are included in the Linux kernel since several years ago. Just booting your installation on a computer with a supported CPU – basically anything released this side of 2012 – will load the required kernel module.