diff --git a/Cargo.lock b/Cargo.lock
index 8bf9af0108b3114cf01fb4f630e22d750f3d4cc9..a6801f35ce345fa54758e8909e3e8a73d07716f6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1724,25 +1724,6 @@ version = "2.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
 
-[[package]]
-name = "is-docker"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3"
-dependencies = [
- "once_cell",
-]
-
-[[package]]
-name = "is-wsl"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5"
-dependencies = [
- "is-docker",
- "once_cell",
-]
-
 [[package]]
 name = "itoa"
 version = "1.0.9"
@@ -1907,7 +1888,6 @@ dependencies = [
  "base64",
  "chrono",
  "dirs",
- "is-wsl",
  "libc",
  "log",
  "pathdiff",
diff --git a/lektor_utils/Cargo.toml b/lektor_utils/Cargo.toml
index b938a47ee246d2ff7d1c9c0726c2390077bf5126..ef4f59a243bd1b39b2e3a628851901a983362c38 100644
--- a/lektor_utils/Cargo.toml
+++ b/lektor_utils/Cargo.toml
@@ -25,8 +25,5 @@ serde_json.workspace = true
 [target.'cfg(all(unix, not(macos)))'.dependencies]
 pathdiff = "0.2.0"
 
-[target.'cfg(any(target_os = "linux", target_os = "android", target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd", target_os = "openbsd", target_os = "illumos", target_os = "solaris" ))'.dependencies]
-is-wsl = "0.4.0"
-
 [target."cfg(unix)".dependencies]
 libc = "0.2"
diff --git a/lektor_utils/src/is.rs b/lektor_utils/src/is.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a88e6f068801c7032d5151f06003c7af8ad74ab9
--- /dev/null
+++ b/lektor_utils/src/is.rs
@@ -0,0 +1,37 @@
+use std::{fs, sync::OnceLock};
+
+pub fn is_docker() -> bool {
+    static RES: OnceLock<bool> = OnceLock::new();
+    *RES.get_or_init(|| {
+        let env = fs::metadata("/.dockerenv").is_ok();
+        let cgroup = fs::read_to_string("/proc/self/cgroup")
+            .map(|file| file.contains("docker"))
+            .unwrap_or_default();
+        env || cgroup
+    })
+}
+
+pub fn is_wsl() -> bool {
+    static RES: OnceLock<bool> = OnceLock::new();
+    *RES.get_or_init(|| {
+        const OS_REL: &str = "/proc/sys/kernel/osrelease";
+        const PROC_VER: &str = "/proc/version";
+        let trim_lowercase = |str: String| str.trim().to_lowercase();
+
+        if std::env::consts::OS != "linux" {
+            return false;
+        }
+
+        if let Ok(os) = fs::read_to_string(OS_REL).map(trim_lowercase) {
+            if os.to_lowercase().contains("microsoft") {
+                return !is_docker();
+            }
+        }
+
+        fs::read_to_string(PROC_VER)
+            .map(|file| trim_lowercase(file).contains("microsoft"))
+            .unwrap_or_default()
+            .then(|| !is_docker())
+            .unwrap_or_default()
+    })
+}
diff --git a/lektor_utils/src/lib.rs b/lektor_utils/src/lib.rs
index 7ba1476ec80e3e574aca2879e946d5693e2030dc..05ec6081764adacf889f7c5c0c0de5c93e4660f1 100644
--- a/lektor_utils/src/lib.rs
+++ b/lektor_utils/src/lib.rs
@@ -6,6 +6,19 @@ mod base64;
 mod iterator;
 mod macros;
 
+// Import the is_wsl and is_docker code here...
+#[cfg(any(
+    target_os = "linux",
+    target_os = "android",
+    target_os = "freebsd",
+    target_os = "dragonfly",
+    target_os = "netbsd",
+    target_os = "openbsd",
+    target_os = "illumos",
+    target_os = "solaris"
+))]
+pub mod is;
+
 pub mod config;
 pub mod log;
 pub mod logger;
diff --git a/lektor_utils/src/open/unix.rs b/lektor_utils/src/open/unix.rs
index c76356df7db1a3811bc2ee40b2ef5b7731b88cca..7cb23eebb01f36176c10ca6bcc038e7cc23f7b37 100644
--- a/lektor_utils/src/open/unix.rs
+++ b/lektor_utils/src/open/unix.rs
@@ -10,7 +10,7 @@ pub fn commands<T: AsRef<OsStr>>(path: T) -> Vec<Command> {
     let mut commands: Vec<(&str, Vec<&OsStr>)> = vec![];
 
     let wsl_path = wsl_path(path);
-    if is_wsl::is_wsl() {
+    if crate::is::is_wsl() {
         commands.push(("wslview", vec![&wsl_path]));
     }