hello-world Run
Your first run with Docker: pulling an image, starting a container, mapping ports, and the basics of clean teardown.
Docker — hello, container
EXAMPLE
# ===== Run hello-world ===== docker run --rm hello-world # Pulls the image, starts a one-shot container, prints, then exits. # --rm removes the container after exit. # ===== Run a server ===== docker run -d --name web -p 8080:80 nginx:1.27-alpine # -d: detached (background) # --name: stable name (default is random) # -p HOST:CONTAINER: port mapping # Visit http://localhost:8080 # ===== Inspect ===== docker ps # running containers docker ps -a # all (incl stopped) docker logs web # stdout/stderr of the container docker logs -f web # follow docker exec -it web sh # exec a shell inside # ===== Stop + remove ===== docker stop web # graceful (SIGTERM, then SIGKILL) docker rm web # remove the stopped container # Or: docker rm -f web (force stop + remove) # ===== Volumes (persistence) ===== docker volume create pg-data docker run -d --name pg \ -e POSTGRES_PASSWORD=dev \ -v pg-data:/var/lib/postgresql/data \ -p 5432:5432 \ postgres:16 # Bind mount your code: docker run -d --name dev \ -v "$PWD":/app -w /app \ -p 3000:3000 \ node:20-alpine npm run dev # ===== Environment variables ===== docker run --rm -e NODE_ENV=production -e PORT=3000 my-app # Or from a file: docker run --rm --env-file ./.env my-app # ===== Networks ===== docker network create app-net docker run -d --name pg --network app-net postgres:16 docker run -d --name api --network app-net -p 3000:3000 my-api # 'api' can reach 'pg' at hostname 'pg'. # ===== Cleaning up ===== docker stop $(docker ps -q) # stop all running docker rm $(docker ps -aq) # remove all containers docker image prune # untagged + dangling images docker system prune -a # everything not in use # ===== Common gotchas ===== # - Port already in use: change HOST port (use -p 8081:80) # - Cannot connect from host: forgot -p mapping or wrong CONTAINER port # - State lost after rm: use volumes for any persistence # - Permission errors with bind mounts: rootless containers + volume ownership # ===== Patterns to internalise ===== # - --rm for one-shots; --name + -d for daemons # - Volumes for data you must keep; bind mounts for code in dev # - Networks for inter-container DNS; do not rely on IPs # - Always check 'docker logs' first when something fails # ===== Pitfalls ===== # - Forgetting -p -> service is unreachable from host # - Not mounting a volume -> data wiped on next run # - Running as root inside containers in production # - Leaving 'latest' tags everywhere in prod
Why it matters
docker run --rm hello-world is the first ten seconds. From there: -d + --name for services, -p for ports, -v for volumes, --network for inter-container DNS. Cleanup with stop + rm, or rely on --rm for ephemerals.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
docker run hello-world # Pulls the image, runs the container, prints a welcome message.Try it Yourself »
Discussion
Loading…