Back to Info Hub

Docker & Containers

Learn about containerization with Docker and related technologies.

Why Containers Changed Everything

Before containers, deploying software meant wrestling with environment inconsistencies - "it works on my machine" was a daily frustration. Docker solved this by packaging applications with everything they need to run, making deployments reproducible from a developer laptop to a production cluster. Today, containers are the standard unit of deployment for startups and enterprises alike.

At Wizard Tech Services, our web development projects are containerized by default, ensuring smooth handoffs and consistent environments. We also help teams containerize existing applications and set up orchestration as part of our automation and infrastructure services.

Containers vs. VMs

Virtual machines emulate entire operating systems and take minutes to boot. Containers share the host OS kernel and start in milliseconds, using a fraction of the memory. Use VMs when you need full OS isolation; use containers for application-level packaging and rapid scaling.

Dev-to-Prod Parity

Use Docker Compose locally and Kubernetes in production to keep your environments as similar as possible. The same Dockerfile builds the same image everywhere, eliminating configuration drift and "works on my machine" bugs.

Click below to see more information!
Select a category to explore detailed content

Back to Docker

Images & Registries

Build images with Dockerfiles, optimize with multi-stage builds, and push to Docker Hub or GitHub Container Registry.

Essential Commands

$ docker build -t myapp:latest . # Build from Dockerfile

$ docker images # List local images

$ docker tag myapp:latest registry/myapp:v1.0 # Tag for pushing

$ docker push registry/myapp:v1.0 # Push to registry

$ docker pull nginx:alpine # Pull from Docker Hub

$ docker rmi myapp:latest # Remove a local image

$ docker system prune -a # Remove all unused images

Example: Multi-Stage Dockerfile (Node.js)
# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2: Production
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
EXPOSE 3000
CMD ["node", "dist/index.js"]

Why Multi-Stage?

  • • Build tools and dev dependencies stay in the builder stage
  • • Final image only contains production code - much smaller
  • • Fewer files = smaller attack surface in production
  • • Same Dockerfile works for dev and prod
Key Concepts

Layers - each Dockerfile instruction creates a layer; unchanged layers are cached

FROM - base image to start from (e.g., node:20-alpine, python:3.12-slim)

COPY / ADD - copy files from host into the image

RUN - execute a command during build (install deps, compile code)

CMD / ENTRYPOINT - default command when the container starts

EXPOSE - document which port the app listens on

.dockerignore - exclude files from the build context (like .gitignore)

Container Registries

Docker Hub

The default public registry with official images (nginx, postgres, node, etc.) and community-contributed images. Free for public repos.

Browse Docker Hub →

GitHub Container Registry

GHCR integrates with GitHub Actions for seamless CI/CD image publishing. Free for public repos, included with GitHub Pro for private.

GHCR Docs →

AWS ECR / Google GCR

Cloud-native private registries integrated with their respective cloud platforms. Best for teams already on AWS or GCP.

Self-Hosted Registry

Run your own registry with the official registry:2 image. Full control over storage and access for air-gapped or compliance-heavy environments.