diff --git a/api/client.go b/api/client.go index e86dc530..c89ff38f 100644 --- a/api/client.go +++ b/api/client.go @@ -18,10 +18,6 @@ import ( "github.com/jmorganca/ollama/version" ) -const DefaultHost = "127.0.0.1:11434" - -var envHost = os.Getenv("OLLAMA_HOST") - type Client struct { base *url.URL http http.Client diff --git a/docs/faq.md b/docs/faq.md index 2c7711d5..a1d11fc5 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -60,3 +60,7 @@ systemctl restart ollama - macOS: Raw model data is stored under `~/.ollama/models`. - Linux: Raw model data is stored under `/usr/share/ollama/.ollama/models` + +### How can I change where Ollama stores models? + +To modify where models are stored, you can use the `OLLAMA_MODELS` environment variable. Note that on Linux this means defining `OLLAMA_MODELS` in a drop-in `/etc/systemd/system/ollama.service.d` service file, reloading systemd, and restarting the ollama service. diff --git a/server/images.go b/server/images.go index 5ae8d008..e249f8f9 100644 --- a/server/images.go +++ b/server/images.go @@ -131,7 +131,7 @@ func (m *ManifestV2) GetTotalSize() (total int64) { } func GetManifest(mp ModelPath) (*ManifestV2, string, error) { - fp, err := mp.GetManifestPath(false) + fp, err := mp.GetManifestPath() if err != nil { return nil, "", err } @@ -595,10 +595,13 @@ func CreateManifest(name string, cfg *LayerReader, layers []*Layer) error { return err } - fp, err := mp.GetManifestPath(true) + fp, err := mp.GetManifestPath() if err != nil { return err } + if err := os.MkdirAll(filepath.Dir(fp), 0o755); err != nil { + return err + } return os.WriteFile(fp, manifestJSON, 0o644) } @@ -710,16 +713,19 @@ func CreateLayer(f io.ReadSeeker) (*LayerReader, error) { func CopyModel(src, dest string) error { srcModelPath := ParseModelPath(src) - srcPath, err := srcModelPath.GetManifestPath(false) + srcPath, err := srcModelPath.GetManifestPath() if err != nil { return err } destModelPath := ParseModelPath(dest) - destPath, err := destModelPath.GetManifestPath(true) + destPath, err := destModelPath.GetManifestPath() if err != nil { return err } + if err := os.MkdirAll(filepath.Dir(destPath), 0o755); err != nil { + return err + } // copy the file input, err := os.ReadFile(srcPath) @@ -882,7 +888,7 @@ func DeleteModel(name string) error { return err } - fp, err := mp.GetManifestPath(false) + fp, err := mp.GetManifestPath() if err != nil { return err } @@ -1121,10 +1127,13 @@ func PullModel(ctx context.Context, name string, regOpts *RegistryOptions, fn fu return err } - fp, err := mp.GetManifestPath(true) + fp, err := mp.GetManifestPath() if err != nil { return err } + if err := os.MkdirAll(filepath.Dir(fp), 0o755); err != nil { + return err + } err = os.WriteFile(fp, manifestJSON, 0o644) if err != nil { diff --git a/server/modelpath.go b/server/modelpath.go index c6798a02..13b26eeb 100644 --- a/server/modelpath.go +++ b/server/modelpath.go @@ -85,20 +85,27 @@ func (mp ModelPath) GetShortTagname() string { return fmt.Sprintf("%s/%s/%s:%s", mp.Registry, mp.Namespace, mp.Repository, mp.Tag) } -func (mp ModelPath) GetManifestPath(createDir bool) (string, error) { +// modelsDir returns the value of the OLLAMA_MODELS environment variable or the user's home directory if OLLAMA_MODELS is not set. +// The models directory is where Ollama stores its model files and manifests. +func modelsDir() (string, error) { + if models, exists := os.LookupEnv("OLLAMA_MODELS"); exists { + return models, nil + } home, err := os.UserHomeDir() if err != nil { return "", err } + return filepath.Join(home, ".ollama", "models"), nil +} - path := filepath.Join(home, ".ollama", "models", "manifests", mp.Registry, mp.Namespace, mp.Repository, mp.Tag) - if createDir { - if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { - return "", err - } +// GetManifestPath returns the path to the manifest file for the given model path, it is up to the caller to create the directory if it does not exist. +func (mp ModelPath) GetManifestPath() (string, error) { + dir, err := modelsDir() + if err != nil { + return "", err } - return path, nil + return filepath.Join(dir, "manifests", mp.Registry, mp.Namespace, mp.Repository, mp.Tag), nil } func (mp ModelPath) BaseURL() *url.URL { @@ -109,12 +116,12 @@ func (mp ModelPath) BaseURL() *url.URL { } func GetManifestPath() (string, error) { - home, err := os.UserHomeDir() + dir, err := modelsDir() if err != nil { return "", err } - path := filepath.Join(home, ".ollama", "models", "manifests") + path := filepath.Join(dir, "manifests") if err := os.MkdirAll(path, 0o755); err != nil { return "", err } @@ -123,7 +130,7 @@ func GetManifestPath() (string, error) { } func GetBlobsPath(digest string) (string, error) { - home, err := os.UserHomeDir() + dir, err := modelsDir() if err != nil { return "", err } @@ -132,7 +139,7 @@ func GetBlobsPath(digest string) (string, error) { digest = strings.ReplaceAll(digest, ":", "-") } - path := filepath.Join(home, ".ollama", "models", "blobs", digest) + path := filepath.Join(dir, "blobs", digest) dirPath := filepath.Dir(path) if digest == "" { dirPath = path