example-projects/reference/docker/03_running_containers.md

116 lines
4.3 KiB
Markdown
Raw Normal View History

# Lesson 03: Running Containers (and Pretending You're on a Different OS)
Now we run something with substance. This lesson is mostly about feeling, in your hands, what container isolation actually means.
## Step into Ubuntu — even if you're on a Mac or Windows
```bash
docker run -it ubuntu bash
```
The new flags:
- `-i` — keep STDIN open so you can type into the container.
- `-t` — allocate a pseudo-TTY so the terminal behaves like a real shell.
- (`-it` is just `-i` and `-t` stuck together — you'll see this everywhere.)
`ubuntu` is the image name. `bash` is the command to run inside, overriding the image's default.
After a brief download, your prompt changes to something like:
```
root@a1b2c3d4e5f6:/#
```
You are now in a shell *inside* an Ubuntu container. Try a few commands:
```bash
cat /etc/os-release # confirm it really is Ubuntu
ls / # the container's root filesystem
whoami # root, by default, inside a container
apt-get update # this Ubuntu's package manager (works even on a Mac)
apt-get install -y cowsay # install something
/usr/games/cowsay "I am running inside Docker"
```
You just installed `cowsay` into an Ubuntu system on your machine without touching your real machine at all. To leave:
```bash
exit
```
You're back on your real machine. None of those packages are installed on your host. The container is still around (stopped, but present) — we'll clean it up in the next lesson.
## Now try Alpine — a totally different distro
```bash
docker run -it alpine sh
```
Alpine is a tiny Linux distro often used for containers (the image is around 5MB). It uses `sh` instead of `bash` and `apk` instead of `apt-get`:
```sh
cat /etc/os-release # now it's Alpine
apk add --no-cache cowsay
cowsay "Different OS, same laptop"
exit
```
Two completely different Linux distributions, one after the other, on the same physical machine, neither one leaving a trace once it stops.
## Now Python, with no Python installed on your host
```bash
docker run -it python:3.12 python
```
You're dropped into a Python 3.12 REPL — running inside a container that has Python 3.12 installed, even if your real machine has Python 3.10, Python 2, or no Python at all. Type:
```python
import sys
sys.version
exit()
```
You just used Python 3.12 without installing it.
## The `:tag` part
Notice `python:3.12`. The part after the colon is the **tag**, usually a version. If you leave it off (`python`), Docker assumes `:latest` which is whatever the maintainers most recently published. You should usually pin a version explicitly so your work is reproducible.
Some examples of tags you'll see:
- `python:3.12` — Python 3.12 on a default base.
- `python:3.12-slim` — same Python, on a much smaller Debian base. Faster to download, smaller disk footprint.
- `python:3.12-alpine` — same Python, on the tiny Alpine base. Even smaller. Occasionally causes issues with packages that expect a glibc-based system.
- `ubuntu:22.04`, `ubuntu:24.04`, `ubuntu:latest` — Ubuntu by version number.
- `postgres:16`, `redis:7`, `nginx:1.27` — pick the major version you want.
When in doubt, look up the image on Docker Hub (https://hub.docker.com/) and read its tag list.
## Run a container in the background
Some containers (web servers, databases) are meant to keep running. Use `-d` (detached) to start one in the background:
```bash
docker run -d --name webserver nginx
```
`--name webserver` gives the container a memorable name instead of a random one like `peaceful_einstein`. Visit `http://localhost` … wait, you can't yet. We haven't told Docker to expose its port. That's lesson 07. For now, just check it's running:
```bash
docker ps
```
You should see one running container. Stop it:
```bash
docker stop webserver
```
## Try it yourself
1. Run an Ubuntu container and a Debian container side-by-side in two terminal windows. Note that `cat /etc/os-release` shows different distros in each, even though they share your machine.
2. Run `docker run -it python:3.11 python` and then `docker run -it python:3.12 python`. Two different Python versions, on the same laptop, in the same minute, without installing anything.
3. Move on to [`04_images_vs_containers.md`](04_images_vs_containers.md) — by now you've created several containers and you may be wondering where they all went.