How to install Debian offline

When tinkering with old computers, there is little about an operating system quite as endearing as flexibility at install time.  The “Universal Operating System” is no slouch in this regard; the Debian installer will work quite happily from CD, DVD, USB drive,  PXE boot (my personal fav), and even a Windows executable.

But what if none of those is an option?  Suppose you’re stuck with a system with no optical media, no USB boot, no PXE boot, and no OS?  Can we get Debian on such a machine?

You bet we can!  


Of course, we can’t do it without some extra tools.  So here are some things we’re going to need:

  • A working system (laptop, desktop, netbook, etc) running some kind of Debian-based OS (Debian, Ubuntu, Mint, Mepis, etc).
  • A USB hard drive enclosure, or some way to mount the target computer’s hard drive on the working system.
  • A broadband internet connection
  • Probably a phillips-head screwdriver.
  • A distinct lack of discomfort with the command-line, or at least command-line package management.


Before we can install, we need access to the target system’s hard drive on our working system.  So open up the case and remove the hard drive (this is where the screwdriver probably comes in).

Hard disk enclosure

A hard drive in a typical USB enclosure, courtesy of Wikipedia

Next, we need to attach that hard drive to our working system.  Since we’re probably installing on an old computer here (read: PATA/IDE drive) and our working system is probably a newer computer (read: SATA connectors only) or laptop (read: no connectors), this is where the USB enclosure comes in.  These devices are cheap ($20-$30 US), so there’s no reason not to have one if you do this kind of tinkering often.

Once the drive is installed in the enclosure, hook it in to your working computer.

A critically important bit of information

At this point, we need to figure out which device name is assigned to the attached drive.  Depending on your distribution and desktop environment, and if there are any partitions on the drive, you may see a the device listed in your file manager or get a pop-up notification about new devices.  If not, you probably need to check dmesg, or run “sudo fdisk -l” to determine what the device name is.

If you have only one hard drive in your system, the device name is probably going to be “/dev/sdb”, but make sure you know absolutely for certain before moving on with this procedure.  Using the wrong device name will at best just not work, and at worst destroy data on your working system.

For the purposes of this article, I’m going to assume the device name is “/dev/sdb”.  If you see that in any commands, replace it with the device name you find here.

Install packages

The most important package we’ll need (which is probably not already on your system) is debootstrap.   It should be readily available in your Debian/Ubuntu repositories, so go ahead and install it now.  Depending on what tools you prefer for partitioning drives, you also might want to grab gparted while you’re mucking about in the package manager.


 Step 1: partition and format the drive

Our first step is to create a root partition on this drive and format it appropriately.  You can use any partitioning tool you feel comfortable with, such as fdisk or cfdisk; but if you’re new to this you might want to stick with friendly, graphical gparted.

Gparted blank disk

Gparted with a blank disk

Depending on the size of your disk, and how much you plan to install on this system, you want to create a root partition of at least 3 GB and at most 20 GB.  If you’ve no interest in making a separate home partition or dual-booting this computer, go ahead an use the whole drive minus a GB or so for swap.

Choose ext4 for the formatting (or your favorite filesystem, if you care about such things), and then make sure to create an appropriately-sized swap partition.

My partitioned drive is shown here (click for larger image):

Partitioned Drive

This is the partitioned drive. Note the "flags" field


One important note:  it’s critical here to set the boot flag on the root partition.  Without this, some machines just won’t boot.  In gparted, just right-click the partition after it’s been created and select “manage flags”.  Then check the “boot” option and apply.

Step 2: create the base install

Now that our drive is formatted, we need to put some data on it.  Most of what follows will need root priveleges, so either log in as root (if your distro will do that), or prepend all these steps with sudo.

  1. Mount the drive.  I’m mounting it to /media/sdb1 here:
    mkdir /media/sdb1 && mount /dev/sdb1 /media/sdb1
  2. CD to the mount point.  Now we’re going to run the debootstrap command.  This cool little command downloads and sets up a nearly-complete install of Debian in any directory we specify.  We can specify any release or architecture as well.  Here we’ll specify the stable release on an i386 architecture:
    debootstrap --arch=i386 stable /media/sdb1/

    This usually take a while to run, depending on connection speed and other factors.

  3. The man page for debootstrap lists a ton of other options, such as options to use certain templates, use local APT mirrors, exclude or include a list of packages, etc.  Read through it as you wait for the system to finish downloading.   When debootstrap finishes, move on to the next step.

Step 3: install a kernel and bootloader

The debootstrap command creates a base install, but doesn’t actually install a kernel or bootloader.  This may seem odd, but there are reasons for it I won’t go into right now.  Not a problem, though, we just need to install them.


The first thing we need to do is get into the new environment so we can run commands in it.  This is where the chroot command comes in.  If you’ve never used chroot before, it’s a little brain-bending.  What we’re going to do is change the root of our shell to a new directory, so that whatever commands or  actions we take are done as if this new directory is the root of the filesystem and everything above it is invisible.

Of course, that also makes certain important directories like /proc, /dev, and /sys unavailable, so we need to deal with that too.  The following sequence of commands takes care of all that (run as root, of course):

cd /media/sdb1
mount --bind /proc proc
mount --bind /dev dev
mount --bind /sys sys
chroot .

You might notice at this point that the prompt has changed, and now you’re in your new environment. You can verify this by examining /etc/issue (to view the OS & release) or /boot (which should be empty). You can now run aptitude to install packages.

Installing packages

Let’s start with our kernel and bootloader:

aptitude update
aptitude install linux-image-486 grub-pc

Make sure you install grub to the correct device! In my case this was /dev/sdb, of course. Also, note that I installed the 486 kernel image; if your target computer is a Pentium II or newer, you can install the 686 kernel instead. If you decided to do a different architecture (64 bit, for example), substitute the appropriate kernel.

At this point, you can use aptitude to install any other software you want on the system; if the target hardware is unlikely to have network capability, this would be a good time to do so. Also, unless you’re certain there are free drivers for all the hardware in the target system, you might want to take a moment to install the debian non-free firmware packages:

    1. Open /etc/apt/sources.list in nano or vi.  You should see a single line containing the location of the repository mirror.
    2. At the end of the line after “main” add “non-free contrib” separated by spaces.
    3. Save and close the file, then run:
      aptitude update && aptitude install firmware-linux-nonfree

Step 4: Final fixes and tweaks

Before we can reboot into our glorious new system, there are a few things we have to set up.  You’ll need to still be in the chroot environment for these things, so if you exited out, get back in and do the following:

Set root password

Root’s going to need a password, otherwise there’ll be no logging in to this system when it boots.  So as root (which you are by default when you chroot), issue the passwd command and follow the prompts to set  the password. If you wish, you can use the adduser command at this point to add non-root users to the system.  Might not be a bad idea.

Create fstab

This is (potentially) one of the trickier parts of the process: creating the /etc/fstab file.  Fortunately, you can probably just copy what I have below and 99% of the time for a single-disk system it’s going to work just fine, so open the chroot’s /etc/fstab in your favorite text editor and paste this in:

#This mounts the root partition
/dev/sda1   /  ext4   defaults,noatime 0 1

#This is the swap partition
/dev/sda2   none swap  sw 0  0

This assumes you followed the same partitioning scheme I did above, with the first partition for the OS and the second for swap. If not, adjust accordingly. Do take note that I specified “sda” here instead of “sdb”; once the drive is put back in the other system, it will take on the name “sda” since it will likely be the first and only drive detected.

Exit and cleanup

We should be done with the chroot at this point, so get out of it by typing “exit”. Then clean up with the following commands:

umount /media/sdb1/proc
umount /media/sdb1/sys
umount /media/sdb1/dev
umount /media/sdb1

Step 5: test

At this point, you should be ready to roll with the install. If your working system has adequate specs for virtualization, you might want to test the install before you go to all the trouble of putting the drive back in the target computer.

Qemu is a good, simple virtualization tool that’s readily available in any Debian-based OS. If you have it installed, test your installation with this command (must be run as root/sudo):

qemu -hda /dev/sdb

If all has gone well, you should soon see a GRUB screen, followed shortly by a login prompt. If it looks good and logs in, you’re ready to go!

Step 6: Humpty-Dumpty back together again

If you’ve made it this far, put that drive back in the original computer and boot it up. If you’ve been trying this in real life, let me know how it worked out for you!

Leave a Reply

Your email address will not be published.