The chroot system call changes the apparent root directory of a process. As the chroot(2) manual page puts it, chroot() “changes the root directory of the calling process to that specified in path. This directory will be used for pathnames beginning with /.” After the call, the process and its children resolve absolute paths relative to the new directory, effectively confined to a subtree of the filesystem. This idea of giving a process a restricted view of the filesystem is the earliest ancestor of the container, predating cgroups and namespaces by decades.
The chroot(2) page is emphatic that this confinement is not a security boundary. It warns that the call “changes an ingredient in the pathname resolution process and does nothing else. In particular, it is not intended to be used for any kind of security purpose, neither to fully sandbox a process nor to restrict filesystem system calls.” It then lists ways out: an attacker can exploit open file descriptors or directory moves, and the superuser can simply create a subdirectory, chroot into it, and walk back up with cd .. to escape.
Because chroot isolates only the filesystem view and nothing else, a chrooted process still shares the host’s process IDs, network, and users. Modern containers close those gaps by layering Linux namespaces and cgroups on top of the filesystem-isolation idea that chroot first introduced. Understanding chroot therefore explains both where containers came from and why filesystem isolation alone was never enough.