Authors Top

If you have a few years of experience in the Linux ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

1. Overview

Sometimes, while running a script or program, we need to know if we are running it inside a container or not. This is because some commands are not relevant to the container environment. For example, if our script tries to change some OS kernel parameters using the sysctl command, it won’t work in a docker container.

In this article, we’ll talk about some ways to determine if we’re inside a Linux container or not.

2. Using Control Groups

We can identify if a process is running in a docker or LXC container from the control group of the init process:

$ docker run -it --rm --name myubuntu ubuntu:latest
[email protected]:/# cat /proc/1/cgroup
14:name=systemd:/docker/184977d6a721a33b0df3855d197b222496d4d049ed118e3dc5e42ca3d22377b5
13:rdma:/
12:pids:/docker/184977d6a721a33b0df3855d197b222496d4d049ed118e3dc5e42ca3d22377b5
11:hugetlb:/docker/184977d6a721a33b0df3855d197b222496d4d049ed118e3dc5e42ca3d22377b5
10:net_prio:/docker/184977d6a721a33b0df3855d197b222496d4d049ed118e3dc5e42ca3d22377b5
9:perf_event:/docker/184977d6a721a33b0df3855d197b222496d4d049ed118e3dc5e42ca3d22377b5
8:net_cls:/docker/184977d6a721a33b0df3855d197b222496d4d049ed118e3dc5e42ca3d22377b5
7:freezer:/docker/184977d6a721a33b0df3855d197b222496d4d049ed118e3dc5e42ca3d22377b5
6:devices:/docker/184977d6a721a33b0df3855d197b222496d4d049ed118e3dc5e42ca3d22377b5
5:memory:/docker/184977d6a721a33b0df3855d197b222496d4d049ed118e3dc5e42ca3d22377b5
4:blkio:/docker/184977d6a721a33b0df3855d197b222496d4d049ed118e3dc5e42ca3d22377b5
3:cpuacct:/docker/184977d6a721a33b0df3855d197b222496d4d049ed118e3dc5e42ca3d22377b5
2:cpu:/docker/184977d6a721a33b0df3855d197b222496d4d049ed118e3dc5e42ca3d22377b5
1:cpuset:/docker/184977d6a721a33b0df3855d197b222496d4d049ed118e3dc5e42ca3d22377b5

The above command displays the contents of the control group file for the process with PID 1. This is the initialization process for a Linux-based operating system. If some of the lines start with /docker or /lxc, the process is running inside the docker or LXC container. They’ll start with only / if the process runs in a host operating system.

The control group is a Linux kernel feature to control or track resource usage for a group of processes. Here, by resources, we mean system resources like memory, CPU, and IO devices. Linux represents these control groups as a pseudo-filesystem. The Linux containers share the kernel of their host. So, Linux uses a separate namespace for them in the control groups.

3. Existence of .dockerenv

Another popular way is to check the existence of the .dockernev file at the root location (/):

$ echo `[ ! -f /.dockerenv ]` $?

This command checks the existence of the file and prints 1 if it is there; otherwise, it prints 0. Docker creates this file while creating the root file system. The LXC drivers use this file to set up environment variables in a proper way.

But, as the LXC support is already removed from the recent docker versions, this file may not exist in the future.

4. Using CPU Scheduling Info

We can also check the scheduling information of the init process to find out if we are inside the container:

$ cat /proc/1/sched | head -n 1
bash (1, #threads: 1)

This command extracts the first line of the scheduling overview for the process with PID 1. For the Linux containers, it displays the command of the main process. For ubuntu or centos, it is bash.

However, if the process is not in a container, it displays init – the initialization process of the OS:

$ cat /proc/1/sched | head -n 1
init (1, #threads: 1)

In some Linux distributions like CentOS and Debian, the initialization process is systemd. So, for them, it shows system instead of init.

5. Using a Custom Environment Variable

If we are responsible for running the containers, there’s one easier and effective way. We may pass an environment variable while running our docker containers. This variable will denote the environment as a container environment:

$ docker run -it -d --name myubuntu -e OS_ENV=container ubuntu:latest
e4b26a308e0ab0ae6a976b7866004d9358920d195672f734701a02724494a8c6

Here, we pass the environment variable OS_ENV as a container using the -e argument. Now, we may start a new bash shell in the container and identify the environment through the variable:

$ docker exec -it myubuntu /bin/bash
[email protected]:/# echo $OS_ENV
container

For the host operating system, this value won’t be present. So, in any program or script, we can decide the environment based on the presence of this variable.

6. Conclusion

In this article, we’ve learned how to recognize if the current environment is inside a container or not. While discussing the different methods, we’ve also pointed out any downsides and in which scenario they might be applicable.

Authors Bottom

If you have a few years of experience in the Linux ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

Comments are closed on this article!