{"record":{"id":"ff8d47a1ba28b689","repo":"Billionmail/BillionMail","slug":"failed-to-create-temporary-directory-s-v","errorCode":null,"errorMessage":"failed to create temporary directory %s: %v","messagePattern":"failed to create temporary directory (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/multi_ip_domain/config_manager.go","lineNumber":171,"sourceCode":"}\n\n// updateDockerCompose Generate docker-compose_addnetwork.yml\nfunc (m *ConfigManager) updateDockerCompose(ctx context.Context, configs []map[string]interface{}) error {\n\toriginalPath := filepath.Join(public.HostWorkDir, \"docker-compose.yml\")\n\toutputPath := filepath.Join(public.HostWorkDir, \"docker-compose_addnetwork.yml\")\n\n\t// 设置临时文件路径\n\t// 容器内路径：/opt/billionmail/core/data (通过 public.AbsPath 获取)\n\t// 宿主机路径：./core-data (相对于 docker-compose.yml 所在目录)\n\tcontainerDataPath := public.AbsPath(\"../core/data/\")\n\thostDataPath := filepath.Join(public.HostWorkDir, \"core-data\") // 宿主机的实际映射路径\n\ttempDockerComposePath := filepath.Join(containerDataPath, \"temp_docker-compose.yml\")\n\thostTempDockerComposePath := filepath.Join(hostDataPath, \"temp_docker-compose.yml\")\n\n\t// Ensure container directory exists\n\tif !gfile.Exists(containerDataPath) {\n\t\tif err := gfile.Mkdir(containerDataPath); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to create temporary directory %s: %v\", containerDataPath, err)\n\t\t}\n\t}\n\n\tdk, err := docker.NewDockerAPI()\n\tif err != nil {\n\t\treturn gerror.New(public.LangCtx(ctx, \"failed to create Docker API instance: %v\", err.Error()))\n\t}\n\tdefer dk.Close()\n\n\t// Step 1: 复制宿主机的 docker-compose.yml 到宿主机的 core-data 目录\n\t// 注意：这里目标路径使用宿主机的路径，因为 chroot /host_root 看到的是宿主机文件系\n\tcopyCmd := []string{\n\t\t\"/bin/sh\", \"-c\",\n\t\tfmt.Sprintf(`chroot /host_root cp \"%s\" \"%s\"`, originalPath, hostTempDockerComposePath),\n\t}\n\tresult, err := dk.ExecHostCommand(ctx, copyCmd)\n\tif err != nil || result.ExitCode != 0 {\n\t\treturn gerror.New(\"failed to copy original configuration file, please check path and permissions\")","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/multi_ip_domain/config_manager.go#L153-L189","documentation":"updateDockerCompose needs the container-side data directory (../core/data) to stage temp copies of docker-compose.yml via the host volume mapping. If the directory does not exist and gfile.Mkdir cannot create it, this error aborts the compose update before any Docker command runs. It indicates a filesystem permission or path problem inside the container.","triggerScenarios":"gfile.Exists(containerDataPath) is false and gfile.Mkdir fails: parent dir missing, no write permission, read-only filesystem, or an invalid path component.","commonSituations":"Deployment where the core/data volume was pruned and the parent directory is root-owned; image runs as non-root; working directory moved so public.AbsPath('../core/data') resolves somewhere unwritable.","solutions":["Create the directory manually with correct ownership: mkdir -p <containerDataPath> && chown <process-user> <containerDataPath>.","Use gfile.Mkdir (recursive) instead of single-level Mkdir so a missing parent does not abort.","Verify the volume mount for core/data exists in docker-compose.yml and is writable.","Confirm the process work directory is correct so AbsPath resolves the intended location."],"exampleFix":"// before\nif !gfile.Exists(containerDataPath) {\n\tif err := gfile.Mkdir(containerDataPath); err != nil {\n\t\treturn fmt.Errorf(\"failed to create temporary directory %s: %v\", containerDataPath, err)\n\t}\n}\n// after\nif !gfile.Exists(containerDataPath) {\n\tif err := gfile.Mkdir(containerDataPath); err != nil {\n\t\treturn fmt.Errorf(\"failed to create temporary directory %s: %v\", containerDataPath, err)\n\t}\n}","handlingStrategy":"validation","validationCode":"dir := public.AbsPath(\"../core/data\")\nif fi, err := os.Stat(dir); err != nil || !fi.IsDir() {\n\tif err := os.MkdirAll(dir, 0o755); err != nil {\n\t\treturn fmt.Errorf(\"cannot prepare temp dir %s: %v\", dir, err)\n\t}\n}","typeGuard":null,"tryCatchPattern":"if err := mgr.ApplyConfigsWithRollback(ctx, configs); err != nil {\n\tif strings.Contains(err.Error(), \"failed to create temporary directory\") {\n\t\t// mkdir the path manually with correct ownership, then retry\n\t}\n}","preventionTips":["Pre-create the core/data directory in the deployment image with correct ownership.","Mount core/data rw in docker-compose.","Use recursive Mkdir for nested paths.","Verify AbsPath base directory at service startup."],"tags":["filesystem","permissions","docker","go"],"backgroundTag":"temp-dir-creation-failed","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}