init: complete homelab mastery guide
Architecture overview, design decisions, Docker/networking/OAuth2/Linux concept deep-dives, cert roadmap for cloud engineering track, interview prep with model answers, and structured learning path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
commit
ca9e8a7959
10 changed files with 1534 additions and 0 deletions
126
concepts/docker.md
Normal file
126
concepts/docker.md
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
# Docker — What It Actually Is
|
||||
|
||||
## The Wrong Mental Model
|
||||
|
||||
Most people think containers are "mini virtual machines." They're not. Understanding the real model is what makes Docker make sense.
|
||||
|
||||
## What a Container Actually Is
|
||||
|
||||
A container is a **process** (or group of processes) running on the host Linux kernel, with two things applied:
|
||||
|
||||
1. **Namespaces** — isolation. The process gets its own view of the filesystem, network, processes, users. It can't see other containers' processes.
|
||||
2. **cgroups (control groups)** — resource limits. The process is limited to a certain amount of CPU, RAM, etc.
|
||||
|
||||
That's it. There's no second kernel. No hypervisor. No hardware emulation. The nginx running in your `homepage` container is a regular Linux process on your laptop — it just *thinks* it's alone.
|
||||
|
||||
This is why containers start in milliseconds (no boot) and use almost no overhead.
|
||||
|
||||
## Images vs Containers
|
||||
|
||||
| Concept | Analogy | What it is |
|
||||
|---------|---------|-----------|
|
||||
| **Image** | A recipe | A read-only template — filesystem layers, default command, environment |
|
||||
| **Container** | A meal cooked from that recipe | A running instance of an image — has its own writable layer on top |
|
||||
|
||||
You can run 10 containers from the same image. They all share the read-only image layers and each gets their own writable layer on top. If a container is deleted, its writable layer is gone. The image remains.
|
||||
|
||||
When you run `docker compose up -d`, Docker:
|
||||
1. Pulls the image if not already local
|
||||
2. Creates a container (adds writable layer)
|
||||
3. Attaches it to the specified networks
|
||||
4. Mounts the volumes
|
||||
5. Starts the process defined in the image's CMD or your compose override
|
||||
|
||||
## Docker Networks — Why the `kitestacks` Network Exists
|
||||
|
||||
Docker creates several default networks. Containers on the **same network** can reach each other by **container name** (Docker has its own DNS built in).
|
||||
|
||||
In this homelab:
|
||||
```
|
||||
docker network create kitestacks
|
||||
```
|
||||
|
||||
Every container joins this network. So when cloudflared routes traffic for `www.kitestacks.com`, it resolves `homepage` via Docker DNS to the container's IP on the `kitestacks` network. Without this shared network, cloudflared can't find the other containers.
|
||||
|
||||
```
|
||||
cloudflared container → DNS lookup "homepage" → 172.x.x.x (homepage container)
|
||||
```
|
||||
|
||||
**`network_mode: host`** is different — the container shares the HOST's network namespace entirely. No isolation. Used for the metrics API so it can read actual host network stats.
|
||||
|
||||
## Volumes — Keeping Data When Containers Are Deleted
|
||||
|
||||
Containers are ephemeral — their writable layer is deleted when the container is removed. To persist data:
|
||||
|
||||
**Bind mount:** Links a host directory to a container path.
|
||||
```yaml
|
||||
volumes:
|
||||
- ./data:/forgejo-data
|
||||
```
|
||||
`./data` on your laptop → `/forgejo-data` inside container. Data lives on your laptop. You can browse it with `ls`.
|
||||
|
||||
**Named volume:** Docker manages the storage location.
|
||||
```yaml
|
||||
volumes:
|
||||
- prometheus-data:/prometheus
|
||||
```
|
||||
Docker stores it in `/var/lib/docker/volumes/prometheus-data/`. You don't specify where.
|
||||
|
||||
**In this homelab:** Databases, config files, and user data use bind mounts (`./data`, `./config`, etc.) so you know exactly where everything is. Named volumes are used where location doesn't matter (Prometheus metrics, Portainer settings).
|
||||
|
||||
## Docker Compose — What It's Doing
|
||||
|
||||
`docker compose up -d` reads `docker-compose.yml` and for each service:
|
||||
1. Ensures the image exists (pull if needed)
|
||||
2. Creates the network if it doesn't exist
|
||||
3. Creates the container with all specified config (env vars, volumes, ports, networks)
|
||||
4. Starts the container
|
||||
|
||||
`-d` means detached — run in background.
|
||||
|
||||
`restart: unless-stopped` means Docker will restart the container if it crashes or if the host reboots — unless you explicitly stop it with `docker compose stop`.
|
||||
|
||||
## Port Mappings
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- "3006:3000"
|
||||
```
|
||||
|
||||
`HOST_PORT:CONTAINER_PORT`
|
||||
|
||||
Port 3000 inside the container is mapped to port 3006 on the host. From the host, `http://localhost:3006` reaches the service. From within the `kitestacks` Docker network, other containers use `http://forgejo:3000` (the container port, via Docker DNS).
|
||||
|
||||
Cloudflare Tunnel doesn't use host ports — it goes through the Docker network directly using the container name and container port.
|
||||
|
||||
## Commands to Know Cold
|
||||
|
||||
```bash
|
||||
# See all running containers
|
||||
docker ps
|
||||
|
||||
# See logs for a container
|
||||
docker logs forgejo
|
||||
docker logs -f forgejo # follow (live tail)
|
||||
|
||||
# Execute a command inside a running container
|
||||
docker exec -it forgejo bash # open a shell
|
||||
docker exec forgejo forgejo admin user list # run a specific command
|
||||
|
||||
# Inspect a container's config
|
||||
docker inspect authentik
|
||||
|
||||
# See all networks
|
||||
docker network ls
|
||||
docker network inspect kitestacks
|
||||
|
||||
# See disk usage
|
||||
docker system df
|
||||
|
||||
# Remove unused images/containers/networks
|
||||
docker system prune
|
||||
```
|
||||
|
||||
## What to Say About Docker
|
||||
|
||||
> *"I containerized every service using Docker and Docker Compose. Each service is isolated in its own container with its own dependencies, connected through a shared Docker bridge network named 'kitestacks' so they can communicate by container name. Data is persisted via bind-mounted host directories. The entire stack is defined in version-controlled YAML files, making it reproducible on any Linux host."*
|
||||
Reference in a new issue