Skip to main content

Poking around

In the previous section, we ran ls using the ubuntu:22.04. The result, if you run this on your computer with Docker installed, will look like this:

$ docker run ubuntu:22.04 ls
bin
boot
dev
etc
home
lib
lib32
lib64
libx32
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

If you run the same command in a container built from the fedora:39 image, you’ll get a different result (after any output about Docker downloading the image, if you’re using it for the first time):

$ docker run fedora:39 ls
afs
bin
boot
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

In some meaningful way, when you run a container based on these OS images, you’ve actually “installed” Ubuntu or Fedora on your computer. You can poke around inside a container by running bash inside, as long as bash is installed. You’ll need to pass the -i and -t flags to docker run to be able to interact with Bash (or whatever program you’re running in a container):

docker run -it ubuntu:22.04 bash

We can try, for example, installing and using NodeJS within this container:

$ docker run -it ubuntu:22.04 bash

root@f3b882ba5c8d:/# apt-get update
Get:1 http://archive.ubuntu.com/ubuntu jammy InRelease [270 kB]
... snip ...
Get:18 http://archive.ubuntu.com/ubuntu jammy-backports/universe amd64 Packages [32.6 kB]
Fetched 28.3 MB in 4s (6918 kB/s)
Reading package lists... Done

root@f3b882ba5c8d:/# apt-get install nodejs
Reading package lists... Done
... snip ...
Processing triggers for libc-bin (2.35-0ubuntu3.4) ...
Processing triggers for ca-certificates (20230311ubuntu0.22.04.1) ...
Updating certificates in /etc/ssl/certs...
0 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.

root@f3b882ba5c8d:/# node -e 'console.log("hello from ubuntu!");'
hello from ubuntu!

root@f3b882ba5c8d:/#

This won’t work in a Fedora-based container, though, because Fedora doesn’t use apt:

$ docker run -it fedora:39 bash

[root@d127fe6d8aa3 /]# apt-get update
bash: apt-get: command not found

If we use Fedora’s package manager dnf, though, it works fine, because Bash is able to find dnf inside that container and run it, allowing it to place its installed files into the container filesystem:

$ docker run -it fedora:39 bash

[root@209a7c01f113 /]# dnf install -y nodejs
Fedora 39 - x86_64
...snip...
Installed:
libuv-1:1.46.0-2.fc39.x86_64 nodejs-1:20.8.1-1.fc39.x86_64 nodejs-docs-1:20.8.1-1.fc39.noarch nodejs-full-i18n-1:20.8.1-1.fc39.x86_64 nodejs-libs-1:20.8.1-1.fc39.x86_64
nodejs-npm-1:10.1.0-1.20.8.1.1.fc39.x86_64

Complete!

[root@209a7c01f113 /]# node -e 'console.log("hello from fedora!");'
hello from fedora!

[root@209a7c01f113 /]#

Our host machine can even run an Ubuntu-based container and a Fedora-based container at the same time, side by side. Since Docker is intercepting and redirecting system calls from the running programs so that they’re only reading and writing in the virtual filesystem, the containers don’t much care about each other or about what’s going on on the host machine.

You can poke around as much as you’d like using a bash shell. When you install software or write files, everything happens inside the container. Once the program you ran in the container terminates (which, in the case of running bash interactively, happens if you press Ctrl+D or close the containing terminal), the container is considered “stopped”.

That container’s filesystem is still kicking around somewhere on your computer (as evidenced in docker ps -a), but if you docker run the image again, it’ll actually create a new container using the original image as a base. Nothing you did or installed earlier will be present in the new container.