TechEarl

How to Run Ubuntu, Debian, or Alpine in Docker (Try Linux Without Installing)

Try a Linux distro for ten minutes without a VM or dual-boot. One docker run command gets you an interactive Ubuntu, Debian, Alpine, or Fedora shell. Walk away when you're done; nothing left behind.

Ishan KarunaratneIshan Karunaratne⏱️ 6 min readUpdated
Share thisCopied

There are real reasons to want a Linux shell that isn't your host's: testing a script's portability, reading docs that assume a specific distro, learning Linux on a Windows or Mac machine, or making sure a tool works on Alpine before you commit to building a slim image. A VM is overkill for a 30-minute experiment. A docker run gives you a Linux shell in under three seconds.

How do I run Linux in Docker?

bash
# Ubuntu 24.04 LTS
docker run --rm -it ubuntu:24.04 bash

# Debian 12 (bookworm)
docker run --rm -it debian:12 bash

# Alpine 3.20 (very small, musl libc)
docker run --rm -it alpine:3.20 sh

# Fedora 41
docker run --rm -it fedora:41 bash

# Rocky Linux 9 (RHEL-compatible)
docker run --rm -it rockylinux:9 bash

--rm deletes the container when you exit, so nothing is left behind. -it gives you an interactive terminal. Replace bash with sh on Alpine (no bash by default).

When you exit, the container is gone. Anything you installed, every file you created, all gone. A new docker run is a fresh, untouched system.

What's NOT in a minimal image

Container images are stripped down. The things you take for granted on a real Linux install are often absent:

  • No sudo. You are root inside the container; sudo is unnecessary and usually not installed.
  • No systemd. Container processes run directly under PID 1. systemctl does not work.
  • No editors. vim, nano, less — not in the base image. Install them: apt update && apt install -y vim on Ubuntu/Debian, apk add vim on Alpine.
  • No ping, curl, wget, dig, ip, netstat. Networking tools are extras. apt install -y iputils-ping curl dnsutils iproute2.
  • No ps, top, kill -l. Many process tools come from procps: apt install -y procps.
  • Tiny package lists by default. Ubuntu official is ~30 MB. Alpine official is ~7 MB. Compare to a real install at multiple GB — the difference is everything except the bare minimum.

That's the trade-off of container images. The first thing most experiments need is apt update to refresh the package index.

Practical usage: a real session

A common case — checking whether a shell script works on Ubuntu 24.04 when you're on a Mac:

bash
docker run --rm -it -v "$(pwd):/work" -w /work ubuntu:24.04 bash

# Inside the container:
apt update
apt install -y curl jq
./my-script.sh

The bind mount (-v "$(pwd):/work") means your project on the host is at /work inside the container; the script sees your files. When you exit, the container is gone but the files on your host are unchanged (unless the script wrote to them — bind mounts go both ways).

Same shape for trying a tool that doesn't run on macOS or Windows natively. Need strace? Run an Ubuntu container with it.

Make changes persist across runs

--rm is the throwaway version. If you want your work to stick across multiple sessions, skip --rm, name the container, and docker start -ai it next time:

bash
# First time: create and start
docker run --name sandbox -it ubuntu:24.04 bash
# do work, exit

# Next time: resume
docker start -ai sandbox
# everything you installed is still there

docker start -ai starts the container and attaches your terminal to it. The writable layer survives between runs as long as the container exists.

To preserve work across container removal (so you can docker rm and recreate without losing files), put your work in a named volume:

bash
docker run --name sandbox -it \
  -v sandbox-home:/root \
  ubuntu:24.04 bash

The sandbox-home volume holds anything you put in /root (or wherever you mount it). New containers attached to the same volume see the same files.

Pick a distro

DistroWhen to reach for it
Ubuntu (ubuntu:24.04, ubuntu:22.04)Default for tutorials, broad package support, what most cloud VMs run.
Debian (debian:12, debian:11)Stable, smaller package surface than Ubuntu, parent of Ubuntu. Great for reproducible servers.
Alpine (alpine:3.20)Tiny (~7 MB). musl libc and BusyBox tools — different enough from Debian that some software doesn't build. Used heavily for small production images.
Fedora (fedora:41)Bleeding-edge package versions. Good for testing against future RHEL.
Rocky / AlmaLinux (rockylinux:9)RHEL-compatible. For matching production RHEL/CentOS environments.
Arch (archlinux:latest)Rolling release, AUR style, for testing against very current packages.

For learning Linux fundamentals, Ubuntu or Debian are the easiest start.

Common pitfalls

  • Container exits immediately when you start it without -it. A container with no foreground process exits. -it (-i to keep stdin open, -t for a TTY) gives you an interactive shell. Without it, bash reads no input and exits.
  • Unable to locate package errors right after apt install. Run apt update first. The image has no package index by default to keep its size down.
  • No bash on Alpine. Use sh (BusyBox ash). If you really want bash, apk add bash first.
  • Changes lost after exit. Expected with --rm. For persistence, name the container and use docker start -ai, or mount a volume.
  • Permission errors on a bind-mounted directory. The container's UID 0 (root) creates files owned by root on the host. Run as your user with -u "$(id -u):$(id -g)", or accept that you'll need sudo chown to clean up.

FAQ

Sources

Authoritative references this article was fact-checked against.

TagsDockerLinuxUbuntuDebianAlpineFedoraDevOps

Found this useful? Pass it on.

Copied
Ishan Karunaratne

Ishan Karunaratne

Tech Architect · Software Engineer · AI/DevOps

Tech architect and software engineer with 20+ years building software, Linux systems, and DevOps infrastructure, and lately working AI into the stack. Currently Chief Technology Officer at a healthcare tech startup, which is where most of these field notes come from.

Keep reading

Related posts