The official way to install Ollama on Linux is one line, curl -fsSL https://ollama.com/install.sh | sh, and on a bare Ubuntu 24.04 it fails the first time. This post runs that line in a throwaway Ubuntu 24.04 container, reads what the script does with and without systemd, starts the server by hand, pulls a model, and then compares the result with the two installs already on this PC: the systemd service inside WSL and the Windows app. Every output is quoted from the run, including the error that stops most people.

Do it yourself
  1. On Ubuntu or WSL: sudo apt-get update && sudo apt-get install -y curl ca-certificates zstd. The last package is the one the installer will ask for
  2. On WSL only, before installing: put [boot] and systemd=true in /etc/wsl.conf and restart the distribution, so the installer can create its service
  3. curl -fsSL https://ollama.com/install.sh | sh; expect a 1.4 GB download
  4. With systemd: the service is already running, check with systemctl is-active ollama. Without: ollama serve in a second terminal
  5. curl localhost:11434/api/version, then ollama pull qwen2.5:0.5b and ollama run qwen2.5:0.5b "Say hello in five words."
  6. ollama ps shows where it ran, GPU or CPU; ollama list and ollama rm manage what you keep

The one-liner on a bare Ubuntu 24.04

The container started with nothing: no curl, no zstd, no systemctl. After installing curl, the official line ran for 45 seconds and stopped:

>>> Installing ollama to /usr/local
ERROR: This version requires zstd for extraction. Please install zstd and try again:
  - Debian/Ubuntu: sudo apt-get install zstd
  - RHEL/CentOS/Fedora: sudo dnf install zstd
  - Arch: sudo pacman -S zstd

The 45 seconds were not a download. The script sends a HEAD request for the archive before it checks for the zstd command, so the wait comes first and the complaint second. It had also already created /usr/local/lib/ollama, which is why the next run opens by cleaning up an old version that was never installed. After apt-get install -y zstd the same line finished in 97 seconds:

>>> Cleaning up old version at /usr/local/lib/ollama
>>> Installing ollama to /usr/local
>>> Downloading ollama-linux-amd64.tar.zst
######################################################################## 100.0%
>>> The Ollama API is now available at 127.0.0.1:11434.
>>> Install complete. Run "ollama" from the command line.
>>> The Ollama API is now available at 127.0.0.1:11434.
>>> Install complete. Run "ollama" from the command line.

The archive is 1.44 GB and the script never prints that; it streams the download through zstd and tar straight into /usr/local, 2.1 GB on disk with the CUDA and Vulkan libraries, and leaves nothing in a temp folder. The closing lines appear twice because Docker Desktop containers run on the WSL2 kernel, which sends the script down its WSL2 branch, and that branch reports success once itself and once from its exit trap. The same doubling is what a WSL distribution sees. Note the last-but-one line: it says the API is available even when nothing is running, as the next section shows.

With systemd and without

Without systemctl, the script skips its whole service section in silence. There is no warning, and afterwards id ollama answers id: 'ollama': no such user: no user, no group, no service file, no /usr/share/ollama. You have a binary and nothing else, and the "API is now available" line is simply untrue until you start a server yourself. With systemd installed, even when it is not running, the same script does the rest and says what it is doing:

>>> Creating ollama user...
>>> Adding ollama user to video group...
>>> Adding current user to ollama group...
>>> Creating ollama systemd service...
WARNING: systemd is not running
WARNING: see https://learn.microsoft.com/en-us/windows/wsl/systemd#how-to-enable-systemd to enable it

The unit it writes, in full:

[Unit]
Description=Ollama Service
After=network-online.target

[Service]
ExecStart=/usr/local/bin/ollama serve
User=ollama
Group=ollama
Restart=always
RestartSec=3
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

[Install]
WantedBy=default.target

That is the WSL lesson in one block. A distribution without systemd gets the warning and the link; a distribution with systemd=true in /etc/wsl.conf gets a service that runs ollama serve as the ollama user every time the distribution starts, which is exactly what the Ubuntu-24.04 distribution on this PC has, down to the same unit. One thing to know about that unit on WSL: the PATH the script copies into it is the shell's PATH at install time, and on WSL that includes the whole Windows PATH with your user name in it, so read the unit before you paste it anywhere. Put settings such as OLLAMA_HOST in a drop-in file under /etc/systemd/system/ollama.service.d/, not in the unit the script owns.

Starting it by hand, and the first model

In the container, ollama serve run as root generated a key pair under /root/.ollama and announced itself:

msg="Listening on 127.0.0.1:11434 (version 0.40.4)"

The GPU discovery found only the CPU, 15.5 GiB visible, because no GPU is passed into the container. Pulling the smallest useful model took 18 seconds:

pulling manifest
pulling c5396e06af29: 100% ... 397 MB
pulling 005f95c74751: 100% ... 490 B
verifying sha256 digest
writing manifest
success

ollama run qwen2.5:0.5b "Say hello in five words." answered Hello, how are you? in 1.3 seconds on the CPU, four words rather than five, which is a fair summary of a 0.5B model. ollama ps then showed the model loaded with 100% CPU under PROCESSOR, the column to read when you want to know whether your GPU is being used at all. The models folder was 380 MB, and ollama rm qwen2.5:0.5b took it back to 20 KB. Both pull and run write cursor codes and a spinner even when piped to a file, so a captured log looks like noise until it is rendered.

Where the models live

SetupHow the server runsModels folderSize on this PC
Container, script without systemctlollama serve by hand, as root/root/.ollama/models380 MB with one small model
WSL Ubuntu-24.04, script with systemdsystemd unit, user ollama/usr/share/ollama/.ollama/models14 GB
Windows tray appper-user app%USERPROFILE%\.ollama\models30.2 GiB

One rule covers all three: models go to .ollama/models in the home directory of the user who runs the server; the ollama command you type is only a client and stores nothing. That is why the WSL folder is not readable by the normal user (it belongs to ollama), why a server you start by hand on WSL will not see the service's models, and why this PC holds three of its models twice, once per side. The uninstall section of the Linux documentation removes /usr/share/ollama as "the downloaded models", which is right for the service install only. OLLAMA_MODELS moves the folder for any of them.

The manual route in the documentation

The Linux page also gives a manual install: download the archive and pipe it into tar x -C /usr. On Ubuntu 24.04, with zstd installed, that exact command fails:

tar: Archive is compressed. Use --zstd option
tar: Error is not recoverable: exiting now
curl: (23) Failure writing output to destination

With --zstd added it worked, silently, in 99 seconds, and put the same 0.40.4 binary in /usr/bin rather than /usr/local/bin. The page's service unit also differs from the script's in one line, WantedBy=multi-user.target against default.target. The tar error has a Fixes post, as does the installer's own zstd message.

Which install do you have?

Three versions were on this PC at the end of the run: 0.40.4 in the container (installed today), 0.34.2 as the WSL service (installed in September), and 0.40.3 as the Windows app, which updates itself. Rerunning the one-liner is the documented upgrade path for Linux and WSL, and it downloads the full archive again. If Windows and WSL both run Ollama on the same PC, they both want port 11434, and which one answers from where is the subject of Ollama ports, OLLAMA_HOST and 11434.

Frequently asked

How do I install Ollama on Linux?
Install curl, ca-certificates and zstd with your package manager, then run the official line curl -fsSL https://ollama.com/install.sh | sh. It downloads a 1.4 GB archive into /usr/local and, when systemd is present, creates an ollama user and group and a service that starts ollama serve at boot. Without systemd it installs only the binary, and you start ollama serve yourself.
Why does the Ollama installer say it requires zstd?
The Linux archive is compressed with zstd, and the script extracts it with the zstd command, which a bare Ubuntu 24.04 does not have. Install it with sudo apt-get install zstd (or dnf, or pacman, as the message says) and run the installer again; the second run begins by cleaning up the folder the first run created.
Where does Ollama store models on Linux?
In .ollama/models under the home directory of the user that runs ollama serve: /usr/share/ollama/.ollama/models for the systemd service, which runs as the ollama user, or /root/.ollama/models or your own home when you start the server by hand. Set OLLAMA_MODELS in the server's environment to move it. The ollama client command stores nothing.

What to do with the server once it runs, from the first chat to a private clinic assistant, is the series From Prompt to Private. The errors on the way are in the Fixes category.