How to determine if a process runs inside lxc/Docker?
Solution 1
The most reliable way is to check /proc/1/cgroup
. It will tell you the control groups of the init process, and when you are not in a container, that will be /
for all hierarchies. When you are inside a container, you will see the name of the anchor point. With LXC/Docker containers, it will be something like /lxc/<containerid>
or /docker/<containerid>
respectively.
Solution 2
Docker creates a .dockerenv
file at the root of the directory tree inside container. This can be seen by performing an ls -la /.dockerenv
to show that it is created on container startup.
You can run this script to verify:
#!/bin/bash
if [ -f /.dockerenv ]; then
echo "I'm inside matrix ;(";
else
echo "I'm living in real world!";
fi
MORE:
Ubuntu actually has a bash script: /bin/running-in-container
and it can return the type of container it has been invoked in. Might be helpful.
Don't know about other major distros though.
Solution 3
On a new ubuntu 16.04 system, new systemd & lxc 2.0
sudo grep -qa container=lxc /proc/1/environ
Solution 4
A concise way to check for docker/lxc in a bash script is:
#!/bin/bash
if grep -sq 'docker\|lxc' /proc/1/cgroup; then
echo "I am running on Docker."
fi
Solution 5
Handy Python function to check if running in Docker:
def in_docker():
""" Returns: True if running in a Docker container, else False """
with open('/proc/1/cgroup', 'rt') as ifh:
return 'docker' in ifh.read()
Related videos on Youtube
Mate Varga
Updated on August 03, 2022Comments
-
Mate Varga almost 2 years
Is there any way to determine if a process (script) runs inside an lxc container (~ Docker runtime)? I know that some programs are able to detect whether they run inside a virtual machine, is something similar available for lxc/docker?
-
mah over 10 yearsIt might seem pedantic, but it would be best to rephrase your question to describe a problem you're having and ask how to solve it -- without that, the question stands a higher chance of being closed. In many cases it's difficult to make that change but in yours it wouldn't be hard to simply rephrase if you wish.
-
Scott Stensland over 7 yearsthere is an interesting response when issuing this command while inside a container : uptime
-
-
Andy over 8 yearsdocker now uses
docker
instead oflxc
in those paths -
Draco Ater about 8 yearsThis one works not only for docker (I didn't check that), but more importantly for lxd/lxc containers (checked), where
/proc/1/cgroup
does not allow you to detect that. -
Draco Ater about 8 yearsDoes not work for lxd/lxc containers, but stackoverflow.com/a/20010626/170230 does.
-
Max Murphy almost 8 yearsOn Debian
/bin/running-in-container
is provided byupstart
. With the transition to systemd it might go away. I hope not - it sounds useful! -
Alexander Mills over 7 years"on top of directory tree", what does that mean? where is that?
-
Alexander Mills over 7 yearscan you edit the answer with code instead of pseudocode? "container=lxc" ?is not proper anything. do you mean something like if [[ "lxc" = "$container" ]] ?
-
Alexander Mills over 7 yearsI mean...it is weird, usually env variables are in all caps, so looking for some precision here
-
abourget over 7 years@RomanTrofimov LXC/Docker doesn't either. What a funny comment.
-
BrianV about 7 yearsDepending on the OS, "init" might need to be replaced by "systemd". More information on systemd here.
-
Lucas over 6 yearsDoesn't work with
virt-what
version 1.14-1 on Ubuntu 16.04. Needs patch. -
Venkateswara Rao over 6 yearsIt does not work in centos 7 as well. When I run in my host machine it says docker. Looks like systemd is running as process id 1
-
Govind Kailas over 6 years@VenkateswaraRao - This must be run inside the container. The intent is to find out if you are inside a docker container or not.
-
Gert van den Berg over 6 years@GovindKailas: The problem is that this assumes that the normal PID one is
init
, which is not true onsystemd
orlaunchd
based systems... -
cjs over 6 yearsWith later versions of systemd it looks like you can't rely on process 1 using
/
for all cgroups; on my Debian 9 system (systemd 232) only three of the ten cgroups (3:cpuset
,4:perf_event
and7:freezer
) are at root; the rest are under/init.scope
. That said, I think that searching that file for:/docker/
is probably the most reliable heuristic at the moment. -
MillerGeek about 6 yearsYes, but the point wasn't the name of the init process, the point was the process number.
-
MillerGeek about 6 yearsThis seems to only work on Docker. In an LXC container It's returning Systemd PID 1
-
Gert van den Berg about 6 years@SamThomas: launchd, upstart, Solaris SMF, systemd, Sys V style init, BSD style init (these two and some others might call their PID 1
init
though), OpenRC, initng, runit. See here. Most modern Linux-based systems would usesystemd
, some older ones, upstart.... All modern OS X systems would uselaunchd
-
toriningen almost 6 yearsNo
docker
binary is available from inside of container, obviously. -
shalomb almost 6 yearsUmm, this would fail in situations (e.g. gitlab docker-in-docker) where the controlling container has
docker
and access to the hosts' docker socket. -
stevokk almost 6 yearsThanks for this module, seems to be a couple of open fixes pending - are you still maintaining this?
-
Dave over 5 yearsOthers have pointed out that checking
.dockerenv
is not recommended -
okutane over 5 yearsFor me .dockerenv is more like edge of the world from "13th floor".
-
JJC over 5 yearsImportant Note! This does not appear to work when the container is running in kubernetes. Instead, replace the last line with 'kubepod' in place of 'docker'. (Or, put in an "or" statement that checks for both ;))
-
rypel over 5 years
grep 'docker\|lxc' /proc/1/cgroup
works for me on Docker 18.09. -
Archimedes Trajano over 5 years
docker run alpine env
does not give anything that looks like that variable -
rubicks about 5 yearsHere's a tighter (extended) regex that assumes a
sha256
hash in thebasename
position:grep -Eq '/(lxc|docker)/[[:xdigit:]]{64}' /proc/1/cgroup
-
Boop almost 5 yearsCombining two answers for increased robustness:
if [[ -f /.dockerenv ]] || grep -Eq '(lxc|docker)' /proc/1/cgroup; then echo True; else echo False; fi
(Though I don't know if cgroup file is in every linux; You might whant to add extra checks) -
rookie099 almost 5 yearsIt's
kubepods
I guess. -
Gab almost 5 yearsNot working for me. Host Ubuntu 19.04, guest Ubuntu 18.04 using LXC privileged container. /proc/1/cgroup does NOT contain the lxc string.
-
Benjamin Kircher almost 5 yearsNote: testing for .dockerenv works only if the runtime is docker daemon. If you are using podman or something else this fails.
-
splintercell over 4 yearsThis didn't work for me on Mac based docker container. Returns empty. Docker version 2.1.0.1 (37199).
-
splintercell over 4 yearsThis one did:
def is_non_docker(): return os.path.exists('/proc/1/cgroup')
as per the accepted answer here stackoverflow.com/questions/20010199/… -
sorin over 4 yearsReturns 1 on both.
-
Leonardo Da Vinci about 4 yearsyeah, you're right, of course there isn't ^^. I got the wrong interpretation about the question back at the time when I read it. Thank you, Shalomb.
-
Jonathan Hartley about 4 yearsThis works for me on Ubuntu focal 20.04. None of the answers above this point did.
-
Jan Hudec about 4 yearsIt's now returning 1 in docker as well. It is usually
sh
and notinit
there, but it may be almost anything in either. -
Jan Hudec about 4 yearsYou get a Useless Use Of Cat Award. And Useless Use Of Subprocess one.
-
Timmmm about 4 yearsYeah this is a whole new level of unnecessary
cat
! Nice one :-D -
blakev about 4 yearsYou're right, I'll update it the answer even though it's still not all-encompassing. @JanHudec
-
shalomb about 4 yearsUnder docker, this is no longer the case -
bash-5.0# cat /proc/1/sched bash (1, #threads: 1)
-
Meir Gabay almost 4 yearsIt's Aug 2020 and
/.dockerenv
is available on ubuntu:20.04 and alpine:3.12, so I'd say that's definitely the best answer -
Daniel Griscom over 3 yearsUbuntu 18.0.4 doesn't have
/bin/running-in-container
. -
Treviño over 3 yearsNot sure this is correct when using a schroot instead, in such case the cgroup is still the same
-
Peter V. Mørch over 3 yearsInterestingly, inside docker on windows,
virt-what
reportshyperv
, just as my WSL2 bash shell does. -
oNaiPs about 3 yearsThanks @DanielGriscom that looks way better.
-
Alek about 3 yearsThanks! it works for lxc! Can you please explain why '-a' is needed? Isn't
grep -q container=lxc /proc/1/environ
enough? -
erik about 3 yearsThis didn't work when my container was running within kubernetes.
-
teknopaul about 3 yearsThis does work in Ubuntu 20.04, it greps for "lxc" in /proc/1/environ
-
teknopaul about 3 yearseven systemd os (Ubuntu) call /lib/systemd/systemd /sbin/init when its pid 1
-
Hi-Angel almost 3 yearsWorth adding that the same way wouldn't work for detecting
chroot
, because if/proc/
is mounted inside chroot thecgroup
gonna have same content. There's a different way with/proc
, but apparently no unified way to detect both chroot and docker at the same time. -
Adam Azarchs almost 3 years
/proc/$$/environ
separates environment variables with null bytes. Without-a
, this passage from the man page applies: > By default, TYPE is binary, and grep suppresses output after null input binary data is discovered -
Brett Sutton over 2 yearsOn my docker image: cat /proc/1/cgroup 0::/ so doesn't work.
-
Henrique Capozzi over 2 yearsI'm running fedora 34 and the output of /proc/1/cgroup inside a container ir 0::/ If the linux distribuition relies on systemd a possible way is to check if the contents of /proc/1/comm are not 'systemd'
-
TommyD over 2 yearsFYI the echo command should use double quotes due to the single quote in "I'm"
-
Jeff about 2 yearsThis module is no longer maintained. Additionally, a Node.js module that detects non-Docker container environments is needed.