You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(startup): scope generated-content and upload dirs to the current user (#10698)
The `--generated-content-path` and `--upload-path` defaults were the fixed
shared locations `/tmp/generated/content` and `/tmp/localai/upload`. On any
multi-user host these collide across accounts: macOS routes `/tmp` to the
shared `/private/tmp` for every user, so whichever account starts LocalAI
first creates the parent with 0750 perms and every other account then fails
startup with:
unable to create ImageDir: "mkdir /tmp/generated/content: permission denied"
unable to create UploadDir: "mkdir /tmp/localai/upload: permission denied"
The same happens on Linux once a stale root-owned `/tmp/generated` (e.g. from
a prior `sudo` run) is left behind. This bites the desktop launcher and any
app embedding the raw binary (Wingman, nib-desktop), which start `local-ai
run` with no path flags.
Default both paths under the OS temp dir (`os.TempDir()`, honoring `$TMPDIR`;
already per-user on macOS) namespaced by the current UID
(`TMPDIR/localai-<uid>/...`), so accounts never collide while the paths stay
ephemeral. Wired via new kong vars in main.go so every consumer of the raw
binary inherits the fix. All content subdirs (audio, images) derive from
`GeneratedContentDir`, so they are fixed transitively.
As defense in depth, the launcher also anchors these two paths under its own
per-user data directory (mirroring the #10610 fix for data/config), extracted
into a testable `BuildRunArgs`.
Assisted-by: Claude:claude-opus-4-8 [Claude Code]
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
Copy file name to clipboardExpand all lines: core/cli/run.go
+27-2Lines changed: 27 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -35,8 +35,8 @@ type RunCMD struct {
35
35
BackendsPathstring`env:"LOCALAI_BACKENDS_PATH,BACKENDS_PATH" type:"path" default:"${basepath}/backends" help:"Path containing backends used for inferencing" group:"backends"`
36
36
BackendsSystemPathstring`env:"LOCALAI_BACKENDS_SYSTEM_PATH,BACKEND_SYSTEM_PATH" type:"path" default:"/var/lib/local-ai/backends" help:"Path containing system backends used for inferencing" group:"backends"`
37
37
ModelsPathstring`env:"LOCALAI_MODELS_PATH,MODELS_PATH" type:"path" default:"${basepath}/models" help:"Path containing models used for inferencing" group:"storage"`
UploadPathstring`env:"LOCALAI_UPLOAD_PATH,UPLOAD_PATH" type:"path" default:"/tmp/localai/upload" help:"Path to store uploads from files api" group:"storage"`
UploadPathstring`env:"LOCALAI_UPLOAD_PATH,UPLOAD_PATH" type:"path" default:"${uploadpath}" help:"Path to store uploads from files api" group:"storage"`
40
40
DataPathstring`env:"LOCALAI_DATA_PATH" type:"path" default:"${basepath}/data" help:"Path for persistent data (collectiondb, agent state, tasks, jobs). Separates mutable data from configuration" group:"storage"`
41
41
LocalaiConfigDirstring`env:"LOCALAI_CONFIG_DIR" type:"path" default:"${basepath}/configuration" help:"Directory for dynamic loading of certain configuration files (currently api_keys.json and external_backends.json)" group:"storage"`
42
42
LocalaiConfigDirPollInterval time.Duration`env:"LOCALAI_CONFIG_DIR_POLL_INTERVAL" help:"Typically the config path picks up changes automatically, but if your system has broken fsnotify events, set this to an interval to poll the LocalAI Config Dir (example: 1m)" group:"storage"`
@@ -186,6 +186,31 @@ type RunCMD struct {
186
186
PIIDefaultDetectors []string`env:"LOCALAI_PII_DEFAULT_DETECTORS" help:"Instance-wide default PII/secret detector model names applied to any PII-enabled model (chiefly cloud-proxy / MITM models) that names no pii.detectors of its own. Comma-separated, e.g. privacy-filter-nemotron,secret-filter. Takes precedence over the value persisted via the Middleware UI." group:"middleware"`
187
187
}
188
188
189
+
// userScopedTempDir returns a temp directory namespaced to the current user.
190
+
//
191
+
// The generated-content and upload directories are ephemeral, so they live
192
+
// under the OS temp dir - but a fixed shared name like /tmp/generated is a trap
193
+
// on any multi-user host. macOS routes /tmp to the shared /private/tmp for every
194
+
// account, so whichever user starts LocalAI first creates the parent with 0750
195
+
// perms and every other account then fails startup with
196
+
// "mkdir /tmp/generated/content: permission denied" (the same happens on Linux
197
+
// once a stale root-owned /tmp/generated is left behind). Scoping to the current
198
+
// UID gives each account its own tree so they never collide.
|`--models-path`|`BASEPATH/models`| Path containing models used for inferencing |`$LOCALAI_MODELS_PATH`, `$MODELS_PATH`|
25
25
|`--data-path`|`BASEPATH/data`| Path for persistent data (collectiondb, agent state, tasks, jobs). Separates mutable data from configuration |`$LOCALAI_DATA_PATH`|
26
-
|`--generated-content-path`|`/tmp/generated/content`| Location for assets generated by backends (e.g. stablediffusion, images, audio, videos) |`$LOCALAI_GENERATED_CONTENT_PATH`, `$GENERATED_CONTENT_PATH`|
27
-
|`--upload-path`|`/tmp/localai/upload`| Path to store uploads from files API |`$LOCALAI_UPLOAD_PATH`, `$UPLOAD_PATH`|
26
+
|`--generated-content-path`|`TMPDIR/localai-UID/generated/content`| Location for assets generated by backends (e.g. stablediffusion, images, audio, videos). Defaults under the OS temp dir (`$TMPDIR`, falling back to `/tmp`), scoped to the current user's UID so accounts sharing a host never collide.|`$LOCALAI_GENERATED_CONTENT_PATH`, `$GENERATED_CONTENT_PATH`|
27
+
|`--upload-path`|`TMPDIR/localai-UID/upload`| Path to store uploads from files API. Defaults under the OS temp dir (`$TMPDIR`, falling back to `/tmp`), scoped to the current user's UID.|`$LOCALAI_UPLOAD_PATH`, `$UPLOAD_PATH`|
28
28
|`--localai-config-dir`|`BASEPATH/configuration`| Directory for dynamic loading of certain configuration files (currently runtime_settings.json, api_keys.json, and external_backends.json). See [Runtime Settings]({{%relref "features/runtime-settings" %}}) for web-based configuration. |`$LOCALAI_CONFIG_DIR`|
29
29
|`--localai-config-dir-poll-interval`|| Time duration to poll the LocalAI Config Dir if your system has broken fsnotify events (example: `1m`) |`$LOCALAI_CONFIG_DIR_POLL_INTERVAL`|
30
30
|`--models-config-file`|| YAML file containing a list of model backend configs (alias: `--config-file`) |`$LOCALAI_MODELS_CONFIG_FILE`, `$CONFIG_FILE`|
0 commit comments