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!

187 thoughts on “Making a portable full installation of Ubuntu on a USB HDD”

  1. Wednesday, 15 November 2017 11:39
    Hi. I would like to notice that in the 'Fix windows 10 boot' when recreating the BCD store. A '/f' flag is missing from the original instructions, and the RIGHT version should be:

    bcdboot c:\Windows /l en-us /s z: /f All

    Otherwise, very bad things happen... :*
  2. Saturday, 18 November 2017 23:14
    Wow! I just finished this procedure, and it works. It did take several hours for me to complete it because I and just getting started with Ubuntu Linux. One thing which took me a while to figure out was that I had to change directory to "/" before the "cp /etc/resolv.conf /mnt/etc/" would work. This was located in the second to last bullet point in the procedure. Question: now hard would it be to change to Linux Mint if I want to do that? Do I have to start all over at the beginning of the procedure? Many thanks for the detailed procedure! No way I would have done the installation in this manner without the excellent procedure.
    1. Wednesday, 22 November 2017 09:54
      Mint is not an official flavor of Ubuntu IIRC, meaning that you can't just apt-get install something and be done with it (as you'd do with Kubunty, Xubuntu, Mythbuntu and other official flavors). So in this case, yup, you'd need to start over.
  3. Saturday, 18 November 2017 23:30
    Oops: I didn't notice the last comment about the missing "/f" flag. Is this comment validated by N.K. Dionysopoulos? Can I fix it now, after already booting from my external ssd?
    1. Wednesday, 22 November 2017 10:00
      It's not a flag, it's a selector. It tells bcdboot which boot loader (formware) technology to use: BIOS (MBR) or UEFI. The default value is auto-detect. If you are running it on a UEFI-capable computer it will default to UEFI. I would NOT use /f All unless you have a valid reason to want to boot Windows using legacy boot. Since this guide talks about UEFI I think it's safe to assume you'd never want to do it. Well, if you have explicitly enabled legacy boot and your firmware doesn't fall back to UEFI if there's no MBR record then, yes, you will need to use /f All - which I believe is what happened to our anonymous friend above. For most other people, though, this would be an unnecessary step with potential complications.

      TL;DR: If it ain't broken don't fix it.
  4. Wednesday, 22 November 2017 08:22
    Hi Nicholas, GREAT job!... but I need a little help. I'm trying to follow your guide using my mac and installing ubuntu on my external HD. Do you think will be the same? Is your guide usefull for Apple's too? Thank you in advance.
    Best regards.

    Andrea.
    1. Wednesday, 22 November 2017 10:08
      It's actually simpler with Macs since all you need to do is reset the PRAM after unplugging the external SSD. The Mac's firmware prioritizes booting macOS from the main partition of the primary disk. I would bet that you have a MacBook Pro / Air which means that macOS will prioritize booting from its internal SSD. Therefore you don't need to do the whole restore Windows bootloader dance. You still need to follow the instructions to reinstall the Linux bootloader in a way that makes it into a portable boot disk.

      That said, running Linux on a Mac is a pretty hectic experience since Apple won't release any drivers or specifications for its proprietary hardware implementations, of course. The least of my worries had been the keyboard. Using an external keyboard or mapping keys the hard ways had helped a lot. The major problem I had with it is that many built-in devices won't work. You may get iSight working if you have an old Mac. Forget about getting the SD card reader working. If you have a 15" with discrete graphics you're in for a world of pain (I have an old 2011 MacBook Pro with AMD discrete graphics that took serious boot parameter tinkering to get it booting and nope, discrete graphics won't work at all). The touchpad was recognized as a 2 button mouse - no multitouch. External touchpad was simply not working. Magic Mouse was recognized as a very non-magical 2 button mouse. It couldn've been worse.
  5. Thursday, 23 November 2017 22:37
    I do have a problem: My system won't boot when I remove the external ssd. I get The message: GNU GRUB Version 2.02~beta3-4ubuntu7. This is followed by several more lines That begin with "Minimal BASH-like line editing is supported. ..." followed by "grub _". Apparently, I did something wrong. I am using a computer with Windows 10 installed. I did execute the line: "bcdboot c:\Windows /l en-us /s z: All" (it is possible that I entered /1 instead of /l after windows). I got a message that indicated the command didn't work - don't remember the wording. Then, I executed the "bootrec /RebuildBcd" command. It seemed to work; I got no message after I executed it. Then, I continued with the remaining instructions. My system works fine with Ubuntu, but will not boot to Windows 10. Can you suggest how I should fix this, please. Thanks, Jim Mc.
    1. Friday, 24 November 2017 08:17
      My only logical conclusion is that you accidentally missed something in the "Fix Windows 10 boot" section of this guide. It's the trickiest bit for getting this to work. It took me two days to figure out how to fix the same problem you had and that's how I fixed it. Then I started over and redid everything from scratch just to make sure that my guide is accurate (yup, it is). If, however, you miss any of the steps, even those which look inconsequential (like changing to the ESP directory before running bcdboot) can throw the entire process out of whack.

      So, my best advice is to print a hardcopy of this guide, or open it on a tablet / phone / whatever, and retry the Fix Windows 10 Boot section's instructions very carefully, without skipping anything. I know it sucks and it's slow. Sorry :(
  6. Monday, 04 December 2017 04:59
    I finally got back to this, and it works. However, to boot to Windows with the HDD removed, it is necessary to go into setup and change the first boot device to "windows Boot Manager", save changes, and exit; otherwise it hangs. I thought it would automatically skip Ubuntu and boot into Windows, but it doesn't. Thanks for the procedure and the help. Jim
    1. Monday, 04 December 2017 09:57
      Boot into your UEFI setup (what we used to call "BIOS" in the olden days) and change the boot order. Set Windows first.
  7. Monday, 04 December 2017 22:23
    With "Windows boot manager" as the first boot device, it always boots into windows, and I don't have an option to boot into Ubuntu without going into setup and changing the first boot device to Ubuntu. Not a big issue, just a small annoyance that I can deal with. If Ubuntu is set to boot first, I do have the option to choose Windows, but if I then disconnect the SSD, I have to go into setup and change the first boot device to windows. It would be a tad more convenient if it would just skip ubuntu when the SSD is disconnected, or give the option to choose Windows or Ubuntu when the first boot device is set to Windows. I'm not complaining, just making a fine point.
  8. Wednesday, 13 December 2017 16:02
    I've seen other HOWTOs that suggest an alternate process, which *sounds* simpler: (1) set the BIOS boot sequence to boot from a USB device, (2) shut down compuyer and disconnect internal hard disk(s), (3) boot Ubuntu from USB flash drive, (4) install Ubunti form flash drive to portable hard disk. (Since the only i8nstalled or available hard disk is the portable one, it will be installed as single boot without altering the disconnected internal drive.) Any comments./comparisons on this, or any additional steps this would require to insure compatibility with UEFI? I am carrying out the install on an older BIOS computer, but want to be able to use the portable hard disk to boot UEFI machines.
    1. Wednesday, 13 December 2017 19:16
      First of all you need to disconnect the internal hard drive which may not always be feasible or convenient. It’s been a decade since I last run a midi tower with a side panel missing and don’t get me started on my Slimbook and its abundance of screws.

      Secondly, most computers will freak out as soon as you unplug the USB HDD because the only and default boot disk disappeared.

      Thirdly and MOST important: what you end up with IS NOT a portable hard drive! It will only boot on the computer you installed it on and only if you don’t mess with the UEFI boot order. In other words you’ll still have to press F9 to choose which OS to boot on the original computer and your HDD cannot be used anywhere.

      I don’t know what the other people claim, but it doesn’t look like they tried their own instructions. I did and I was disappointed. So I spent two days, found instructions that work, wrote them down, formatted my HDD again, tried them again and only then did I hit publish.

      Basically, if you see something written on this blog I have tried and use it myself. I don’t do useless brain fart dumps for page views. That’s why my blog posts are so far in between :)

  9. Thursday, 28 December 2017 02:12
    Thank you for these instructions. I use W8 on my notebook but having an Ubuntu installation available on my notebook would come in handy for me because I'll be away from my desktop with Ubuntu for over a month soon. I don't want to make any changes to my notebook's HDD with W8 installation, so I thought running Ubuntu from an external drive would be the best.
    Before I start (well, I still haven't got any SSD yet, so I can't really start yet), I would like to confirm one thing. Does it mean that if I follow these instructions, I can create an installation of Ubuntu and make it bootable on some PC, and then when it's done take the SSD and use it with a different PC if I plug it in and change the booting priority?
    If it's possible I'd rather try to make the external SSD Ubuntu installation on my old W7 notebook so that it wouldn't matter that much if something got screwed up during the part where you have to fix Windows booting. But I'd like to use it with my regular W8 notebook when it's done.
    1. Thursday, 28 December 2017 06:32
      Hello Jan,

      Yes, you understand correctly. You can create the bootable drive on any computer and have it boot on any other computer just fine. Modern Linux is very smart about automatically detecting hardware and loading the appropriate drivers. I've tested that by booting my portable Ubuntu installation off a MacBook Pro when I had to boot the Intel NUC into Windows but still needed to use my Ubuntu installation at the same time :)
  10. Saturday, 30 December 2017 13:57
    Can we unplug the internal disk drive that contains windows to avoid the fix part?
    1. Saturday, 06 January 2018 16:09
      Maybe, but I wouldn't count on it. Installing an operating system may change the default EFI boot entry in the system. Part of the solution addressed that issue.
  11. Sunday, 31 December 2017 15:16
    Thank you for these instructions. However im running into a boot issue. when the dual boot screen appears i select Ubuntu and then it seems as though it want to load the OS but then i get a screen which is black and white and list some boot details (similar to below). any thoughts? also, the hardware is a surface pro 3. thanks

    [ 1.65621] 18042: cant read CTR while initializing 18042
    /dev/sdb1: clean, 187936/2437776 files, 1117662/971276 blocks
    [FAILED] failed to mount /boot/efi.
    See 'systemctl status boot-efi.mount' for details
    ..........


    1. Saturday, 06 January 2018 16:12
      The first line is not an error, see https://unix.stackexchange.com/questions/379834/linux-throws-error-cant-read-ctr-while-intializing-i8042

      The second line means that Ubuntu can't mount the EFI partition. At this point it should be throwing you to a shell. As told, run systemctl status boot-efi.mount to see why the mount failed. This should give you more clues as to what's going on. 80% of the time spent on the computer doing something new is troubleshooting - but that's we get to learn something new, right? ;)