Linux concept: distribution
Nobody installs "Linux". You install Ubuntu, Debian, Fedora, Arch, or Alpine, and each one hands you the same kernel wrapped in a different set of programs, a different package manager, a different update rhythm, and a different idea of what a finished system should look like. Ask two administrators how to install a web server and you can get two different commands, both correct. The thing that decides which command is right on your machine is the Linux distribution, and once you understand what a distribution actually is, half of the confusing differences between Linux systems suddenly make sense.
1. The Basics
A Linux distribution, or distro for short, is a complete operating system built around the Linux kernel. The kernel on its own is only the core program that talks to the hardware (see the kernel article). It cannot list a directory, run a shell script, or install software. Everything you actually work with comes from somewhere else, and a distribution is the project that collects all those pieces, makes them work together, and keeps them updated for years.
A distribution makes a long list of decisions for you. Which version of the kernel to ship. Which C library every program links against. Which shell sits behind /bin/sh. Which init system starts your services. Which package format and package manager you use to install software. How often a new release comes out, and how long each release receives security fixes. Two distributions can share every single upstream program and still feel completely different because they made different decisions on that list.
The right mental model: the kernel is the engine, and a distribution is the whole car built around it, plus the garage that services it. Two cars can share an engine and still differ in everything you touch, and in how long the garage keeps fixing them.
This article explains what a distribution is made of, where the families come from, how you find out which one you run, how the differences show up in daily work, and why the version numbers a distribution shows you are often not what they seem. The examples are verified on Ubuntu 24.04, and against Debian 13, Fedora 44, Arch Linux, AlmaLinux 9, openSUSE Leap 16.0 and Alpine 3.23 running as containers on the same machine.
1.1 Seeing Which Distribution You Run
Every modern distribution describes itself in one small text file, /etc/os-release. It is the first thing to read on any unfamiliar server:
$ cat /etc/os-release
PRETTY_NAME="Ubuntu 24.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="24.04"
VERSION="24.04.5 LTS (Noble Numbat)"
VERSION_CODENAME=noble
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
...
The PRETTY_NAME line is for humans. The ID and VERSION_ID lines are for scripts. The ID_LIKE line is the most interesting one: it says which distribution this one is derived from. Ubuntu says debian, and that one word tells you that almost everything you know about Debian also works here.
1.2 The Layers of a Distribution
It helps to see a distribution as a stack. Only the bottom layer is strictly "Linux":
YOUR SOFTWARE web server, database, PHP, your application
|
DISTRO CHOICES package manager, repositories, init system, defaults
|
USERLAND shell, ls/cp/grep, C library, compilers
|
KERNEL Linux: hardware, processes, memory, filesystems
The kernel is shared by every distribution. The userland comes mostly from upstream projects such as GNU, and is also largely shared. The layer that really separates one distribution from another is the one in the middle: the choices, the packaging, and the people who maintain it.
1.3 What Actually Differs Between Distributions
These are the differences you notice first, side by side for the distributions tested for this article:
| Distribution | Package manager | C library | Release model |
|---|---|---|---|
| Debian | apt / dpkg (.deb) |
glibc | Fixed releases, about every two years |
| Ubuntu | apt / dpkg (.deb) |
glibc | Every six months, an LTS every two years |
| Fedora | dnf / rpm (.rpm) |
glibc | Fixed releases, short support |
| AlmaLinux | dnf / rpm (.rpm) |
glibc | Follows Red Hat Enterprise Linux |
| openSUSE Leap | zypper / rpm (.rpm) |
glibc | Fixed releases |
| Arch Linux | pacman |
glibc | Rolling: no versions at all |
| Alpine | apk |
musl | Fixed releases, very small base |
Notice that the package manager follows the family, not the individual distribution. Ubuntu uses Debian's tools; AlmaLinux uses Fedora's. Learn one member of a family and you can work on all of them.
Less visible, but just as real, is the choice of security module: the kernel feature that limits what a program may do even when it runs as root. Ubuntu uses AppArmor; its server documentation says it "is installed and loaded by default". Red Hat Enterprise Linux uses SELinux, and Red Hat's documentation calls enforcing mode "the default, and recommended, mode of operation". You can see which modules your kernel has active in one virtual file:
$ cat /sys/kernel/security/lsm # on Ubuntu 24.04
lockdown,capability,landlock,yama,apparmor,ima,evm
This difference explains a whole class of "works on Ubuntu, permission denied on RHEL" problems: the file permissions are identical, but a different security module is saying no.
1.4 Why There Are So Many Distributions
All of this software is open source, so anyone may take it, combine it differently, and share the result. People do that because there is no single right answer to the choices above. Every distribution is a different balance between a few goals that pull against each other:
| Goal | What it costs |
|---|---|
| Stability: versions that do not change for years | Older software and older hardware support |
| Freshness: the newest upstream versions | More change to test with every update |
| Small size: only what is strictly needed | Fewer tools on board, more compatibility differences |
| Long support: security fixes for many years | Slower adoption of new features, sometimes a subscription |
| Community governance: no single company in charge | No vendor to call when something breaks |
So the useful question is never "which distribution is best?" but "which balance fits this machine?" A laptop for development, a production web server and a container image have different answers, and that is why one administrator can run three distributions without contradiction.
Back to top2. Where the Name Comes From
The word distribution describes the original job quite literally. In the early 1990s, "installing Linux" meant collecting the kernel from one place, the GNU tools from another, a C library, a shell, and dozens of small programs from yet other places, compiling them, and making them fit together yourself. A distribution was someone who had already done that work and distributed the result as a ready-made set of disk images. You were not getting a different operating system, you were getting a delivery.
That is still the core of the word. A distribution writes very little of the software it ships. Its real product is the selection, the integration, the packaging, and the promise to keep delivering fixes. The short form distro is informal, but it is so common that you will see it in official documentation too.
The names of individual distributions often carry a story of their own:
- Debian is a contraction of the names of Debra and Ian Murdock, who founded the project. The project pronounces it "Deb-ee-en" (Debian FAQ).
- Ubuntu is, in the project's own words, "an ancient African word meaning 'humanity to others'" (ubuntu.com/about).
- Release codenames are a distribution habit, not a Linux one. Debian names its releases after characters from Toy Story (Debian 13 is
trixie), Ubuntu uses an alliterating adjective and animal (24.04 is "Noble Numbat", codenamenoble). You will see these codenames in repository configuration files far more often than the version numbers.
3. A Short History
Linus Torvalds announced the Linux kernel in 1991, but a kernel alone is not something you can use. Within two years the first distributions appeared, and the families they started still shape almost every Linux system running today.
Two of the earliest are still alive. Slackware, by Patrick Volkerding, had its first beta release in April 1993. Debian was begun in August 1993 by Ian Murdock, then an undergraduate at Purdue University, as a distribution built and governed by a community of volunteers rather than by one person or company. Debian's packaging format, .deb, and later its apt tool became the base of an entire family.
Red Hat's distribution gave the world the other big packaging format, .rpm, and grew into Red Hat Enterprise Linux (RHEL), a commercial product with long support. Free rebuilds of RHEL followed, most famously CentOS. When the CentOS project ended CentOS Linux 8 on 31 December 2021 and shifted its focus to CentOS Stream, community projects such as AlmaLinux, which describes itself as "binary compatible with RHEL", stepped in to fill the gap.
In October 2004 Ubuntu 4.10 appeared, created by a small team of Debian developers who together founded the company Canonical. Ubuntu took Debian's packages and tools, added a fixed six-month release schedule, and made the desktop and server install friendly enough for a much wider audience.
| Year | Milestone |
|---|---|
| 1991 | Linus Torvalds announces the Linux kernel |
| 1993 | Slackware's first beta (April) and the start of Debian (August) |
| 2004 | Ubuntu 4.10 "Warty Warthog", built on Debian, released in October |
| 2012 | /etc/os-release proposed as one standard identity file for all distributions |
| 2021 | CentOS Linux 8 reaches end of life; RHEL-compatible rebuilds such as AlmaLinux take over |
| Today | Hundreds of distributions, almost all descended from a handful of families |
3.1 The Families
Most distributions are not built from scratch. They start from another distribution and change part of it. That creates family trees, and knowing the family is often more useful than knowing the name:
| Family | Members you will meet | Shared tools |
|---|---|---|
| Debian | Debian, Ubuntu, and everything built on Ubuntu | apt, dpkg, .deb |
| Red Hat | Fedora, RHEL, CentOS Stream, AlmaLinux | dnf, rpm, .rpm |
| SUSE | openSUSE Leap, SUSE Linux Enterprise Server | zypper, rpm, .rpm |
| Independent | Arch Linux, Alpine, Slackware | Each has its own |
The SUSE family shows that a package format and a package manager are two different things. openSUSE uses the same .rpm format as Fedora, but its own manager, zypper, and it names its own family in os-release:
$ grep -E '^(ID|ID_LIKE)=' /etc/os-release # inside an openSUSE Leap 16.0 container
ID="opensuse-leap"
ID_LIKE="suse opensuse"
$ rpm -qf /usr/bin/ls
coreutils-9.6-160000.2.2.x86_64
3.2 Fixed Releases versus Rolling Releases
The biggest philosophical split between distributions is not the package format, it is how they handle time.
A fixed-release distribution, such as Debian, Ubuntu, or AlmaLinux, freezes a set of software versions, tests them together, and releases them as one numbered version. For the life of that release, the versions stay the same; only bug and security fixes are added. This is what servers want: nothing changes underneath you unless you choose to upgrade.
A rolling-release distribution, such as Arch Linux, has no version numbers at all. You install once and keep updating, and every update can bring new upstream versions. Arch's own /etc/os-release shows this plainly:
$ cat /etc/os-release # inside an Arch Linux container
NAME="Arch Linux"
PRETTY_NAME="Arch Linux"
ID=arch
BUILD_ID=rolling
...
Neither model is better. Rolling gives you the newest software; fixed gives you predictability. The choice decides how much testing you have to do yourself before every update.
3.3 A Third Model: Image-Based and Declarative Systems
Both models above update a system one package at a time, in place. A newer group of distributions replaces the whole system in one step instead. Fedora Silverblue describes it plainly: "The whole system is updated in one go, and an update will not apply if anything goes wrong", and "a previous version of your system is always kept around". Its tool, rpm-ostree, calls itself "a hybrid image/package system".
NixOS goes one step further. You do not install and configure software by hand at all; you describe the whole machine in one file, /etc/nixos/configuration.nix, and nixos-rebuild switch builds that description and makes it the running system. Every change adds a new entry to the boot menu, so an earlier configuration is one reboot away.
The idea behind both is the safety net the kernel article describes for kernels, extended to the entire system: never change the working version, build a new one next to it and keep the old one bootable. The price is a different way of working, because the classic habit of editing a file under /usr or installing a quick package no longer fits.
3.4 My Five Switches in Nineteen Years
The families and release models above are not theory for me. I have used Linux since 2007, and every distribution change I made was one of the trade-offs from section 1.4:
| Year | Switch | Why | What it shows |
|---|---|---|---|
| 2007 | Ubuntu | A ready-made desktop to start with | A distribution saves you assembling the system yourself |
| 2011 | Ubuntu → Debian | I disliked the new Unity desktop | Same family: apt, .deb and my habits came along unchanged |
| 2012 | Debian → Arch Linux | I wanted a minimal system I assembled myself | Rolling release, pacman, full control |
| 2013 | Arch → Debian | USB drives stopped automounting during Arch's move from initscripts to systemd | A rolling release delivers big integration changes in the middle of normal updates |
| 2018 | Debian → Ubuntu | More modern and practical, and the distribution I met most on servers | One family on laptop and servers |
Today I run Ubuntu on my servers, Alpine in Docker containers, and antiX, a systemd-free distribution based on Debian Stable, on old hardware. Even my laptop starts as a minimal Ubuntu Server install: an Ansible playbook then adds the GNOME desktop and every program I use, so the laptop holds only what I need. It is a home-made version of the declarative idea from section 3.3: the machine is described in a file, not built up by hand.
None of those switches was a search for the best distribution. Each was a different answer to "which balance fits this machine?", and the answer changed when the job did.
Back to top4. Simple Use Cases
The first questions on any new server are always the same: what is this, which version, and how is it supported? The answers are all in a few files and commands.
4.1 Read os-release
You saw /etc/os-release above. It is the standard answer, and it exists on Debian, Ubuntu, Fedora, AlmaLinux, Arch and Alpine alike. Even a minimal container image ships it:
$ cat /etc/os-release # inside an Alpine container
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.23.3
PRETTY_NAME="Alpine Linux v3.23"
...
If a server is so old that it has no /etc/os-release, that fact alone tells you something important: it has not been upgraded in a very long time.
4.2 hostnamectl and lsb_release
On a system that runs systemd, hostnamectl prints the distribution together with the kernel and the hardware, which is a quick overview of the whole machine:
$ hostnamectl
Static hostname: xps
...
Operating System: Ubuntu 24.04.5 LTS
Kernel: Linux 7.0.0-34-generic
Architecture: x86-64
Older tutorials use lsb_release, where the -a flag (short for "all") prints everything it knows. It works on Ubuntu, but it is a separate package and is often missing on minimal and container installs, so do not rely on it in scripts:
$ lsb_release -a
Distributor ID: Ubuntu
Description: Ubuntu 24.04.5 LTS
Release: 24.04
Codename: noble
4.3 Distribution Version Is Not Kernel Version
This one confuses people constantly. The distribution has a version, and the kernel has a completely separate version:
$ grep VERSION_ID /etc/os-release
VERSION_ID="24.04"
$ uname -r
7.0.0-34-generic
24.04 is Ubuntu's release, named after its year and month: April 2024. 7.0.0 is the Linux kernel, which on this laptop is much newer than the distribution, because Ubuntu offers newer kernels to LTS releases for newer hardware. When a vendor asks "which Linux version?", they almost always want both numbers.
4.4 Finding Out How Long Your Release Is Supported
Every fixed release has an end date, after which it no longer receives security fixes. That date is the single most important fact about a server's operating system, and the numbers are very different per distribution:
| Distribution | Support | Source |
|---|---|---|
| Ubuntu LTS | About five years of standard support (24.04: April 2024 to May 2029), longer with the paid Ubuntu Pro | ubuntu.com/about |
| Debian stable | Regular security support, then Debian LTS extends every stable release to at least five years | wiki.debian.org/LTS |
| Arch Linux | No end date, because there is no release: you stay supported by updating continuously | Arch wiki |
Look up the date for your exact release on the distribution's own site, and write it down next to the server's name. A server that quietly passes that date keeps running perfectly; it simply stops getting fixed.
4.5 Moving to the Next Release
The way out of an ending release is an in-place upgrade to the next one, and each family has its own procedure. On Ubuntu it is one command, and Ubuntu's documentation adds that "you can only upgrade from one LTS release directly to the next sequential LTS release". Whether the tool even offers non-LTS releases is set in a small configuration file:
$ grep Prompt /etc/update-manager/release-upgrades
Prompt=lts
$ sudo do-release-upgrade # Ubuntu: upgrade to the next release
Debian has no such tool. Its release notes tell you to change the codename in your APT sources (bookworm becomes trixie), then run apt update, apt upgrade --without-new-pkgs, and finally apt full-upgrade. Fedora uses a dnf command that downloads everything first and installs it during a reboot:
$ sudo dnf system-upgrade download --releasever=45 # Fedora: fetch the next release
$ sudo dnf system-upgrade reboot # install it during a restart
Whatever the family, read the release notes first and make a backup. A release upgrade replaces hundreds of packages at once, which is the riskiest moment in a fixed-release system's life.
Back to top5. Moderate Use Cases
Once you know which distribution you are on, the next step is to work with what makes it different: its package manager, its repositories, and its versions of the tools you use every day.
5.1 One Task, Five Package Managers
The most visible difference between families is the command you type to manage software. The ideas are the same everywhere; only the words change:
| Task | Debian / Ubuntu | Fedora / AlmaLinux | openSUSE | Arch | Alpine |
|---|---|---|---|---|---|
| Refresh package lists | apt update |
dnf makecache |
zypper refresh |
pacman -Sy |
apk update |
| Install a package | apt install nginx |
dnf install nginx |
zypper install nginx |
pacman -S nginx |
apk add nginx |
| Search | apt search nginx |
dnf search nginx |
zypper search nginx |
pacman -Ss nginx |
apk search nginx |
| Who owns this file? | dpkg -S FILE |
rpm -qf FILE |
rpm -qf FILE |
pacman -Qo FILE |
apk info --who-owns FILE |
In pacman, the capital letter is the operation: -S (short for "sync", install from the repositories) and -Q (short for "query", ask about installed packages). In rpm -qf, -q is "query" and -f is "file"; it works on openSUSE too, because zypper sits on top of the same rpm database. The apt side is covered in depth in the apt article.
5.2 Every File Belongs to a Package
On a distribution, almost every file outside your home directory and your data was put there by a package. Asking which package owns a file is how you find out where a program came from, what to reinstall when it breaks, and whose documentation to read:
$ dpkg -S /usr/bin/ls # Ubuntu
coreutils: /usr/bin/ls
$ rpm -qf /usr/bin/ls # Fedora
coreutils-9.10-5.fc44.x86_64
$ pacman -Qo /usr/bin/ls # Arch
/usr/bin/ls is owned by coreutils 9.12-2
$ apk info --who-owns /bin/ls # Alpine
/bin/ls symlink target is owned by busybox-1.37.0-r30
Three distributions give the same answer: ls comes from GNU coreutils. Alpine gives a different one, and that difference is the subject of section 6.4.
5.3 Repositories: Where the Software Comes From
A package manager installs from repositories: servers run by the distribution that hold its signed packages. Your system has a list of them, and on Ubuntu 24.04 it looks like this:
$ cat /etc/apt/sources.list.d/ubuntu.sources
Types: deb
URIs: http://nl.archive.ubuntu.com/ubuntu/
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
...
Read it as a sentence: fetch .deb packages from this mirror, for the noble release and its update channels, from these four sections, and only trust packages signed with this key. The codename appears again here; this is where it really matters. To see exactly which repository a package was installed from, ask apt-cache policy:
$ apt-cache policy coreutils
coreutils:
Installed: 9.4-3ubuntu6.3
Candidate: 9.4-3ubuntu6.3
Version table:
*** 9.4-3ubuntu6.3 500
500 http://nl.archive.ubuntu.com/ubuntu noble-updates/main amd64 Packages
500 http://security.ubuntu.com/ubuntu noble-security/main amd64 Packages
5.4 Same Command, Different Versions
Because each distribution freezes its own set of upstream versions, the "same" command can be a different program on each machine. Here is ls on the six systems tested for this article, all on the same day:
| Distribution | Provides ls | Why |
|---|---|---|
| Ubuntu 24.04 | GNU coreutils 9.4 | LTS release, frozen in 2024 |
| Debian 13 | GNU coreutils 9.7 | Newer stable release |
| Fedora 44 | GNU coreutils 9.10 | Fast release cycle |
| Arch Linux | GNU coreutils 9.12 | Rolling: always close to upstream |
| Alpine 3.23 | BusyBox 1.37.0 | A different program altogether |
Usually this does not matter. Sometimes a flag you rely on exists in one version and not in another, and a command copied from a blog post fails on your server for no visible reason. When that happens, the first question is "which distribution and which release is this?"
Back to top6. Advanced Use Cases
The sections above were about reading. This section is about the places where distribution differences bite: scripts that must run everywhere, version strings you need to decode, containers, and binaries that refuse to run.
6.1 Writing Scripts That Know the Distribution
/etc/os-release is designed to be read by scripts. Its format is simple shell variable assignments, so a script can load it with the . command and then test the variables:
#!/bin/sh
. /etc/os-release
case "$ID" in
debian|ubuntu) pkg="apt-get install -y" ;;
fedora|almalinux|rhel) pkg="dnf install -y" ;;
opensuse-leap) pkg="zypper install -y" ;;
arch) pkg="pacman -S --noconfirm" ;;
alpine) pkg="apk add" ;;
*) echo "Unknown distribution: $ID" >&2; exit 1 ;;
esac
That works until someone runs your script on a distribution you have never heard of. That is what ID_LIKE is for. The os-release manual says build scripts "should check this variable if they need to identify the local operating system and the value of ID= is not recognized". AlmaLinux, for example, declares three relatives, closest first:
$ grep -E '^(ID|ID_LIKE)=' /etc/os-release # inside an AlmaLinux 9 container
ID="almalinux"
ID_LIKE="rhel centos fedora"
So a robust script checks ID first, then walks through ID_LIKE. A distribution derived from Ubuntu will usually say ID_LIKE contains ubuntu or debian, and your apt branch will just work. Note that the format deliberately supports no shell features beyond plain assignments, so other programs can parse the file without a shell. The full field list is in man os-release and on the systemd documentation site.
6.2 Reading a Distribution's Version String
A package version on a distribution is not the upstream version. It is the upstream version plus the distribution's own history of changes. Take the SSH client on Ubuntu 24.04:
$ dpkg -l openssh-client | tail -1
ii openssh-client 1:9.6p1-3ubuntu13.19 amd64 secure shell (SSH) client, ...
Read 1:9.6p1-3ubuntu13.19 from left to right:
| Part | Meaning |
|---|---|
1: |
The epoch: a counter the packagers bump when a version scheme changes, so that newer always sorts higher |
9.6p1 |
The upstream version: what the OpenSSH project released |
-3 |
The Debian revision: the third Debian packaging of that upstream version |
ubuntu13.19 |
Ubuntu's own changes on top of Debian's package, revised many times since |
That one string tells the whole family story from section 3.1: upstream code, packaged by Debian, changed again by Ubuntu. RPM-based distributions encode the same idea differently; coreutils-9.10-5.fc44 means upstream 9.10, Fedora's fifth build, for Fedora 44.
6.3 Distributions in Containers
When you write FROM debian or FROM alpine in a Dockerfile, you are choosing a distribution. A container image contains a distribution's userland, its package manager and its /etc/os-release, but not a kernel. Every container on a host uses the host's kernel:
$ uname -r # the Ubuntu host
7.0.0-34-generic
$ docker exec web uname -r # an Alpine container on it
7.0.0-34-generic
$ docker exec web grep PRETTY /etc/os-release
PRETTY_NAME="Alpine Linux v3.23"
This Alpine container is not a demo: it is the Apache container from my own local Joomla development stack, running on this Ubuntu laptop. The container honestly reports itself as Alpine, and it honestly runs on Ubuntu's kernel. Both are true, because a distribution and a kernel are different layers. This is the practical proof of the stack in section 1.2. The Docker article explains the kernel features that make this possible.
A virtual machine is the opposite case. It emulates a whole computer, so the guest boots its own kernel, and a Debian VM really does run a Debian kernel. If you need a different kernel version or kernel settings than the host, you need a VM, not a container.
A container image is also not always a complete distribution. Base images are trimmed hard, and the smallest ones may have no init system, no shell, or no package manager at all. That is normal: an image only has to run one application, not boot a machine.
6.4 When a Binary Will Not Run: glibc versus musl
Almost every distribution uses the GNU C library, glibc. Alpine is different: it is "built around musl libc and busybox". The C library is the layer that nearly every program calls for basic things such as opening files, so a program compiled against glibc expects glibc to be there. Copy the ls binary from Ubuntu into an Alpine container and try to run it:
$ file /usr/bin/ls
/usr/bin/ls: ELF 64-bit LSB pie executable, x86-64, ... interpreter /lib64/ld-linux-x86-64.so.2 ...
$ docker run --rm -v /usr/bin/ls:/tmp/ls:ro httpd:alpine sh -c '/tmp/ls /'
sh: /tmp/ls: not found
"Not found" for a file that clearly exists is one of the most confusing errors in Linux. The file is there. What is missing is the interpreter named inside it, /lib64/ld-linux-x86-64.so.2, glibc's program loader, which Alpine does not have. Alpine has its own, musl's:
$ docker exec web sh -c 'ls /lib/ld-musl*'
/lib/ld-musl-x86_64.so.1
The same thing happens with a downloaded binary built for one family and run on another, or with a pre-built language package (a PHP extension, a Python wheel, a Node module) that was compiled for glibc. The fix is to install the distribution's own package, or a build made for musl. That is what the PHP image of my own Joomla development stack does: it starts from php:8.3.26-fpm-alpine, installs g++, make and the ImageMagick -dev headers, and compiles the imagick extension with pecl inside the image, so the result links against musl rather than glibc. A binary is only portable between distributions that share its C library.
6.5 Alpine's Commands Are BusyBox
The apk info --who-owns answer in section 5.2 hinted at it: on Alpine, ls is not GNU ls at all. It is a symbolic link to BusyBox, one single program that behaves like ls, cp, sh and hundreds of other commands depending on the name it was called by:
$ docker exec web ls -l /bin/ls /bin/sh
lrwxrwxrwx 1 root root 12 Jan 28 2026 /bin/ls -> /bin/busybox
lrwxrwxrwx 1 root root 12 Jan 27 2026 /bin/sh -> /bin/busybox
$ docker exec web ls --version
ls: unrecognized option: version
That is why Alpine images are so small, and why GNU-only flags from a tutorial can fail inside them. The default shell differs per distribution too: on Debian and Ubuntu, /bin/sh is dash; on Fedora, it is bash; on Alpine, it is BusyBox. A script that starts with #!/bin/sh gets a different shell on each. The POSIX article explains how to write scripts that survive that.
6.6 Software That Bypasses the Distribution
Not everything on a modern system comes through the distribution's own repositories. Formats such as snap and Flatpak ship an application together with the libraries it needs, so the same package runs on many distributions. Ubuntu 24.04 goes further and delivers Firefox this way. The Firefox .deb is only a placeholder that points at the snap:
$ dpkg -l firefox | tail -1
ii firefox 1:1snap1-0ubuntu5 amd64 Transitional package - firefox -> firefo...
$ snap list firefox
Name Version Rev Tracking Publisher Notes
firefox 157.0-1 8995 latest/stable/... mozilla** -
Look at the Publisher column: this Firefox is built and updated by Mozilla, not by Ubuntu. That changes who is responsible for the fixes. Everything section 7.1 says about distribution maintainers backporting security patches applies to the packages from the distribution's repositories. A snap, a Flatpak, a container image or a binary you downloaded is patched by whoever published it, on their schedule, and apt upgrade does not touch it. On a server, keep a list of what came from where, and check each source separately.
7. Something Most Users Do Not Know
7.1 Old Version Numbers Can Be Fully Patched
A security scanner looks at the server above, sees OpenSSH 9.6p1, and reports a long list of vulnerabilities fixed in newer upstream versions. In many cases the server is not vulnerable at all.
A fixed-release distribution promises not to change versions during a release, because a new upstream version can change behaviour and break things. So when a security hole is found, the distribution's maintainers take only the fix from the newer version and apply it to the old one. This is called backporting. The upstream number stays 9.6p1; only the distribution suffix grows. The changelog shows the fixes that went in:
$ zcat /usr/share/doc/openssh-client/changelog.Debian.gz | grep -c CVE-
64
So on a distribution, the upstream version number tells you very little about security. The full package version and the distribution's own security notices do. This is also why "upgrade to the latest upstream version" is usually the wrong advice for a stable server: the distribution is already doing that work, more carefully.
7.2 Ubuntu Thinks It Is a Debian That Was Never Released
Debian distributions have kept a small file called /etc/debian_version since long before os-release existed. Ubuntu inherits it, and it says something surprising:
$ cat /etc/debian_version # on Ubuntu 24.04
trixie/sid
$ cat /etc/debian_version # on real Debian 13
13.7
Ubuntu is not built from a finished Debian release. Every six months it takes a snapshot of Debian's development branch, still unfinished at the time, and builds on that. trixie/sid means "the work that would later become Debian 13, taken from the development stream". The file is a fossil of exactly where Ubuntu 24.04 branched off its parent.
7.3 /etc/os-release Is Younger Than Most Distributions
For about twenty years every family had its own way to say who it was: /etc/debian_version, /etc/redhat-release, /etc/lsb-release, and many more. Scripts had to check them all. In February 2012 the systemd developers proposed os-release as one standard file for everyone, and it was so useful that even distributions that do not use systemd, such as Alpine, adopted it. The old files are still there, because old scripts still read them:
$ cat /etc/redhat-release # inside a Fedora container
Fedora release 44 (Forty Four)
And the file you read is usually not even in /etc. The specification says the vendor's copy belongs in /usr/lib/os-release, with /etc/os-release as a relative symbolic link to it:
$ ls -l /etc/os-release
lrwxrwxrwx 1 root root 21 Sep 6 16:29 /etc/os-release -> ../usr/lib/os-release
7.4 Where a Distribution Stops
It helps to know which questions are distribution questions and which are not:
- Hardware, drivers, and system calls are the kernel, shared by every distribution: see the kernel article.
- How services start and stop is the init system. Debian, Ubuntu, Fedora and Arch use systemd; Alpine uses OpenRC. See the systemd article.
- How software gets onto the machine is the package manager, which is the most distribution-specific part of all: see the apt article.
- Whether a command behaves the same everywhere is a standards question: see the POSIX article.
8. Best Practices
- Read
/etc/os-releasefirst. On any unfamiliar server, know the distribution, the release, and the family before you type a single install command. - Choose a fixed-release LTS distribution for servers. Predictable versions and years of security fixes matter far more on a production machine than having the newest software.
- Write down the end-of-support date. Keep it next to the server's name and plan the upgrade well before it. A server past that date still runs; it just stops being fixed.
- Install software from the distribution's repositories. Its packages are signed, tested together, and receive backported security fixes. A program you compile or download yourself is a program you have to patch yourself.
- Judge security by package version, not upstream version. Check the distribution's security notices or the package changelog before trusting a scanner that only reads the upstream number.
- Use
IDandID_LIKEin scripts. Never parsePRETTY_NAMEor/etc/issue; they are for humans and change format. - Match the C library when you copy binaries or build images. A glibc binary will not run on Alpine, and a "not found" error for a file that exists usually means exactly that.
- Keep the same family across your servers when you can. One package manager, one set of paths, one set of habits: fewer surprises at three in the morning.
- Read the documentation.
man os-releasedescribes every field, and each distribution's own handbook or wiki is the reference for its tools.
$ man os-release # every field of the identity file
$ man hostnamectl # system identity on systemd distributions
$ man dpkg # Debian family packages (rpm, pacman, apk elsewhere)
Back to top9. Common Mistakes
9.1 Myth versus Reality
| Myth | Reality |
|---|---|
| "I installed Linux." | You installed a distribution. Linux is only the kernel inside it. |
| "The distribution version and the kernel version are the same thing." | They are separate. Ubuntu 24.04 on this machine runs kernel 7.0.0. |
| "An old version number means the software is vulnerable." | Fixed-release distributions backport security fixes into the old version. Check the package version and the changelog. |
| "A Linux binary runs on any Linux." | Only on distributions with the same C library and the libraries it needs. A glibc binary fails on musl-based Alpine. |
| "A Debian container runs the Debian kernel." | Containers have no kernel of their own. They all use the host's kernel. |
| "Rolling releases are unstable, fixed releases are stable." | Both can be stable. They differ in when change arrives: continuously, or once per release. |
| "Every distribution is completely different." | Most belong to a few families and share the same package tools and habits. |
9.2 Other Traps to Avoid
- Copying install commands from a tutorial for another family. An
aptcommand does nothing useful on AlmaLinux. Check the family first, then translate the command with the table in section 5.1. - Mixing repositories from different releases or distributions. Adding a Debian repository to Ubuntu, or a newer release's repository to an older one, can pull in libraries that break the rest of the system.
- Forgetting the end-of-support date. The machine keeps working, which is exactly why nobody notices that it stopped receiving security fixes.
- Relying on
lsb_releasein scripts. It is often not installed on minimal systems and containers./etc/os-releaseis always there. - Assuming
/bin/shis bash. It isdashon Debian and Ubuntu and BusyBox on Alpine. Bash features in a#!/bin/shscript break there. - Choosing Alpine for a small image without testing. The size is real, but so are the musl and BusyBox differences. Test your application on it, not just your Dockerfile.
10. Summary
A Linux distribution is the complete operating system around the kernel: the userland, the C library, the package manager and repositories, the init system, the defaults, and the promise to keep it all patched for a defined number of years. The kernel is shared. Everything you notice in daily work, the commands, the versions, the update rhythm, is the distribution.
- A distribution (or distro) bundles the Linux kernel with upstream software, packages it, and maintains it; the name comes from literally distributing that bundle.
/etc/os-releaseidentifies the system:IDandVERSION_IDfor scripts,ID_LIKEfor the family,PRETTY_NAMEfor humans.- There are so many distributions because each one strikes a different balance between stability, freshness, size, support length and governance.
- Most distributions belong to a family: Debian (
apt,.deb), Red Hat (dnf,.rpm), SUSE (zypper,.rpm), or an independent one such as Arch or Alpine. - Distributions also choose the security module: AppArmor on Ubuntu, SELinux on Red Hat Enterprise Linux.
- Slackware and Debian both started in 1993; Ubuntu followed in 2004, built on Debian; AlmaLinux and other rebuilds filled the gap after CentOS Linux 8 ended in 2021.
- Fixed releases freeze versions and backport fixes; rolling releases such as Arch update continuously and have no version number; image-based systems such as Fedora Silverblue and NixOS replace the whole system in one step and keep the previous one bootable.
- Every fixed release ends;
do-release-upgrade, Debian's codename switch plusapt full-upgrade, anddnf system-upgrademove you to the next one. - The distribution version and the kernel version are different numbers; you usually need both.
- Every file belongs to a package:
dpkg -S,rpm -qf,pacman -Qo,apk info --who-owns. - A distribution package version such as
1:9.6p1-3ubuntu13.19contains the upstream version plus the distribution's own revisions, so an old upstream number can still be fully patched. - Containers carry a distribution's userland but use the host's kernel; a virtual machine boots its own.
- Snaps, Flatpaks, container images and downloaded binaries bypass the distribution, so their publisher, not the distribution, is responsible for patching them.
- Binaries are tied to their C library: a glibc program reports "not found" on musl-based Alpine, whose commands are BusyBox.
This is the quick reference worth keeping:
cat /etc/os-release which distribution, release and family
. /etc/os-release; echo "$ID" the distribution ID inside a script
hostnamectl distribution, kernel and hardware at once
uname -r the kernel version (not the distro version)
cat /etc/debian_version Debian family: the parent release
dpkg -S FILE Debian/Ubuntu: which package owns a file
rpm -qf FILE Fedora/RHEL/SUSE: which package owns a file
pacman -Qo FILE Arch: which package owns a file
apk info --who-owns FILE Alpine: which package owns a file
apt-cache policy PKG Debian/Ubuntu: installed version and its repository
cat /sys/kernel/security/lsm active security modules (apparmor, selinux)
snap list software that bypasses the distribution
sudo do-release-upgrade Ubuntu: move to the next release
file BINARY which loader (glibc or musl) a program expects
man os-release every field explained
And if a security scan flags a server as dangerously out of date while every update has been installed, the answer is often a distribution that quietly backported the fixes and kept the old version number.
Back to top

Peter is a Joomla specialist and a Linux admin for fast, secure and scalable websites.












