Containerization: The process of packaging an application and its dependencies into a standardized, isolated unit called a container.
Image: A lightweight, standalone, executable package that includes everything needed to run a piece of software, including the code, a runtime, libraries, and settings. Images are immutable.
Container: A running instance of an image. It is an isolated environment where the application runs.
Dockerfile: A text file that contains instructions for building a Docker image.
Docker Hub/Registry: A repository for storing and sharing Docker images.
Volume: A mechanism for persisting data generated by and used by Docker containers. Volumes are managed by Docker and exist outside the container's filesystem.
Network: A virtual network that allows containers to communicate with each other and with the host machine.
🧮 Command Structure
Docker commands follow a consistent structure of management commands and sub-commands.
management_command: The type of resource to manage (e.g., container, image, volume).
sub_command: The action to perform (e.g., run, ls, rm).
Example:docker container run -d -p 8080:80 --name webserver nginx
While older syntax like docker run still works, the newer, more explicit syntax like docker container run is recommended for clarity.
🛠️ Core Commands Reference
Image Management
Command
Description
docker image build -t [name:tag] .
Builds an image from a Dockerfile in the current directory.
docker image pull [name:tag]
Pulls an image from a registry (like Docker Hub).
docker image push [name:tag]
Pushes an image to a registry.
docker image ls
Lists all local images.
docker image rm [image_id]
Removes one or more images.
Container Management
Command
Description
docker container run [image]
Creates and starts a new container from an image.
docker container start / stop [container_id]
Starts/stops an existing container.
docker container ls
Lists running containers (use -a to see all containers).
docker container logs [container_id]
Fetches the logs of a container. (Use -f to follow).
docker container exec -it [id] [cmd]
Executes a command inside a running container (e.g., bash for a shell).
docker container rm [container_id]
Removes one or more containers. (Use -f to force).
System & Data Management
Command
Description
docker volume create [name]
Creates a named volume.
docker volume ls
Lists all volumes.
docker network ls
Lists all networks.
docker system prune -a
Removes all unused data (containers, networks, images). Use with caution!
🧭 Basic Development Workflow
Write a Dockerfile that defines your application environment.
Build the image: Run docker image build -t my-app . to create a local image tagged as "my-app".
Run the container: Run docker container run -d -p 5000:5000 --name my-app-instance my-app to start your app.
Check logs for errors: Use docker container logs my-app-instance to see the output from your app.
Debug inside the container: If needed, get a shell inside the running container with docker exec -it my-app-instance bash.
Stop and remove: Once finished, stop with docker container stop my-app-instance and remove with docker container rm my-app-instance.
⌨️ Productivity Tips
Use .dockerignore: Create a .dockerignore file to exclude files and directories (like node_modules or .git) from the build context. This makes builds much faster.
Multi-stage Builds: Use multi-stage builds in your Dockerfile to create smaller, more secure production images by separating build-time dependencies from runtime dependencies.
Docker Compose: For applications that require multiple services (e.g., a web app and a database), use Docker Compose to define and run them with a single command (docker-compose up).
Combine Flags: Short flags can be combined. -it is the same as -i -t.
📊 Common docker run Flags
Flag
Name
Description
-d
--detach
Runs the container in the background (detached mode).
-p [host]:[container]
--publish
Maps a port on the host to a port in the container (e.g., -p 8080:80).
-v [host]:[container]
--volume
Mounts a host directory or a named volume into the container.
-e [KEY=VALUE]
--env
Sets an environment variable inside the container.
--name [name]
Assigns a custom name to the container for easy reference.
--rm
Automatically removes the container when it exits.
-it
--interactive --tty
Provides an interactive terminal session (used with exec).
🧪 Example: Simple Node.js Web App
Dockerfile
# 1. Use an official Node.js runtime as a base image
FROM node:18-slim
# 2. Set the working directory in the container
WORKDIR /app
# 3. Copy package files and install dependencies
COPY package*.json ./
RUN npm install
# 4. Copy the rest of the application source code
COPY . .
# 5. Expose the port the app runs on
EXPOSE 3000
# 6. Define the command to run the app
CMD [ "node", "server.js" ]
Build and Run Commands
# Build the image
docker build -t my-node-app .
# Run the container
docker run -d -p 3000:3000 --name webapp my-node-app
🧹 Troubleshooting Common Issues
Error: Cannot connect to the Docker daemon. Is the docker daemon running?
Fix: The Docker service is not running on your machine. Start it via Docker Desktop or your system's service manager (e.g., sudo systemctl start docker).
Problem: Container exits immediately after starting.
Fix: The main process inside the container has finished or crashed. Check the logs with docker logs [container_name] to see the error message. A common cause is a command that doesn't stay running (like a script that just prints and exits).
Problem: "Bind for 0.0.0.0:8080 failed: port is already allocated."
Fix: The host port you are trying to map with -p is already being used by another application or container. Choose a different host port (e.g., -p 8081:80).
Problem: Changes to my code don't appear in the running container.
Fix: Images are immutable. If you change your source code, you must rebuild the image (docker build) and then create a new container from the new image. For development, use a volume (-v .:/app) to sync your local code into the container without rebuilding.