1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//! Check if the process is running inside a container.
//!
//! # Examples
//!
//! ```
//! use is_container::is_container;
//!
//! if is_container() {
//!     println!("Running inside a container");
//! }
//! ```
//!
//! # Inspired
//!
//! - [How to determine if a process runs inside lxc/Docker?](https://stackoverflow.com/questions/20010199/how-to-determine-if-a-process-runs-inside-lxc-docker)
//! - [sindresorhus/is-inside-container](https://github.com/sindresorhus/is-inside-container)

use std::fs;

use once_cell::sync::Lazy;

fn has_docker_env() -> bool {
    fs::metadata("/.dockerenv").is_ok()
}

fn has_container_env() -> bool {
    fs::metadata("/run/.containerenv").is_ok()
}

fn has_cgroup_v1() -> bool {
    fs::read_to_string("/proc/1/cgroup").map_or(false, |contents| {
        contents.contains("docker") || contents.contains("lxc")
    })
}

fn has_mountinfo() -> bool {
    fs::read_to_string("/proc/1/mountinfo").map_or(false, |contents| {
        contents.contains("docker") || contents.contains("lxc")
    })
}

/// The main function provided by this crate. See crate documentation for more information.
pub fn is_container() -> bool {
    static CACHED_RESULT: Lazy<bool> =
        Lazy::new(|| has_docker_env() || has_container_env() || has_mountinfo() || has_cgroup_v1());

    *CACHED_RESULT
}