Skip to content

Commit 37f1d3d

Browse files
committed
Add container runtime pre-flight check
Validates Docker or Podman is installed and running before attempting to build the devcontainer. Aborts with OS-specific remediation guidance (Windows/WSL, macOS, Linux) instead of a cryptic Docker client error.
1 parent b2261ed commit 37f1d3d

File tree

3 files changed

+118
-0
lines changed

3 files changed

+118
-0
lines changed

.devcontainer/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
### Added
66

7+
#### Startup
8+
- **Container runtime pre-flight check** — validates Docker or Podman is installed and running before attempting to build the devcontainer; aborts with OS-specific remediation guidance (Windows/WSL, macOS, Linux) instead of a cryptic Docker client error
9+
710
#### README
811
- **"Why CodeForge?" section** — motivation and value proposition explaining the project's origins as a power user's personal setup
912
- **Architecture overview** — three-layer diagram (DevContainer → CodeForge Layer → Claude Code) with brief descriptions and link to full architecture docs

.devcontainer/devcontainer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
"workspaceFolder": "/workspaces",
66
"workspaceMount": "source=${localWorkspaceFolder},target=/workspaces,type=bind",
77

8+
"initializeCommand": "bash .devcontainer/scripts/preflight.sh",
9+
810
"mounts": [
911
{
1012
"source": "codeforge-claude-config-${devcontainerId}",

.devcontainer/scripts/preflight.sh

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#!/usr/bin/env bash
2+
# SPDX-License-Identifier: GPL-3.0-only
3+
# Copyright (c) 2026 Marcus Krueger
4+
# Pre-flight check: validates a container runtime is available on the host.
5+
# Runs via initializeCommand BEFORE any container build/pull/start.
6+
7+
set -euo pipefail
8+
9+
# --- OS detection ---
10+
11+
detect_os() {
12+
if [[ -f /proc/version ]] && grep -qi 'microsoft\|wsl' /proc/version 2>/dev/null; then
13+
echo "wsl"
14+
elif [[ "$(uname -s)" == "Darwin" ]]; then
15+
echo "macos"
16+
else
17+
echo "linux"
18+
fi
19+
}
20+
21+
# --- Timeout wrapper (macOS lacks coreutils timeout) ---
22+
23+
run_with_timeout() {
24+
local seconds="$1"
25+
shift
26+
if command -v timeout &>/dev/null; then
27+
timeout "$seconds" "$@" &>/dev/null 2>&1
28+
else
29+
# Fallback for macOS: background + kill
30+
"$@" &>/dev/null 2>&1 &
31+
local pid=$!
32+
(sleep "$seconds" && kill "$pid" 2>/dev/null) &
33+
local watchdog=$!
34+
if wait "$pid" 2>/dev/null; then
35+
kill "$watchdog" 2>/dev/null
36+
wait "$watchdog" 2>/dev/null
37+
return 0
38+
else
39+
kill "$watchdog" 2>/dev/null
40+
wait "$watchdog" 2>/dev/null
41+
return 1
42+
fi
43+
fi
44+
}
45+
46+
# --- Runtime detection ---
47+
48+
check_runtime() {
49+
local runtime="$1"
50+
if ! command -v "$runtime" &>/dev/null; then
51+
return 1
52+
fi
53+
if run_with_timeout 5 "$runtime" info; then
54+
return 0
55+
fi
56+
return 1
57+
}
58+
59+
# --- Main ---
60+
61+
for runtime in docker podman; do
62+
if check_runtime "$runtime"; then
63+
exit 0
64+
fi
65+
done
66+
67+
# No working runtime found — determine why and advise
68+
69+
found_binary=""
70+
for runtime in docker podman; do
71+
if command -v "$runtime" &>/dev/null; then
72+
found_binary="$runtime"
73+
break
74+
fi
75+
done
76+
77+
HOST_OS="$(detect_os)"
78+
79+
echo ""
80+
echo "╔══════════════════════════════════════════════════════════════╗"
81+
echo "║ CodeForge: Container runtime not available ║"
82+
echo "╚══════════════════════════════════════════════════════════════╝"
83+
echo ""
84+
85+
if [[ -n "$found_binary" ]]; then
86+
echo " Found '$found_binary' but the daemon is not responding."
87+
echo ""
88+
case "$HOST_OS" in
89+
wsl)
90+
echo " Fix: Start Docker Desktop and enable WSL 2 integration:"
91+
echo " Settings → Resources → WSL Integration"
92+
;;
93+
macos)
94+
echo " Fix: Start Docker Desktop:"
95+
echo " open -a Docker"
96+
;;
97+
linux)
98+
echo " Fix: Start the Docker daemon:"
99+
echo " sudo systemctl start docker"
100+
;;
101+
esac
102+
else
103+
echo " No container runtime (docker or podman) found in PATH."
104+
echo ""
105+
echo " Install Docker Desktop:"
106+
echo " https://www.docker.com/products/docker-desktop/"
107+
echo ""
108+
echo " Or install Podman:"
109+
echo " https://podman.io/getting-started/installation"
110+
fi
111+
112+
echo ""
113+
exit 1

0 commit comments

Comments
 (0)