Bart Simons

Bart Simons

Thoughts, stories and ideas.

Bart Simons



.net .net 5 .net core Apache C# CentOS LAMP NET Framework Pretty URLs Windows Server WireGuard access log add analysis android api at the same time authentication authorization automate automation azure azurerm backup bash basics batch bootstrap build capture cheat sheet chromium chroot class cli click to close code coverage code snippet command line commands compile compiling compression containers control controller controlling convert cpu usage create credentials csv csvparser curl data dd deployment desktop detect devices disable diskpart dism distributed diy docker dom changes dotnet core drivers ease of access encryption example export file transfer files fix folders framework generalize getting started ghost gui guide gunicorn gzip html html tables icewarp igd imagex import inotify install installation interactive ios iphone itunes java javascript jquery json kiosk kotlin linux live load data loading screen lock screen loopback audio lxc lxd lxml macos manage manually message messages minio mirrored mod_rewrite monitor monitoring mstest mutationobserver mysql net 5 nexmo nginx no oobe node node.js nodejs not installing notification notifications object storage on desktop one command openssl owncloud parallels parallels tools parse perfect philips hue play port forwarding powershell processing ps-spotify python quick raspberry pi record rip ripping rsync rtmp save save data sbapplication scraping script scripting scriptingbridge scripts security send server service sharedpreferences sms songs sonos spotify spotify api spotlight ssh stack streaming streamlink studio sudo swarm swift sync sysprep system audio systemd tables terminal testing tracking tutorial twilio ubiquiti ubuntu ubuntu 18.04 ui code unifi unlock unsplash source upnp uptime usb tethering wallpapers wasapi website websites webview windows windows 10 without itunes without oobe workaround xaml

Ubuntu Linux chroot guide

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.

Getting started

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.

mkdir /mnt/server

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:

chroot /mnt/server

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:

source /etc/environment

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 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!

Bart Simons

Bart Simons

View Comments