is_container/lib.rs
1//! Check if the process is running inside a container.
2//!
3//! # Examples
4//!
5//! ```
6//! use is_container::is_container;
7//!
8//! if is_container() {
9//! println!("Running inside a container");
10//! }
11//! ```
12//!
13//! # Inspired
14//!
15//! - [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)
16//! - [sindresorhus/is-inside-container](https://github.com/sindresorhus/is-inside-container)
17
18use std::fs;
19
20use once_cell::sync::Lazy;
21
22fn has_docker_env() -> bool {
23 fs::metadata("/.dockerenv").is_ok()
24}
25
26fn has_container_env() -> bool {
27 fs::metadata("/run/.containerenv").is_ok()
28}
29
30fn has_cgroup_v1() -> bool {
31 fs::read_to_string("/proc/1/cgroup").map_or(false, |contents| {
32 contents.contains("docker") || contents.contains("lxc")
33 })
34}
35
36fn has_mountinfo() -> bool {
37 fs::read_to_string("/proc/1/mountinfo").map_or(false, |contents| {
38 // See https://man7.org/linux/man-pages/man5/proc.5.html
39 //
40 // The file contains lines of the form:
41 // 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
42 // (1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11)
43 contents.lines().any(|line| {
44 line.split_whitespace()
45 .nth(3)
46 .map_or(false, |mnt1| mnt1.contains("docker") || mnt1.contains("lxc"))
47 })
48 })
49}
50
51/// The main function provided by this crate. See crate documentation for more information.
52pub fn is_container() -> bool {
53 static CACHED_RESULT: Lazy<bool> =
54 Lazy::new(|| has_docker_env() || has_container_env() || has_mountinfo() || has_cgroup_v1());
55
56 *CACHED_RESULT
57}