How to Use Docker: Compose, Kubernetes, and CI/CD for Beginners

2026-06-05·Getting Started

Key Takeaways

  • Docker packages apps with dependencies into lightweight containers, ensuring consistency across environments.
  • Docker Compose lets you define and run multi-container apps with a single YAML file—perfect for local dev.
  • Kubernetes automates deployment, scaling, and management of containers in production, but start small to avoid complexity.
  • CI/CD pipelines using Docker images cut deployment time by 60-80% compared to traditional methods.

---

# How to Use Docker: Compose, Kubernetes, and CI/CD for Beginners

I remember my first encounter with Docker in 2018. I was building a Python web app with PostgreSQL and Redis, and every teammate had a different way of setting it up. One had Python 3.6, another 3.8, and the Redis version varied. Hours were lost debugging "works on my machine" issues. Docker fixed that.

In this guide, I'll walk you through the practical steps to use Docker for containerization, Docker Compose for multi-service apps, Kubernetes basics for orchestration, and how to integrate everything into a CI/CD pipeline. No fluff—just real examples.

What Is Docker and Why Should You Care?

Docker is a platform that runs applications in isolated environments called containers. Each container includes the app code, runtime, system tools, and libraries. Unlike virtual machines (VMs) that emulate entire operating systems, containers share the host OS kernel, making them lightweight.

Real numbers:

  • A typical container starts in under 1 second, while a VM takes 30-60 seconds.
  • Containers use 50-80% less memory than equivalent VMs.
  • Docker Hub hosts over 8 million container images as of 2024.

Step 1: Install Docker and Run Your First Container

First, download Docker Desktop from [docker.com](https://docker.com) for Windows or macOS. On Linux, use your package manager. For Ubuntu:

```bash

sudo apt update

sudo apt install docker.io

sudo systemctl start docker

sudo systemctl enable docker

```

Verify installation:

```bash

docker --version

# Output: Docker version 24.0.7, build afdd53b

```

Now run a simple container:

```bash

docker run hello-world

```

You'll see a message confirming Docker works. This command pulls the `hello-world` image from Docker Hub and runs it in a container that exits after printing.

Step 2: Containerize Your Own App

Let's containerize a simple Node.js app. Create a `package.json` and `server.js`:

```javascript

// server.js

const http = require('http');

const hostname = '0.0.0.0';

const port = 3000;

const server = http.createServer((req, res) => {

res.statusCode = 200;

res.setHeader('Content-Type', 'text/plain');

res.end('Hello from Docker!\n');

});

server.listen(port, hostname, () => {

console.log(`Server running at http://${hostname}:${port}/`);

});

```

Create a `Dockerfile` in the same directory:

```dockerfile

FROM node:18-alpine

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 3000

CMD ["node", "server.js"]

```

Build the image:

```bash

docker build -t my-node-app .

```

Run it:

```bash

docker run -p 3000:3000 my-node-app

```

Visit `http://localhost:3000`—you'll see the message. The `-p` flag maps port 3000 on your host to port 3000 in the container.

Step 3: Use Docker Compose for Multi-Service Apps

Single containers are fine for simple apps, but real projects have multiple services (e.g., web, database, cache). Docker Compose lets you define them in a `docker-compose.yml` file.

Create a `docker-compose.yml` for a web app with PostgreSQL:

```yaml

version: '3.8'

services:

web:

build: .

ports:

- "3000:3000"

depends_on:

- db

environment:

- DATABASE_URL=postgres://user:pass@db:5432/mydb

db:

image: postgres:15-alpine

environment:

POSTGRES_USER: user

POSTGRES_PASSWORD: pass

POSTGRES_DB: mydb

volumes:

- pgdata:/var/lib/postgresql/data

volumes:

pgdata:

```

Run everything with one command:

```bash

docker-compose up -d

```

The `-d` flag runs containers in detached mode. Stop with `docker-compose down`. This is my go-to for local development because it replicates production environments.

Step 4: Kubernetes Basics for Orchestration

Docker Compose is great for single-machine setups, but when you need to scale across multiple servers, Kubernetes (K8s) takes over. K8s automates deployment, scaling, and management of containers.

Key concepts:

  • Pod: Smallest deployable unit—runs one or more containers.
  • Deployment: Manages replicas of pods.
  • Service: Exposes pods internally or externally.

Here's a basic deployment for our Node.js app:

```yaml

apiVersion: apps/v1

kind: Deployment

metadata:

name: node-app

spec:

replicas: 3

selector:

matchLabels:

app: node-app

template:

metadata:

labels:

app: node-app

spec:

containers:

- name: node-app

image: my-node-app:latest

ports:

- containerPort: 3000

```

Apply it with `kubectl apply -f deployment.yaml`. Then create a service to expose it:

```yaml

apiVersion: v1

kind: Service

metadata:

name: node-app-service

spec:

selector:

app: node-app

ports:

- protocol: TCP

port: 80

targetPort: 3000

type: LoadBalancer

```

Apply with `kubectl apply -f service.yaml`. Kubernetes will distribute traffic across your three pods.

Comparison: Docker Compose vs. Kubernetes

FeatureDocker ComposeKubernetes

-----------------------------------------------------------------------------------------
Best forLocal dev, single-machineProduction, multi-machine
Setup complexityLow (one YAML file)High (cluster setup needed)
ScalingManual (`--scale`)Automatic (HPA)
Resource managementBasicAdvanced (CPU/memory limits)
Learning curveGentleSteep

Start with Compose for learning and small projects; move to K8s when you need high availability.

Step 5: Integrate Docker with CI/CD Pipelines

Continuous Integration/Continuous Deployment (CI/CD) pipelines automate building, testing, and deploying Docker images. Here's a practical example using GitHub Actions.

Create `.github/workflows/docker-deploy.yml`:

```yaml

name: Build and Deploy

on:

push:

branches: [main]

jobs:

build:

runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v3

- name: Login to Docker Hub

uses: docker/login-action@v2

with:

username: ${{ secrets.DOCKER_USERNAME }}

password: ${{ secrets.DOCKER_TOKEN }}

- name: Build and push

uses: docker/build-push-action@v4

with:

push: true

tags: yourusername/my-app:latest

- name: Deploy to server

run: |

ssh user@server "docker pull yourusername/my-app:latest && docker-compose up -d"

```

This pipeline triggers on every push to `main`. It builds the image, pushes it to Docker Hub, then SSHes into your server to redeploy. My team cut deployment time from 15 minutes to under 2 using this approach.

Common Pitfalls to Avoid

  • Ignoring `.dockerignore`: Include node_modules, .git, and other unnecessary files to keep images small.

  • Using `latest` tag in production: Pin versions (e.g., `node:18-alpine`) for reproducibility.
  • Running containers as root: Use `USER` in Dockerfile to run as non-root for security.

FAQ

Q: Do I need to learn Docker before Kubernetes?

Yes, absolutely. Kubernetes manages containers, so you need to understand how to build and run Docker images first. Master Docker Compose before touching K8s—it builds foundational skills.

Q: Can I use Docker on Windows without WSL?

Docker Desktop on Windows now requires WSL 2 (Windows Subsystem for Linux). It's free and easy to install via PowerShell: `wsl --install`. The performance is excellent—I've run production-like stacks without issues.

Q: How do I persist data in Docker containers?

Use volumes or bind mounts. Volumes are managed by Docker (e.g., `docker volume create mydata`) and survive container restarts. Bind mounts link a host directory to a container path—handy for development because changes reflect immediately.

---

Docker isn't just a tool—it's a mindset shift. Once you containerize, you'll wonder how you lived without it. Start with the basics, experiment with Compose, and gradually explore Kubernetes. The learning curve is worth it.

If you hit a wall, the Docker documentation is excellent, and the community on Stack Overflow is active. Happy containerizing!