How does one detect if one is running within a docker container within Python?
Question:
I was trying to find out if my script was running inside a docker container or not within the python script.
Something like:
if inside_docker():
do_stuff()
else:
do_some_other_stuff()
to do this the only hacky way I found out how to do it is that I can inspect the hostname (with platform.node()
) and if the hostname is not the same as my computer then its not in docker (since hostnames docker are some weird hash or something).
Instead I was thinking something a bit more programatic as follows:
- first detect docker with
cat /proc/1/cgroup
- then compare the name those hierarchies with the docker id/hash.
Something like:
from subprocess import call
import platform
hash = call('cat /proc/1/cgroup')
hostname = hostname = platform.node()
docker_boolean = does_hostname_contain_docker_hash(hash, hostname) # true or false
I thought something like that would work but I can’t even get to call the cat /proc/1/cgroup
without an error. If I am in docker I get the error:
>>> from subprocess import call
>>> call('from subprocess import call')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/subprocess.py", line 523, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.7/subprocess.py", line 711, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1343, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
any ideas how to fix that?
as a side node I was thinking of making my solution portable but docker is suppose to be portable already so if I am in docker this should always work…
Answers:
I think the preferred way to do this is through environment variables. If you’re creating your Python app from a Dockerfile, you could specify the ‘ENV’ directive:
https://docs.docker.com/engine/reference/builder/#env
Dockerfile:
...
ENV AM_I_IN_A_DOCKER_CONTAINER Yes
which could then be read from your app with something like:
python_app.py:
import os
SECRET_KEY = os.environ.get('AM_I_IN_A_DOCKER_CONTAINER', False)
if SECRET_KEY:
print('I am running in a Docker container')
import os, re
path = "/proc/self/cgroup"
def is_docker():
if not os.path.isfile(path): return False
with open(path) as f:
for line in f:
if re.match("d+:[w=]+:/docker(-[ce]e)?/w+", line):
return True
return False
print(is_docker())
The is-docker package for npm suggests a robust approach, ported here to Python 2.6+:
import os
def is_docker():
path = '/proc/self/cgroup'
return (
os.path.exists('/.dockerenv') or
os.path.isfile(path) and any('docker' in line for line in open(path))
)
Similar to the is-docker package for npm, I’ve created jaraco.docker with an is_docker
function. For Python 3.5+ with that package installed:
from jaraco.docker import is_docker
if is_docker():
print("In docker")
If you are using nodeJS
is-docker is a popular npm packages to accomplish this.
import isDocker from 'is-docker';
if (isDocker()) {
console.log('Running inside a Docker container');
}
In Python 3.4+ this should work nice
from pathlib import Path
def is_docker():
cgroup = Path("/proc/self/cgroup")
return Path('/.dockerenv').is_file() or cgroup.is_file() and cgroup.read_text().find("docker") > -1
I was trying to find out if my script was running inside a docker container or not within the python script.
Something like:
if inside_docker():
do_stuff()
else:
do_some_other_stuff()
to do this the only hacky way I found out how to do it is that I can inspect the hostname (with platform.node()
) and if the hostname is not the same as my computer then its not in docker (since hostnames docker are some weird hash or something).
Instead I was thinking something a bit more programatic as follows:
- first detect docker with
cat /proc/1/cgroup
- then compare the name those hierarchies with the docker id/hash.
Something like:
from subprocess import call
import platform
hash = call('cat /proc/1/cgroup')
hostname = hostname = platform.node()
docker_boolean = does_hostname_contain_docker_hash(hash, hostname) # true or false
I thought something like that would work but I can’t even get to call the cat /proc/1/cgroup
without an error. If I am in docker I get the error:
>>> from subprocess import call
>>> call('from subprocess import call')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/subprocess.py", line 523, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.7/subprocess.py", line 711, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1343, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
any ideas how to fix that?
as a side node I was thinking of making my solution portable but docker is suppose to be portable already so if I am in docker this should always work…
I think the preferred way to do this is through environment variables. If you’re creating your Python app from a Dockerfile, you could specify the ‘ENV’ directive:
https://docs.docker.com/engine/reference/builder/#env
Dockerfile:
...
ENV AM_I_IN_A_DOCKER_CONTAINER Yes
which could then be read from your app with something like:
python_app.py:
import os
SECRET_KEY = os.environ.get('AM_I_IN_A_DOCKER_CONTAINER', False)
if SECRET_KEY:
print('I am running in a Docker container')
import os, re
path = "/proc/self/cgroup"
def is_docker():
if not os.path.isfile(path): return False
with open(path) as f:
for line in f:
if re.match("d+:[w=]+:/docker(-[ce]e)?/w+", line):
return True
return False
print(is_docker())
The is-docker package for npm suggests a robust approach, ported here to Python 2.6+:
import os
def is_docker():
path = '/proc/self/cgroup'
return (
os.path.exists('/.dockerenv') or
os.path.isfile(path) and any('docker' in line for line in open(path))
)
Similar to the is-docker package for npm, I’ve created jaraco.docker with an is_docker
function. For Python 3.5+ with that package installed:
from jaraco.docker import is_docker
if is_docker():
print("In docker")
If you are using nodeJS
is-docker is a popular npm packages to accomplish this.
import isDocker from 'is-docker';
if (isDocker()) {
console.log('Running inside a Docker container');
}
In Python 3.4+ this should work nice
from pathlib import Path
def is_docker():
cgroup = Path("/proc/self/cgroup")
return Path('/.dockerenv').is_file() or cgroup.is_file() and cgroup.read_text().find("docker") > -1