One of the cool things about Linux is that you can change the root directory to a mounted file system, and that is exactly what chroot does. I use it a lot in combination with my Linux VMs: I have a lot of them and updating them can be a long boring task. So why would you not automate this process? In this article I am going to show you how it's done.
So, first things first - my environment is setup with two disks in a virtual machine:
/dev/sda - this is the disk with my Arch Linux installation /dev/sdb - this disk contains a freshly installed Ubuntu server environment /dev/sda is the boot disk, /dev/sdb is the disk we are going to chroot into.
Once booted into Arch Linux, you start by creating a directory in your /mnt folder - this is where we will mount the needed partitions of /dev/sdb. You do that with the mkdir command of course.
You can now mount the root partition on this folder. Please note that any other partitions might also need to be mounted. You can check this by running
fdisk on your disks just like in this screenshot:
Mounting partitions and other things related to that
As you can see, I also have an EFI system partition that needs to be mounted (since this is configured to boot in UEFI mode). So to wrap things up - I use the following commands to mount my partitions:
mount /dev/sdb2 /mnt/server mount /dev/sdb1 /mnt/server/boot
So far so good. Let's move on to the next thing, which is mounting folders that contain needed device files:
mount -t proc /proc /mnt/server/proc mount -o bind /sys /mnt/server/sys mount -o bind /dev /mnt/server/dev mount --make-rslave /mnt/server/sys mount --make-rslave /mnt/server/dev
If pseudo-terminals are required to be accessible from within the chroot environment (you need them if you plan on using apt within a ubuntu chroot), use this command to mount that as well:
mount -o bind /dev/pts /mnt/server/dev/pts
And because the Ubuntu server installation runs from /dev/sda in standalone mode (with that I mean when Ubuntu is running normally without chroot), you have to 'redirect' that as well:
mount -o bind /dev/sdb /mnt/server/dev/sda
Now comes the fun stuff
You are now ready to enter the chroot environment with the command:
If the last command doesn't return any weird errors or warnings, then you are good to go! The first thing you should do now is sourcing the path environment variables:
This is mandatory because the path variable is not automatically set upon entering the chroot environment. The next thing is double checking if /dev/sda REALLY is the disk where Ubuntu normally runs on:
As you can see, /dev/sda is what /dev/sdb is on the Arch Linux environment, so the redirect works! Now you can run whatever you want. I used
apt update && apt -y upgrade and that worked fine, after fixing one issue: /etc/resolv.conf was a broken symlink inside the chroot environment so I removed it and created it again as a normal file. After putting
nameserver 220.127.116.11 in that file, DNS resolving worked!
Please note that the issue that I have mentioned above might not occur on your system. It might also be that you have a lot more problems than me, or that you break your system (always make backups before any maintenance scenario).
Cleaning things up
You can use the exit command in your terminal to return to your 'real' Linux environment. From here, you can unmount everything with one simple command:
umount -f /mnt/server
I got a message 'target is busy', if you get the same message: a reboot will solve this and the chrooted disk will not be mounted anymore of course.
Again, because your experience with chrooting may vary: what are your experiences with chroot? Please share your problems and/or solutions in the comments. I am sure that it can be helpful for other readers.
Thank you for reading, and stay awesome!