Docker Installation and Setup: From Zero to Production-Ready in 30 Minutes
Docker installation guide for beginners.
20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.
- ✓Basic command-line familiarity (cd, ls, mkdir)
- ✓A machine with internet access and sudo/administrator privileges
- ✓No prior Docker experience needed
Install Docker by downloading Docker Desktop from docker.com or using your package manager on Linux. For Linux, run curl -fsSL https://get.docker.com | sh. Verify with docker --version and docker run hello-world.
Think of Docker as a shipping container for your app. Just like a shipping container holds cargo and fits on any truck, train, or ship, a Docker container holds your app and runs on any computer with Docker installed. No more 'but it worked on my laptop' excuses.
| Chrome | Firefox | Safari | Edge |
|---|---|---|---|
| ✓ | ✓ | ✓ | ✓ |
You've been burned before. You push code to production, and it crashes because the server has a different version of Node, or Python, or some obscure C library. The classic 'works on my machine' lie. Docker ends that nonsense. It packages your app with everything it needs — down to the operating system libraries — into a single, runnable unit called a container. Once you have Docker installed, you can run that container anywhere: your laptop, your teammate's Windows machine, a cloud server, even a Raspberry Pi. No surprises. By the end of this guide, you'll have Docker installed, verified, and ready to run your first container. You'll also know how to avoid the three most common setup traps that waste hours.
What Docker Actually Solves (And Why You Should Care)
Before Docker, deploying software was a nightmare. You'd write a setup script, pray the server had the right OS version, and spend hours debugging library conflicts. Docker eliminates that by bundling your app with its entire runtime environment. A container includes the OS, libraries, environment variables, and your code. It runs identically on any machine with Docker. The core concept is an image — a read-only template with instructions for creating a container. You build an image, push it to a registry (like Docker Hub), and pull it on any machine. Containers are lightweight, start in seconds, and isolate processes. They're not virtual machines — they share the host OS kernel, so they use fewer resources. This is why Docker dominates DevOps: it makes deployment predictable and repeatable.
docker pull to pre-cache images before deployments.Installing Docker on Linux (The Right Way)
Linux is Docker's native home. The Docker Engine runs directly on the Linux kernel. The recommended method is using the official convenience script from Docker. It detects your distribution, adds the correct repository, and installs the latest stable version. Do not use your distro's package manager (apt, yum) unless you want an outdated version. The script handles everything. After installation, you need to start the Docker daemon and enable it to start on boot. Finally, add your user to the 'docker' group to run Docker commands without sudo. This is a security risk in multi-user environments, but for a single developer machine, it's standard practice.
sudo apt-get install docker.io on Ubuntu. That package is often months out of date. Always use the official script or Docker's apt repository.Installing Docker on macOS and Windows (Docker Desktop)
Docker Desktop is the easiest way to run Docker on macOS and Windows. It includes Docker Engine, Docker CLI, Docker Compose, and a GUI. On macOS, it uses a lightweight HyperKit VM to run Linux containers. On Windows, it can use Hyper-V or WSL 2. WSL 2 is recommended for better performance. Download the installer from docker.com, drag it to Applications, and launch. Docker Desktop will start the daemon automatically. You'll see the Docker whale icon in your menu bar or system tray. Click it to manage containers. The CLI works the same as on Linux. One gotcha: Docker Desktop on macOS has default memory limits (2GB). For serious work, increase it in Preferences -> Resources -> Advanced.
Verifying Your Docker Installation (Don't Skip This)
After installation, you must verify Docker works correctly. Run docker version to check client and server versions. If you get 'Cannot connect to the Docker daemon', the daemon isn't running. On Linux, start it with sudo systemctl start docker. On macOS/Windows, launch Docker Desktop. Next, run docker run hello-world. This pulls a tiny test image from Docker Hub and runs a container that prints a success message. If it works, your installation is complete. If you get permission errors, you forgot to add your user to the docker group. Run sudo usermod -aG docker $USER and log out/in. If you're on a VM or remote server, ensure your user has sudo access.
docker version command shows both client and server versions. If server info is missing, the daemon isn't running. This is a common interview debugging scenario.Running Your First Real Container (Not Hello World)
Hello World is boring. Let's run something useful: an Nginx web server. Run docker run -d -p 8080:80 nginx:alpine. The -d flag runs it in detached mode (background). -p 8080:80 maps port 8080 on your host to port 80 in the container. nginx:alpine is a lightweight Nginx image. Open http://localhost:8080 in your browser. You should see the Nginx welcome page. To stop the container, run docker stop <container-id>. To remove it, docker rm <container-id>. This is the pattern you'll use for most services: databases, APIs, frontends. Containers are ephemeral — any data written inside is lost when the container is removed. For persistent data, you need volumes (covered in a later article).
--rm flag with docker run to automatically remove the container when it stops. Great for testing: docker run --rm -p 8080:80 nginx:alpine.Understanding Docker Images and Layers
Docker images are built in layers. Each instruction in a Dockerfile creates a new layer. Layers are cached. If you change a layer, only that layer and subsequent ones are rebuilt. This makes builds fast. Images are read-only. When you run a container, Docker adds a thin writable layer on top. Any changes inside the container (creating files, installing packages) happen in this writable layer. When the container is deleted, the writable layer is lost. That's why you need volumes for persistent data. Images are identified by a hash (SHA256). Tags (like nginx:alpine) are human-readable aliases. Always use specific tags in production, not latest, because latest changes and can break your deployment.
Docker Compose: Multi-Container Setup Made Simple
Real applications need multiple services: a web server, a database, a cache. Docker Compose lets you define and run multi-container applications with a single YAML file. You define services, networks, and volumes. One command (docker-compose up) starts everything. This is essential for local development and CI/CD. Compose is included with Docker Desktop. On Linux, you may need to install it separately. The file is usually named docker-compose.yml. Each service specifies an image or build context, ports, environment variables, and dependencies. Compose creates a default network so containers can communicate by service name.
docker-compose config to validate your YAML file and see the resolved configuration. Catches indentation errors before you run anything.Common Installation Pitfalls and How to Fix Them
The most common error is 'Cannot connect to the Docker daemon'. On Linux, the daemon might not be running or your user isn't in the docker group. Run sudo systemctl status docker to check. If it's inactive, start it. If your user isn't in the docker group, add them and log out/in. On macOS/Windows, Docker Desktop might not be running. Launch it from Applications. Another pitfall: disk space. Docker images and containers consume disk. Run docker system df to see usage. Clean up with docker system prune -a (removes all unused images, containers, and networks). On macOS, Docker Desktop uses a disk image that can grow large. Reset it in Troubleshoot -> Reset to factory defaults. Never run docker system prune in production without understanding what it removes.
docker system prune -a --volumes on a production server without checking what it removes. It deletes all stopped containers, unused networks, dangling images, and unused volumes. You could lose database data if volumes aren't backed up.The 4GB Container That Kept Dying
--memory flag was never set in the docker run command or docker-compose.yml.--memory=4g in docker run or mem_limit: 4g in docker-compose.yml. Also increased swap to 2GB with --memory-swap=6g.- Always explicitly set resource limits for containers in production — default limits are for development only.
sudo systemctl status docker (Linux) or check Docker Desktop is running (macOS/Windows). 2. If inactive, start it: sudo systemctl start docker. 3. If still failing, check logs: journalctl -u docker.service (Linux) or Docker Desktop logs.groups $USER. 2. If not, add: sudo usermod -aG docker $USER. 3. Log out and back in, or run newgrp docker to apply immediately.sudo apt-get install docker-compose-plugin or download binary. 2. On macOS/Windows, ensure Docker Desktop is up to date (includes Compose). 3. Verify: docker compose version.`which docker``sudo sh get-docker.sh` (after downloading script)curl -fsSL https://get.docker.com -o get-docker.sh && sudo sh get-docker.sh| File | Command / Code | Purpose |
|---|---|---|
| WhyDocker.devops | sudo apt-get update | What Docker Actually Solves (And Why You Should Care) |
| InstallDockerLinux.devops | curl -fsSL https://get.docker.com -o get-docker.sh | Installing Docker on Linux (The Right Way) |
| InstallDockerDesktop.devops | docker --version | Installing Docker on macOS and Windows (Docker Desktop) |
| VerifyDocker.devops | docker version | Verifying Your Docker Installation (Don't Skip This) |
| RunNginx.devops | docker run -d -p 8080:80 --name my-nginx nginx:alpine | Running Your First Real Container (Not Hello World) |
| ImageLayers.devops | docker pull nginx:alpine | Understanding Docker Images and Layers |
| docker-compose.yml | version: '3.8' | Docker Compose |
| TroubleshootDocker.devops | sudo systemctl status docker | Common Installation Pitfalls and How to Fix Them |
Key takeaways
:latest.Interview Questions on This Topic
How does Docker handle resource limits for containers, and what happens when a container exceeds its memory limit?
--memory. When a container exceeds its limit, the kernel OOM killer terminates processes inside the container. The container may exit with code 137. To prevent this, set appropriate limits and use --memory-swap to allow swap usage. In production, monitor container memory with docker stats.Frequently Asked Questions
20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.
That's Docker. Mark it forged?
4 min read · try the examples if you haven't