
Docker can feel complicated when you’re starting. Multiple commands, flags, and concepts like containers, images, and volumes can be overwhelming. But for most development projects, you only need to fully understand one command: docker run.
If you understand this command deeply, you understand the essence of Docker.
Note: Please ensure you have a pre-written Dockerfile.
Before running a project in Docker, you need an image. Think of an image as a snapshot of your app including:
To build an image, go to the folder containing your Dockerfile and run:
docker build -t my-app-image .
Breaking it down:
docker build → instructs Docker to create an image from a Dockerfile.-t my-app-image → assigns a human-readable name to your image. This makes it easier to reference later.. → specifies the build context, i.e., Docker can access all files in this folder during the build.After this step, you have a Docker image ready to run.
Here’s the command that launches your app:
docker run -p 5000:5000 \
--name my-app-container \
--rm \
-w /app \
-v my-app-logs:/app/logs \
-v "$(pwd)":/app \
-v /app/node_modules \
my-app-image
Let’s analyze every part so you know exactly what happens.
docker runThis is the core Docker command for running projects. It does three things:
npm start or node index.js).Think of it as “spinning up a mini virtual machine” just for your app.
-p 5000:5000 → Port MappingThis maps ports between your host machine and the container.
5000) → your computer (host).5000) → container.Effectively, Docker listens on your computer’s port 5000 and forwards traffic to the container. This is why you can access your app at localhost:5000.
Without port mapping, your app would run, but no external requests could reach it.
--name my-app-container → Container NamingDocker assigns random names to containers by default (e.g., adoring_babbage). Naming your container:
docker stop my-app-container).--rm → Auto Cleanup--rm tells Docker to delete the container automatically when it stops.
-w /app → Working DirectoryThis sets the default directory inside the container where commands run.
cd /app before running your app../node_modules or ./src resolve correctly.Without it, the container defaults to /, which usually breaks relative paths in your app.
-v "$(pwd)":/app → Bind Mount (Live Code Updates)This is a bind mount, a crucial part of development:
$(pwd) → current directory) to a folder inside the container (/app).This makes Docker development feel almost native—edit code locally and see it reflected in the running container.
-v /app/node_modules → Anonymous Volume (Dependency Isolation)This creates an anonymous volume, a container-only storage:
node_modules inside the container is isolated from your host machine.Effectively, this volume ensures your container can run independently of your host’s environment.
-v my-app-logs:/app/logs → Named Volume (Persistent Data)This is a named volume, explicitly labeled (my-app-logs).
my-app-image → Image to RunThis tells Docker which image to use. Everything before this is configuration. This line answers the question: “What should the container run?”
Once development is done:
docker stop my-app-container
Because of --rm, the container is deleted automatically after stopping.
docker rmi my-app-image
Mastering this command teaches you:
Once you understand this command, Docker stops feeling like magic and starts feeling like a productivity tool.
Keep Learning!