简体   繁体   中英

How does Java application know it is running within a Docker container

I have written a DockerFile for my application primarily to allow it to be run within a NAS machine (via Docker). The web interface allows the user to traverse the filesystem tree looking for Music files, but when using Docker the filesystem tree is irrelevant except for the /Music volume which is the mount point for the users actual Music folder on the NAS.

So I only want to display the /Music folder instead of the whole filesystem tree and to do that the application needs to be aware it is actually running within a Docker rather than an actual native Linux OS.

What is the correct way for the application to know it is in docker, the application is written in Java.

Solution

Check control group of the init process simply by /proc/1/cgroup .

  • if it is initiated normally all hierarchies have in / value
  • if it is initiated from docker container they have /docker/<container_id> value.

When running inside docker /proc/1/cgroup has values similar to :

11:perf_event:/docker/897df2a033d6ab07c357c1ac1f75741bd16474487de83c6d4d98518e5ef52249
10:memory:/docker/897df2a033d6ab07c357c1ac1f75741bd16474487de83c6d4d98518e5ef52249
9:cpuset:/docker/897df2a033d6ab07c357c1ac1f75741bd16474487de83c6d4d98518e5ef52249
8:net_cls,net_prio:/docker/897df2a033d6ab07c357c1ac1f75741bd16474487de83c6d4d98518e5ef52249
7:pids:/docker/897df2a033d6ab07c357c1ac1f75741bd16474487de83c6d4d98518e5ef52249
6:cpu,cpuacct:/docker/897df2a033d6ab07c357c1ac1f75741bd16474487de83c6d4d98518e5ef52249
5:blkio:/docker/897df2a033d6ab07c357c1ac1f75741bd16474487de83c6d4d98518e5ef52249
4:freezer:/docker/897df2a033d6ab07c357c1ac1f75741bd16474487de83c6d4d98518e5ef52249
3:hugetlb:/docker/897df2a033d6ab07c357c1ac1f75741bd16474487de83c6d4d98518e5ef52249
2:devices:/docker/897df2a033d6ab07c357c1ac1f75741bd16474487de83c6d4d98518e5ef52249
1:name=systemd:/docker/897df2a033d6ab07c357c1ac1f75741bd16474487de83c6d4d98518e5ef52249

Note: As @JanisKirsteins informed me, If you run your application in amazon ec2 you might want to change the condition to line.contains("/ecs") instead. because in /proc/1/cgroups you will find pattern similar to: /ecs/<uuid>/<uuid>


In Java

public static Boolean isRunningInsideDocker() {

        try (Stream < String > stream =
            Files.lines(Paths.get("/proc/1/cgroup"))) {
            return stream.anyMatch(line -> line.contains("/docker"));
        } catch (IOException e) {
            return false;
        }
    }

Live code checking


More Info

When you run the container add volume option.

docker run -v /Music:/Music <image-name>

Right side of : is where you application looking for the directory. I assumed it is /Music.

If you really want to check if your application is running inside the docker, you could check for the existence of file "/.dockerenv". Based on your question, one thing you should know is that when your application is running inside the docker, it does not have access to the filesystem of the host unless you give access via volumes. So, if your real linux machine has a directory /Music, your application has no access to it. You provide access via --volume . When you run application inside docker, you could consider it as it is running in another VM or machine for all practical purposes. That is the main purpose of Docker itself: provide isolation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM