--- # You can also start simply with 'default' theme: seriph # random image from a curated Unsplash collection by Anthony # like them? see https://unsplash.com/collections/94734566/slidev background: https://cover.sli.dev # some information about your slides (markdown enabled) title: Welcome to Slidev info: | ## Slidev Starter Template Presentation slides for developers. Learn more at [Sli.dev](https://sli.dev) # apply unocss classes to the current slide class: text-center # https://sli.dev/features/drawing drawings: persist: false # slide transition: https://sli.dev/guide/animations.html#slide-transitions transition: slide-left # enable MDC Syntax: https://sli.dev/features/mdc mdc: true # open graph # seoMeta: # ogImage: https://cover.sli.dev --- # Demystifying Docker Mike Conrad - SCS 2025
Press Space for next page
--- transition: fade-out layout: center --- ## Why Containers? - "It works on my machine" is a thing of the past - Containers are lightweight and portable - Boot in milliseconds - Ideal for reproducible dev environments --- transition: fade-out layout: center --- ## Containers vs Virtual Machines | Feature | VM | Container | |------------------|----------------|------------------| | Boot time | Minutes | Seconds | | Resource usage | Heavy | Lightweight | | Isolation | Strong | Process-level | | Portability | Medium | Very High | In reality we often use containers and vm's together. Containers run inside of VM's for better security and isolation, especially in cloud and multi tenant environments. --- transition: fade-out layout: center --- ## What is Docker? - A tool to build and run containers - Docker engine runs containers using OS features: - Namespaces - cgroups - Union file systems - Uses images layered from base -> app code --- transition: fade-out layout: center --- --- transition: fade-out layout: center --- ## Docker Architecture Docker Engine (Server) <-- REST API --> Docker CLI (Client) --- transition: fade-out layout: center --- ## Docker Under the Hood - **Namespaces**: isolate PID, net, mount, etc. - **cgroups**: control CPU, memory, IO - **UnionFS**: layered filesystem (AUFS, OverlayFS) ![UnionFS diagram](https://docs.docker.com/engine/storage/drivers/images/overlay_constructs.webp) --- transition: fade-out layout: center --- ## Anatomy of a Dockerfile ```dockerfile FROM node:22-slim WORKDIR /app COPY package*.json ./ RUN npm install COPY . . EXPOSE 3000 CMD ["npm", "start"] ``` - Starts with a base image - Copy files and install deps - Set default command --- transition: fade-out layout: center --- ## Dockerfile Best Practices ```dockerfile # Stage 1: Build the Go binary FROM golang:1.24.2-alpine AS builder # Set working directory inside the build container WORKDIR /app COPY go.mod ./ RUN go mod download COPY . . # Build the Go binary statically RUN CGO_ENABLED=0 GOOS=linux go build -o docker-api-proxy . # Stage 2: Run binary in minimal container FROM scratch # Copy binary from builder COPY --from=builder /app/docker-api-proxy /usr/local/bin/docker-api-proxy # Run binary ENTRYPOINT ["docker-api-proxy"] EXPOSE 80 ``` - Use specific versions, not `latest` - Combine commands to reduce layers - Use `.dockerignore` - Prefer slim or alpine images - Run as non-root user if possible --- transition: fade-out layout: center --- ## What is Docker Compose? - Define multi-container apps in one file - Great for local dev and staging (and production!) ```yaml name: traefik_secure services: socket-proxy: image: git.hackanooga.com/mikeconrad/docketproxy:latest container_name: socket-proxy networks: - traefik - socket_proxy volumes: - /var/run/docker.sock:/var/run/docker.sock:ro read_only: true security_opt: - no-new-privileges:true cap_drop: - ALL restart: unless-stopped environment: - ALLOWED_NETWORKS=traefik_secure_traefik traefik: image: traefik:latest container_name: traefik command: - "--log.level=INFO" - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--providers.docker=true" - "--providers.docker.endpoint=tcp://socket-proxy:8000" - "--providers.docker.exposedbydefault=false" - "--entrypoints.traefik.address=:8080" - "--api.insecure=true" - "--api.dashboard=true" labels: - "traefik.enable=true" - "traefik.http.routers.api.rule=Host(`traefik.docker.localhost`)" - "traefik.http.routers.api.entrypoints=web" - "traefik.http.routers.api.service=api@internal" ports: - "80:80" - "8080:8080" networks: - traefik - socket_proxy depends_on: - socket-proxy restart: unless-stopped whoami: image: traefik/whoami networks: - traefik labels: - "traefik.enable=true" - "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)" - "traefik.http.routers.whoami.entrypoints=web" networks: traefik: {} socket_proxy: driver: bridge internal: true enable_ipv6: false ```