You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

macOS下Postinstall脚本执行docker command not found问题求助

问题分析与解决方案

核心问题原因

  1. Postinstall脚本的受限环境:macOS安装器(如.pkg)的Postinstall脚本运行在极简环境中,默认PATH仅包含/usr/bin、/bin等少数系统路径,而Docker的可执行文件通常在/usr/local/bin或Docker app的资源目录中,不在默认PATH里,导致which docker返回空值。
  2. 变量与语法错误:脚本中$Home应为大写的$HOME;使用反引号包裹$CheckVar load -i app.tar是错误的,反引号用于捕获命令输出,此处直接执行命令即可。
  3. Docker安装后未等待启动:Docker完成安装后,daemon不会立即启动,直接执行docker load会失败。
  4. 架构不匹配:Apple Silicon芯片使用Intel架构的Docker安装包,会导致安装失败或无法正常运行。
  5. sudo的环境重置:sudo默认会重置环境变量,即使脚本中设置了PATH,sudo执行时也会丢失。

分步解决方案

1. 明确Docker的绝对路径

在macOS中,Docker的实际路径:

  • Intel芯片:/usr/local/bin/docker
  • Apple Silicon芯片:/Applications/Docker.app/Contents/Resources/bin/docker(安装后会自动创建/usr/local/bin/docker的软链接,但Postinstall环境可能无法立即识别)

2. 修复脚本变量与语法

  • 将$Home改为$HOME
  • 移除命令执行时的反引号,直接使用sudo "$DOCKER_PATH" load -i app.tar
  • 使用sudo -E保留环境变量(如果需要传递PATH)

3. 等待Docker启动

安装Docker后,需要等待Docker daemon启动完成,可以通过循环检查docker info命令的返回值来实现。

4. 区分架构安装对应Docker包

为Apple Silicon芯片准备专门的Docker安装包(如AppleSiliconDocker.dmg),避免架构不兼容。

修改后的脚本

#!/bin/bash

# 定义Docker的可能路径,优先检查实际安装位置
DOCKER_PATHS=(
    "/Applications/Docker.app/Contents/Resources/bin/docker"
    "/usr/local/bin/docker"
)

# 查找可用的Docker路径
DOCKER_PATH=""
for path in "${DOCKER_PATHS[@]}"; do
    if [ -x "$path" ]; then
        DOCKER_PATH="$path"
        break
    fi
done

# 检查芯片类型
CPU_BRAND=$(sysctl -n machdep.cpu.brand_string)
WORK_DIR="$HOME/$DSTROOT/App"

if [[ "$CPU_BRAND" == *"Intel"* ]]; then
    DOCKER_DMG="IntelDocker.dmg"
else
    DOCKER_DMG="AppleSiliconDocker.dmg"
fi

# 确保工作目录存在
mkdir -p "$WORK_DIR"
cd "$WORK_DIR" || exit 1

if [ -n "$DOCKER_PATH" ] && "$DOCKER_PATH" info &>/dev/null; then
    echo "Mac Chip is ${CPU_BRAND%% *}"
    echo "Docker found!"
    echo "Redirected to working dir.."
    sudo -E "$DOCKER_PATH" load -i app.tar
    if [ $? -eq 0 ]; then
        echo "Success"
    else
        echo "Failed to load Docker image"
        exit 1
    fi
else
    echo "Mac Chip is ${CPU_BRAND%% *}"
    echo "Docker not found, installing..."
    echo "Redirected to working dir.."
    
    # 挂载DMG并安装Docker
    sudo hdiutil attach "$DOCKER_DMG" -quiet
    sudo /Volumes/Docker/Docker.app/Contents/MacOS/install --accept-license --quiet
    sudo hdiutil detach /Volumes/Docker -quiet
    
    # 等待Docker启动并检查可用性
    echo "Waiting for Docker to start..."
    MAX_WAIT=300
    WAIT_COUNT=0
    while [ $WAIT_COUNT -lt $MAX_WAIT ]; do
        # 重新查找Docker路径(安装后可能创建了软链接)
        for path in "${DOCKER_PATHS[@]}"; do
            if [ -x "$path" ]; then
                DOCKER_PATH="$path"
                break
            fi
        done
        if [ -n "$DOCKER_PATH" ] && "$DOCKER_PATH" info &>/dev/null; then
            break
        fi
        sleep 5
        WAIT_COUNT=$((WAIT_COUNT + 5))
    done
    
    if [ $WAIT_COUNT -ge $MAX_WAIT ]; then
        echo "Docker failed to start within 5 minutes"
        exit 1
    fi
    
    # 加载镜像
    sudo -E "$DOCKER_PATH" load -i app.tar
    if [ $? -eq 0 ]; then
        echo "Success"
    else
        echo "Failed to load Docker image"
        exit 1
    fi
fi

额外注意事项

  • 确保Postinstall脚本拥有足够的权限,安装包的权限设置正确。
  • Docker安装时使用--accept-license --quiet参数实现静默安装,避免交互。
  • 工作目录$HOME/$DSTROOT/App需要确认$DSTROOT在Postinstall环境中是否正确传递,部分安装器环境中$DSTROOT是目标安装路径,可能需要调整为实际的镜像文件存放路径。

内容的提问来源于stack exchange,提问作者grLearn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 09:35:18