Loading...
Automatically rebuilds Docker containers when Dockerfile or docker-compose.yml files are modified
{
"hookConfig": {
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/docker-container-auto-rebuild.sh",
"matchers": [
"write",
"edit"
]
}
}
},
"scriptContent": "#!/usr/bin/env bash\n\n# Read the tool input from stdin\nINPUT=$(cat)\nTOOL_NAME=$(echo \"$INPUT\" | jq -r '.tool_name')\nFILE_PATH=$(echo \"$INPUT\" | jq -r '.tool_input.file_path // .tool_input.path // \"\"')\n\nif [ -z \"$FILE_PATH\" ]; then\n exit 0\nfi\n\n# Check if it's a Docker-related file\nif [[ \"$FILE_PATH\" == *Dockerfile* ]] || [[ \"$FILE_PATH\" == *docker-compose* ]] || [[ \"$FILE_PATH\" == *.dockerfile ]] || [[ \"$FILE_PATH\" == *dockerignore* ]]; then\n echo \"🐳 Docker file detected: $FILE_PATH\" >&2\n \n # Check if Docker is available\n if ! command -v docker &> /dev/null; then\n echo \"⚠️ Docker not found - install Docker to enable auto-rebuild\" >&2\n exit 0\n fi\n \n # Check if Docker daemon is running\n if ! docker info &> /dev/null; then\n echo \"⚠️ Docker daemon not running - start Docker to enable auto-rebuild\" >&2\n exit 0\n fi\n \n # Handle different Docker file types\n if [[ \"$FILE_PATH\" == *Dockerfile* ]] || [[ \"$FILE_PATH\" == *.dockerfile ]]; then\n echo \"🔨 Dockerfile modified - rebuilding Docker image...\" >&2\n \n # Determine image name (use directory name by default)\n IMAGE_NAME=$(basename \"$(pwd)\"):latest\n \n # Check if there's a specific Dockerfile path\n DOCKERFILE_DIR=$(dirname \"$FILE_PATH\")\n \n echo \"📦 Building image: $IMAGE_NAME\" >&2\n echo \"📁 Build context: $DOCKERFILE_DIR\" >&2\n \n # Build the Docker image\n if docker build -t \"$IMAGE_NAME\" \"$DOCKERFILE_DIR\" 2>&1; then\n echo \"✅ Docker image '$IMAGE_NAME' rebuilt successfully\" >&2\n \n # Show image details\n IMAGE_ID=$(docker images -q \"$IMAGE_NAME\" | head -1)\n if [ -n \"$IMAGE_ID\" ]; then\n IMAGE_SIZE=$(docker images \"$IMAGE_NAME\" --format \"table {{.Size}}\" | tail -1)\n echo \"📊 Image ID: $IMAGE_ID, Size: $IMAGE_SIZE\" >&2\n fi\n else\n echo \"❌ Docker image build failed\" >&2\n exit 1\n fi\n \n elif [[ \"$FILE_PATH\" == *docker-compose* ]]; then\n echo \"🔨 Docker Compose file modified - rebuilding services...\" >&2\n \n COMPOSE_FILE=$(basename \"$FILE_PATH\")\n COMPOSE_DIR=$(dirname \"$FILE_PATH\")\n \n echo \"📁 Compose file: $COMPOSE_FILE\" >&2\n echo \"📁 Working directory: $COMPOSE_DIR\" >&2\n \n # Change to the directory containing the compose file\n cd \"$COMPOSE_DIR\" || exit 1\n \n # Check if docker-compose or docker compose is available\n if command -v docker-compose &> /dev/null; then\n COMPOSE_CMD=\"docker-compose\"\n elif docker compose version &> /dev/null; then\n COMPOSE_CMD=\"docker compose\"\n else\n echo \"⚠️ Neither docker-compose nor 'docker compose' found\" >&2\n exit 0\n fi\n \n # Build the services\n echo \"🔧 Using: $COMPOSE_CMD\" >&2\n if $COMPOSE_CMD -f \"$COMPOSE_FILE\" build 2>&1; then\n echo \"✅ Docker Compose services rebuilt successfully\" >&2\n \n # Show service status\n echo \"📊 Service status:\" >&2\n $COMPOSE_CMD -f \"$COMPOSE_FILE\" ps --format \"table {{.Service}}\\t{{.Status}}\" 2>/dev/null || true\n else\n echo \"❌ Docker Compose build failed\" >&2\n exit 1\n fi\n \n elif [[ \"$FILE_PATH\" == *dockerignore* ]]; then\n echo \"📝 .dockerignore file modified\" >&2\n echo \"💡 This will affect the next Docker build by excluding specified files\" >&2\n \n # Show dockerignore contents for reference\n if [ -f \"$FILE_PATH\" ]; then\n echo \"📋 Current .dockerignore rules:\" >&2\n head -10 \"$FILE_PATH\" >&2\n fi\n fi\n \n # General Docker tips\n echo \"\" >&2\n echo \"💡 Docker Development Tips:\" >&2\n echo \" • Use .dockerignore to exclude unnecessary files\" >&2\n echo \" • Consider multi-stage builds for smaller images\" >&2\n echo \" • Use docker system prune to clean up unused resources\" >&2\n \nelse\n echo \"File $FILE_PATH is not a Docker-related file, skipping rebuild\" >&2\nfi\n\nexit 0"
}.claude/hooks/~/.claude/hooks/{
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/docker-container-auto-rebuild.sh",
"matchers": [
"write",
"edit"
]
}
}
}#!/usr/bin/env bash
# Read the tool input from stdin
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [ -z "$FILE_PATH" ]; then
exit 0
fi
# Check if it's a Docker-related file
if [[ "$FILE_PATH" == *Dockerfile* ]] || [[ "$FILE_PATH" == *docker-compose* ]] || [[ "$FILE_PATH" == *.dockerfile ]] || [[ "$FILE_PATH" == *dockerignore* ]]; then
echo "🐳 Docker file detected: $FILE_PATH" >&2
# Check if Docker is available
if ! command -v docker &> /dev/null; then
echo "⚠️ Docker not found - install Docker to enable auto-rebuild" >&2
exit 0
fi
# Check if Docker daemon is running
if ! docker info &> /dev/null; then
echo "⚠️ Docker daemon not running - start Docker to enable auto-rebuild" >&2
exit 0
fi
# Handle different Docker file types
if [[ "$FILE_PATH" == *Dockerfile* ]] || [[ "$FILE_PATH" == *.dockerfile ]]; then
echo "🔨 Dockerfile modified - rebuilding Docker image..." >&2
# Determine image name (use directory name by default)
IMAGE_NAME=$(basename "$(pwd)"):latest
# Check if there's a specific Dockerfile path
DOCKERFILE_DIR=$(dirname "$FILE_PATH")
echo "📦 Building image: $IMAGE_NAME" >&2
echo "📁 Build context: $DOCKERFILE_DIR" >&2
# Build the Docker image
if docker build -t "$IMAGE_NAME" "$DOCKERFILE_DIR" 2>&1; then
echo "✅ Docker image '$IMAGE_NAME' rebuilt successfully" >&2
# Show image details
IMAGE_ID=$(docker images -q "$IMAGE_NAME" | head -1)
if [ -n "$IMAGE_ID" ]; then
IMAGE_SIZE=$(docker images "$IMAGE_NAME" --format "table {{.Size}}" | tail -1)
echo "📊 Image ID: $IMAGE_ID, Size: $IMAGE_SIZE" >&2
fi
else
echo "❌ Docker image build failed" >&2
exit 1
fi
elif [[ "$FILE_PATH" == *docker-compose* ]]; then
echo "🔨 Docker Compose file modified - rebuilding services..." >&2
COMPOSE_FILE=$(basename "$FILE_PATH")
COMPOSE_DIR=$(dirname "$FILE_PATH")
echo "📁 Compose file: $COMPOSE_FILE" >&2
echo "📁 Working directory: $COMPOSE_DIR" >&2
# Change to the directory containing the compose file
cd "$COMPOSE_DIR" || exit 1
# Check if docker-compose or docker compose is available
if command -v docker-compose &> /dev/null; then
COMPOSE_CMD="docker-compose"
elif docker compose version &> /dev/null; then
COMPOSE_CMD="docker compose"
else
echo "⚠️ Neither docker-compose nor 'docker compose' found" >&2
exit 0
fi
# Build the services
echo "🔧 Using: $COMPOSE_CMD" >&2
if $COMPOSE_CMD -f "$COMPOSE_FILE" build 2>&1; then
echo "✅ Docker Compose services rebuilt successfully" >&2
# Show service status
echo "📊 Service status:" >&2
$COMPOSE_CMD -f "$COMPOSE_FILE" ps --format "table {{.Service}}\t{{.Status}}" 2>/dev/null || true
else
echo "❌ Docker Compose build failed" >&2
exit 1
fi
elif [[ "$FILE_PATH" == *dockerignore* ]]; then
echo "📝 .dockerignore file modified" >&2
echo "💡 This will affect the next Docker build by excluding specified files" >&2
# Show dockerignore contents for reference
if [ -f "$FILE_PATH" ]; then
echo "📋 Current .dockerignore rules:" >&2
head -10 "$FILE_PATH" >&2
fi
fi
# General Docker tips
echo "" >&2
echo "💡 Docker Development Tips:" >&2
echo " • Use .dockerignore to exclude unnecessary files" >&2
echo " • Consider multi-stage builds for smaller images" >&2
echo " • Use docker system prune to clean up unused resources" >&2
else
echo "File $FILE_PATH is not a Docker-related file, skipping rebuild" >&2
fi
exit 0Docker build fails with 'daemon not running' despite Docker Desktop being active
Verify Docker socket accessibility with 'docker info' command. Restart Docker daemon or add user to docker group on Linux: 'sudo usermod -aG docker $USER' then log out and back in.
Hook triggers rebuild but uses wrong Dockerfile when multiple exist in project
Specify Dockerfile path explicitly using 'docker build -f $FILE_PATH' instead of relying on directory context. Detect Dockerfile name pattern and use as -f argument for targeted builds.
Docker Compose rebuild hangs indefinitely when services have dependency conflicts
Add --no-cache flag to force clean rebuild: 'docker-compose build --no-cache'. Stop running containers first with 'docker-compose down' before rebuild to prevent port and resource conflicts.
Build context too large error when .dockerignore changes not respected in hook
Ensure .dockerignore is in same directory as Dockerfile being built. Docker reads .dockerignore from build context root, not from Dockerfile directory if using -f flag with different path.
Hook exits successfully but image not updated with latest changes after rebuild
Verify Docker build cache invalidation by checking layer hashes in build output. Add COPY instruction for modified files or use 'docker build --pull --no-cache' to force complete rebuild without cache.
Loading reviews...
Join our community of Claude power users. No spam, unsubscribe anytime.
Automated accessibility testing and compliance checking for web applications following WCAG guidelines
Automatically generates or updates API documentation when endpoint files are modified
Automatically formats code files after Claude writes or edits them using Prettier, Black, or other formatters