Skip to content

Commit 5bafcbe

Browse files
MohsinHashmi-DataInnmohsin-wiserclaude
authored
fix: create host directories before mounting to devcontainer (#442)
* fix: add automatic permission fixing to coder startup script Add sudo chown command to fix workspace ownership before git operations. This prevents 'insufficient permission' errors when running as vscode user after switching from root user in existing workspaces. * fix: comprehensive permission fixing for all bind-mounted directories Expand permission fixing in startup script to cover: - Workspace directory (/workspaces/SimpleAccounts-UAE) - All config directories (.claude, .gemini, .config/gh, etc.) - SSH directory with proper key permissions (700/600/644) This ensures future workspaces will have correct permissions for all bind-mounted host directories when running as vscode user. * fix: create host directories and files before mounting to devcontainer - Add null_resource provisioner to create host directories before container starts - Create .claude.json and .gemini/config.json files on host if they don't exist - Mount both .claude.json (file) and .claude/ (directory) for Claude CLI - Mount .gemini/ directory containing config.json (simplified from separate file mount) - Update startup script to fix permissions for both files and directories - Add dependency on host_directories resource to ensure proper mount order This ensures files exist on the Coder host before Docker mounts them, preventing permission issues and enabling proper persistence of config between container rebuilds. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Mohsin Hashmi <mhashmi@wiser.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 8741845 commit 5bafcbe

1 file changed

Lines changed: 85 additions & 9 deletions

File tree

.coder/template.tf

Lines changed: 85 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,73 @@ provider "docker" {
4545
host = "unix:///var/run/docker.sock"
4646
}
4747

48+
# Create host directories for bind mounts before container starts
49+
resource "null_resource" "host_directories" {
50+
# Re-run when workspace is rebuilt
51+
triggers = {
52+
workspace_id = data.coder_workspace.me.id
53+
}
54+
55+
provisioner "local-exec" {
56+
command = <<-EOT
57+
#!/bin/bash
58+
set -e
59+
60+
# Create base directory structure
61+
BASE_DIR="/home/coder/.coder-mount/${data.coder_workspace_owner.me.name}"
62+
63+
# Create directories for config files
64+
mkdir -p "$BASE_DIR/claude"
65+
mkdir -p "$BASE_DIR/claude/.claude" # Claude data directory
66+
mkdir -p "$BASE_DIR/gemini/.gemini" # Gemini data directory
67+
mkdir -p "$BASE_DIR/.config/gh"
68+
mkdir -p "$BASE_DIR/.ssh"
69+
mkdir -p "$BASE_DIR/.docker"
70+
mkdir -p "$BASE_DIR/.kube"
71+
mkdir -p "$BASE_DIR/bash_history"
72+
mkdir -p "$BASE_DIR/gitconfig"
73+
74+
# Create .claude.json if it doesn't exist
75+
if [ ! -f "$BASE_DIR/claude/.claude.json" ]; then
76+
echo '{}' > "$BASE_DIR/claude/.claude.json"
77+
echo "✅ Created empty .claude.json file"
78+
fi
79+
80+
# Create .gemini/config.json if it doesn't exist
81+
if [ ! -f "$BASE_DIR/gemini/.gemini/config.json" ]; then
82+
echo '{}' > "$BASE_DIR/gemini/.gemini/config.json"
83+
echo "✅ Created empty gemini config.json file"
84+
fi
85+
86+
# Create .bash_history if it doesn't exist
87+
if [ ! -f "$BASE_DIR/bash_history/.bash_history" ]; then
88+
touch "$BASE_DIR/bash_history/.bash_history"
89+
echo "✅ Created .bash_history file"
90+
fi
91+
92+
# Create .gitconfig if it doesn't exist
93+
if [ ! -f "$BASE_DIR/gitconfig/.gitconfig" ]; then
94+
cat > "$BASE_DIR/gitconfig/.gitconfig" << 'EOF'
95+
[user]
96+
name = ${data.coder_workspace_owner.me.name}
97+
email = ${data.coder_workspace_owner.me.email}
98+
[init]
99+
defaultBranch = main
100+
[pull]
101+
rebase = false
102+
EOF
103+
echo "✅ Created .gitconfig file"
104+
fi
105+
106+
# Ensure proper permissions (coder user should own these)
107+
chown -R coder:coder "$BASE_DIR" 2>/dev/null || true
108+
109+
echo "✅ Host directories prepared for user: ${data.coder_workspace_owner.me.name}"
110+
EOT
111+
interpreter = ["bash", "-c"]
112+
}
113+
}
114+
48115
# Random password for PostgreSQL (generated once per workspace)
49116
resource "random_password" "postgres" {
50117
length = 32
@@ -162,12 +229,12 @@ resource "coder_agent" "main" {
162229
sudo chown -R vscode:vscode /workspaces/SimpleAccounts-UAE 2>/dev/null || true
163230
fi
164231
165-
# Fix ownership of bind-mounted config directories
166-
for dir in /home/vscode/.claude /home/vscode/.gemini /home/vscode/.config/gh \
167-
/home/vscode/.bash_history_dir /home/vscode/.gitconfig_dir \
168-
/home/vscode/.ssh /home/vscode/.docker /home/vscode/.kube; do
169-
if [ -d "$dir" ]; then
170-
sudo chown -R vscode:vscode "$dir" 2>/dev/null || true
232+
# Fix ownership of bind-mounted config files and directories
233+
for path in /home/vscode/.claude.json /home/vscode/.claude /home/vscode/.gemini \
234+
/home/vscode/.config/gh /home/vscode/.bash_history_dir /home/vscode/.gitconfig_dir \
235+
/home/vscode/.ssh /home/vscode/.docker /home/vscode/.kube; do
236+
if [ -e "$path" ]; then
237+
sudo chown -R vscode:vscode "$path" 2>/dev/null || true
171238
fi
172239
done
173240
@@ -342,12 +409,20 @@ resource "docker_container" "workspace" {
342409
container_path = "/home/vscode/.npm"
343410
}
344411

345-
# User credentials (persistent across host)
412+
# User credentials (persistent across host) - mount both file and directory
413+
# Claude config file
414+
volumes {
415+
host_path = "/home/coder/.coder-mount/${data.coder_workspace_owner.me.name}/claude/.claude.json"
416+
container_path = "/home/vscode/.claude.json"
417+
}
418+
419+
# Claude data directory (for cache, sessions, etc.)
346420
volumes {
347421
host_path = "/home/coder/.coder-mount/${data.coder_workspace_owner.me.name}/claude/.claude"
348422
container_path = "/home/vscode/.claude"
349423
}
350424

425+
# Gemini directory (contains config.json and other data)
351426
volumes {
352427
host_path = "/home/coder/.coder-mount/${data.coder_workspace_owner.me.name}/gemini/.gemini"
353428
container_path = "/home/vscode/.gemini"
@@ -432,10 +507,11 @@ resource "docker_container" "workspace" {
432507
value = "8080"
433508
}
434509

435-
# Depend on database containers
510+
# Depend on database containers and host directory setup
436511
depends_on = [
437512
docker_container.postgres,
438-
docker_container.redis
513+
docker_container.redis,
514+
null_resource.host_directories
439515
]
440516

441517
# Auto-restart on failure

0 commit comments

Comments
 (0)