Knowing exactly which Ubuntu version a server runs sounds like a question with one answer — but Linux gives you at least five commands that report it, and each one tells you something slightly different. This guide covers the ones worth knowing, when each is the right tool, and the cross-distro version that works regardless of what distribution you're actually on.

## The fastest answer

If you just want the version and you're on Ubuntu (or any modern Debian-based system):

```
lsb_release -a
```

```
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 24.04.1 LTS
Release: 24.04
Codename: noble
```

That's the canonical answer. `Description` gives you the marketing name (`Ubuntu 24.04.1 LTS`), `Release` gives you the numeric version you'd write in a Dockerfile (`24.04`), and `Codename` gives you the adjective-animal name Ubuntu releases get (`noble`, `jammy`, `focal`).

If `lsb_release: command not found`, install the package — on Ubuntu Server minimal installs it's not preinstalled:

```
sudo apt-get install -y lsb-release
```

## The cross-distro answer: `/etc/os-release`

Every distribution that uses systemd ships an `/etc/os-release` file with standardised fields. It's the right command to reach for in any script that might run across multiple distros (Ubuntu, Debian, AlmaLinux, Rocky, Fedora, Amazon Linux, Alpine):

```
cat /etc/os-release
```

```
PRETTY_NAME="Ubuntu 24.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="24.04"
VERSION="24.04.1 LTS (Noble Numbat)"
VERSION_CODENAME=noble
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
```

To extract just one field — useful in shell scripts:

```
. /etc/os-release # source it as shell variables
echo "$ID $VERSION_ID" # ubuntu 24.04
echo "$VERSION_CODENAME" # noble
```

`ID` is the lowercase distribution identifier (`ubuntu`, `debian`, `almalinux`, `rocky`, `rhel`, `amzn`, `alpine`), and `VERSION_ID` is the major version. Those two are the right pair to branch on in a portable deploy script — see the [Linux distros for deployment guide](https://www.deployhq.com/blog/linux-distros-for-deployment) for context on which IDs your servers might actually report.

## `hostnamectl` — systemd's built-in

`hostnamectl` was designed for setting the hostname, but it also dumps OS metadata as a side effect:

```
hostnamectl
```

```
Static hostname: web-prod-01
       Icon name: computer-vm
         Chassis: vm
      Machine ID: 7c3d8a9e2f1b4c6d8e0f1a2b3c4d5e6f
         Boot ID: a1b2c3d4e5f60718293a4b5c6d7e8f90
  Virtualization: kvm
Operating System: Ubuntu 24.04.1 LTS
          Kernel: Linux 6.8.0-31-generic
    Architecture: x86-64
```

It's the most informative single command — it tells you the distro version _and_ the kernel _and_ whether you're running in a VM. On any systemd system it works without extra packages installed.

## `uname` — kernel, not distro

`uname` reports the kernel, which is not the same thing as the distribution. Treating it as a distro check is one of the most common mistakes:

```
uname -a
```

```
Linux web-prod-01 6.8.0-31-generic #31-Ubuntu SMP PREEMPT_DYNAMIC Thu May 30 21:00:00 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
```

The output mentions Ubuntu, but that's part of the Ubuntu-specific kernel build identifier. On an Amazon Linux box running a Red Hat-flavoured kernel you'd see `.el9.x86_64` instead. `uname -r` alone gives you the kernel version (`6.8.0-31-generic`), which matters when you're checking module compatibility, but it doesn't tell you whether the distro is Ubuntu 22.04 or 24.04.

Use `uname` for kernel-related decisions, not distribution-version decisions.

## `/etc/issue` and `/etc/issue.net` — the legacy options

Some older guides recommend these:

```
cat /etc/issue
```

```
Ubuntu 24.04.1 LTS \n \l
```

The `\n` and `\l` are escape sequences expanded at login time (hostname and tty line). `/etc/issue` is what gets shown above the login prompt on a serial console. It's editable as a free-form file, so on hardened or customised systems it might contain a banner instead of the OS version. Don't rely on it in scripts — `/etc/os-release` is the right substitute.

## Cross-distro examples — what you'll see on each

The output of `/etc/os-release` on the other distros covered earlier:

**Debian 12:**

```
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
```

**AlmaLinux 9:**

```
NAME="AlmaLinux"
VERSION="9.4 (Seafoam Ocelot)"
ID="almalinux"
ID_LIKE="rhel centos fedora"
VERSION_ID="9.4"
PLATFORM_ID="platform:el9"
PRETTY_NAME="AlmaLinux 9.4 (Seafoam Ocelot)"
```

**Amazon Linux 2023:**

```
NAME="Amazon Linux"
VERSION="2023"
ID="amzn"
ID_LIKE="fedora"
VERSION_ID="2023"
PRETTY_NAME="Amazon Linux 2023.5.20240805"
PLATFORM_ID="platform:al2023"
```

**Alpine 3.20:**

```
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.20.3
PRETTY_NAME="Alpine Linux v3.20"
HOME_URL="https://alpinelinux.org/"
```

Notice that AlmaLinux and Amazon Linux both set `ID_LIKE` to `fedora` / `rhel` — that's the field to branch on when you want anything in the RHEL family rather than a specific distro. Debian-derivatives (Ubuntu, Mint) set `ID_LIKE=debian`.

## Scripting version checks in CI

A common pattern in deploy scripts: gate a step on the distro and version. The portable version:

```
#!/usr/bin/env bash
set -euo pipefail

. /etc/os-release

case "$ID" in
  ubuntu|debian)
    sudo apt-get update
    sudo apt-get install -y nginx
    ;;
  almalinux|rocky|rhel|fedora|amzn)
    sudo dnf install -y nginx
    ;;
  *)
    echo "Unsupported distro: $ID" >&2
    exit 1
    ;;
esac
```

For an exact-version check (some deploy steps only support specific versions):

```
. /etc/os-release

if [["$ID" == "ubuntu" && "$VERSION_ID" == "24.04"]]; then
  echo "Detected Ubuntu 24.04 — using the noble apt source"
fi
```

The `[[...]]` test treats `VERSION_ID` as a string, which is what you want — `24.04` is a label, not a number. (Bash float arithmetic would interpret `24.04` and `24.10` as `24.04` and `24.1` respectively, which is exactly the wrong thing.)

For richer version comparisons (greater-than-or-equal), use `dpkg --compare-versions` on Debian-family or `rpm -q --qf` on RHEL-family rather than rolling your own.

## Container-specific: how `cat /etc/os-release` behaves inside containers

Inside a Docker container, `cat /etc/os-release` reports the _image's_ distro, not the host's. A Debian-slim container running on an Amazon Linux host:

```
docker run --rm debian:12-slim cat /etc/os-release
```

```
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
ID=debian
```

That's usually what you want — the script inside the container should see the container's filesystem. But it does mean what distro is this server? gives different answers depending on whether you're asking the host or a container. The host answer comes from `cat /etc/os-release` on the bare metal; the container answer comes from inside `docker exec`.

For Kubernetes nodes, the right place to check the host OS is via the kubelet's `nodeInfo` field (`kubectl get nodes -o wide`) or by `ssh`'ing into the node directly.

## Related deploys

Knowing your distro version unlocks the rest of the server-ops command set:

- [Essential Linux server commands for deployment](https://www.deployhq.com/blog/essential-linux-server-commands-for-deployment) — disk space, memory, process and log inspection that come up every release.
- [Deploying WordPress on a VPS](https://www.deployhq.com/blog/deploying-a-wordpress-application-on-a-vps-a-beginner-s-guide) — distro-version-specific install steps for the most common LAMP stack.
- [Installing cPanel on Ubuntu 22.04](https://www.deployhq.com/blog/installing-cpanel-on-ubuntu-22-04-and-deployhq) — Ubuntu version specificity matters here because cPanel only supports specific point releases.
- [Installing Keycloak on a VPS](https://www.deployhq.com/blog/simplifying-authentication-a-comprehensive-guide-to-installing-keycloak-on-a-vps) — Ubuntu-targeted but the version-check pattern carries.

For deploys themselves, [DeployHQ](https://www.deployhq.com) is distro-agnostic — the [build pipelines](https://www.deployhq.com/features/build-pipelines) feature runs your build inside a container, and the deploy lands on whichever Linux distribution your target servers happen to run. [Start a free trial](https://www.deployhq.com/signup) to wire any of these distros into a Git-driven deploy workflow.

* * *

Need help? Email [support@deployhq.com](mailto:support@deployhq.com) or follow [@deployhq on X](https://x.com/deployhq).

