Chapter 5 of 16 · Visual guide

Running containers

The flags on docker run decide how you interact with a container and how it cleans up after itself.

key idea / Docker itselfcontainer / good pathhost / watch outproblem / blockedneutral

Three ways to start

Pick the mode by what you want your terminal to do.

Three ways to start a containerDetached keeps your terminal free, interactive attaches your keyboard, and --rm deletes the container on exit.-d detachedYour terminalContainerserver in backgroundterminal stays freeread output: docker logs-it interactiveYour terminalContainershell inside containerkeyboard attachedexit stops it--rm auto-cleanYour terminalContainerone-off jobs, testsstops, then is deletedno dead containers

Configuration at run time

Inject settings with -e so one image serves every environment.

One image, many environmentsThe same image runs as staging and production containers, differing only by the environment variables passed with -e.my-api:1.4one imagestaging containerDATABASE_URL=db-stagingLOG_LEVEL=debugproduction containerDATABASE_URL=db-prodLOG_LEVEL=warn-e ...-e ...
Config changes at run time with -e. The image never changes.

States and cleanup

Container statesA container goes from created to running to exited. With --rm it is removed automatically when it exits.Createddocker createstartRunningmain process aliveexitExiteddocker ps -armRemovedgone--rm: removed automatically on exit
--rm skips the Exited resting place: the container is removed the moment it stops.

run versus exec

run versus execdocker run creates a new container. docker exec starts an extra process inside a container that is already running.docker run alpine sleep 300creates a NEW containercontainer api (one set of namespaces)PID 1sleep 300PID 7printenv PORTdocker exec api printenvadds a process to apijoins the same container
exec shares the container namespaces, so it sees the same files, environment and network.
FlagUse it for
-dservers: run in the background, read with docker logs name
-ita shell to look around: docker run -it --rm alpine sh
--rmthrowaway containers: migrations, tests, experiments
-e KEY=valueconfiguration that differs per environment
--namea stable name to use with logs, exec and stop

Try it yourself

  1. Step 1 · An interactive shell

    -it attaches your keyboard. exit stops the container, and --rm deletes it.

    $ docker run -it --rm --name shell alpine:3.20 sh
    / # ls /
    bin    etc    lib    root   tmp
    / # exit
    $ docker ps -a --filter name=shell
    CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
  2. Step 2 · Detached, named, with an environment variable
    $ docker run -d --name api --rm -e PORT=3000 alpine:3.20 sleep 300
    b22e91aa10c4
    $ docker ps --filter name=api
    CONTAINER ID   IMAGE          STATUS         NAMES
    b22e91aa10c4   alpine:3.20    Up 2 seconds   api
  3. Step 3 · logs and exec use the name

    exec starts a second process in the same container. It can read PORT because -e set it at run.

    $ docker logs api
    $ docker exec api printenv PORT
    3000
  4. Step 4 · stop plus --rm removes the container
    $ docker stop api
    api
    $ docker ps -a --filter name=api
    CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Recap

Quick check

A container started with -d exits after one second. Where do you look first?
Show answer

docker ps -a to see the exit code, then docker logs name. A container stays up only as long as its main process runs.