diff --git a/slides.md b/slides.md
index 297335d..bc0491a 100644
--- a/slides.md
+++ b/slides.md
@@ -51,17 +51,62 @@ transition: fade-out
layout: center
---
-## Why Containers?
+# Who is this for?
-- "It works on my machine" is a thing of the past
-- Containers are lightweight and portable
-- Boot in milliseconds
-- Ideal for reproducible dev environments
+## About you
+- Some experience with Docker/containers
+- Some experience with BASH
+- Want to better understand how containers work
---
transition: fade-out
layout: center
---
+
+## Follow Along
+**Example Repo** - https://git.hackanooga.com/mikeconrad/demystifying-docker
+
+---
+transition: fade-out
+layout: center
+---
+
+
+
+---
+transition: fade-out
+layout: center
+---
+
+## Common Use cases for containers
+- Reproducible dev environments
+- Testing in CI/CD environments
+- Better "Portability" of application code
+- Snapshot of application code at specific point in time
+
+
+
+---
+transition: fade-out
+layout: center
+---
+
+## How we use containers
+
+- PR builds (Preview Environments).
+
+
+### Allows us to
+- Test changes in isolated environments
+- Simplify complex dev environment setups
+ - (frontend/backend services, databases, object storage, etc)
+
+
+---
+transition: fade-out
+layout: center
+---
+
## Containers vs Virtual Machines
| Feature | VM | Container |
@@ -71,7 +116,7 @@ layout: center
| 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.
+In reality we 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
@@ -80,17 +125,35 @@ 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
+- Written in GO
+- Uses Client/Server model with REST API (`docker cli` and `dockerd`)
+- Eco system of tools (Compose, Swarm, etc)
+- Public Image Registry (Dockerhub)
+- Docker client typically runs on same machine as server but doesn't have to
---
transition: fade-out
layout: center
---
+## What is Docker?
+
+- A tool to build and run containers
+- Containers are exclusive to Linux
+- Docker engine runs containers using Linux features like:
+ - Namespaces
+ - cgroups
+ - Union file systems
+- Container runs from an image layered with base image and application code
+
+---
+transition: fade-out
+layout: center
+---
+
+## Common Use Cases
+- Reproducible Dev environments (dev containers)
+- Preview/PR environments (ephemeral test environments)
+- Legacy applications or applications with complex environment setups
---
transition: fade-out
@@ -99,10 +162,11 @@ layout: center
## Docker Architecture
-Docker Engine (Server) <-- REST API --> Docker CLI (Client)
+Docker CLI (Client) <-- REST API --> Docker Engine (Server)
-
+
+[https://docs.docker.com/get-started/docker-overview/]
---
transition: fade-out
@@ -113,7 +177,10 @@ layout: center
- **Namespaces**: isolate PID, net, mount, etc.
- **cgroups**: control CPU, memory, IO
-- **UnionFS**: layered filesystem (AUFS, OverlayFS)
+- **UnionFS**: layered filesystem (OverlayFS)
+

@@ -122,6 +189,94 @@ transition: fade-out
layout: center
---
+## Bind/Volume Mounts
+
+- 2 most common storage mechanisms
+- Different use cases and security implications
+
+---
+transition: fade-out
+layout: center
+---
+## Bind Mounts
+
+- Mounting files/directories from the host machine directly into a container (merged overlayfs layer).
+- Processes inside container can modify files on host system.
+- Bind mounts are strongly tied to the host
+- Best for things like dev containers where you need to mount source code into container and have hot reload, etc.
+
+## Bind Mount Example
+```bash
+$ docker run --mount type=bind,src=/home/mikeconrad/projects/example/app,dst=/app,ro nginx # ro for ReadOnly
+$ docker run --volume /home/mikeconrad/projects/example/app:/app nginx
+```
+
+
+
+
+
+---
+transition: fade-out
+layout: center
+---
+
+## Volume Mount Example
+```bash
+$ docker run --name postgrestest \
+ --mount type=volume,src=postgresData,dst=/var/lib/postgresql/data \
+ -e POSTGRES_PASSWORD=postgres \
+ --rm postgres:16
+
+$ docker run --name postgrestest \
+ --volume postgresData:/var/lib/postgresql/data \
+ -e POSTGRES_PASSWORD=postgres \
+ --rm postgres:16
+```
+```bash
+$ docker volume inspect postgresData
+[
+ {
+ "CreatedAt": "2025-06-08T10:39:12-04:00",
+ "Driver": "local",
+ "Labels": null,
+ "Mountpoint": "/var/lib/docker/volumes/postgresData/_data",
+ "Name": "postgresData",
+ "Options": null,
+ "Scope": "local"
+ }
+]
+```
+
+- Docker creates a volume named postgresData and mounts that directory inside the container.
+
+
+---
+transition: fade-out
+layout: center
+---
+
+## Volume mounts
+- Created and managed by the Docker Daemon
+- Volume data is stored on host filesystem but managed by Docker.
+- Used for persistent data.
+
+
+
+---
+transition: fade-out
+layout: center
+---
+
## Anatomy of a Dockerfile
```dockerfile
@@ -133,6 +288,11 @@ COPY . .
EXPOSE 3000
CMD ["npm", "start"]
```
+```bash
+mikeconrad@pop-os:~/projects/demystifying-docker/examples/react
+$ docker build -t react-app .
+```
+
- Starts with a base image
- Copy files and install deps
@@ -143,33 +303,35 @@ transition: fade-out
layout: center
---
-## Dockerfile Best Practices
+## Multi Stage builds
```dockerfile
-# Stage 1: Build the Go binary
-FROM golang:1.24.2-alpine AS builder
-# Set working directory inside the build container
+# Stage 1 - Define Base image
+FROM node:22-alpine AS base
+# Stage 2 Install dependencies
+FROM base AS install-deps
WORKDIR /app
-COPY go.mod ./
-RUN go mod download
+COPY package*.json /app/
+RUN yarn
+# Stage 3 Development
+FROM install-deps AS develop
+WORKDIR /app
+COPY --from=install-deps /app/node_modules /app/node_modules
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
+ENTRYPOINT ["yarn", "dev", "--host=0.0.0.0"]
+EXPOSE 5173
```
-- Use specific versions, not `latest`
-- Combine commands to reduce layers
-- Use `.dockerignore`
-- Prefer slim or alpine images
-- Run as non-root user if possible
-
+```bash
+$ docker build -t react .
+$ docker run --rm -P react
+```
+
---
transition: fade-out
layout: center
@@ -180,64 +342,26 @@ layout: center
- 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
-```
+---
+transition: fade-out
+layout: center
+---
+
+## Q/A
+
+-
+
+---
+transition: fade-out
+layout: center
+---
+
+## Resources
+- [Slide Deck (including examples)](https://git.hackanooga.com/mikeconrad/demystifying-docker-v2)
+- [DocketProxy (Docker socket proxy)](https://git.hackanooga.com/mikeconrad/docketproxy)
+- [SlimToolkit (Optimize and secure containers)](https://github.com/slimtoolkit/slim)
+
+## VSCode plugins
+https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker
+https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers
+https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-containers
\ No newline at end of file