Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| technical:docker-intro [2026/09/11 18:30] – system | technical:docker-intro [2026/09/13 20:12] (current) – [3 types you'll see:] system | ||
|---|---|---|---|
| Line 59: | Line 59: | ||
| * It's a stack of layers, like a lasagna. | * It's a stack of layers, like a lasagna. | ||
| * Each instruction in a Dockerfile = 1 new layer. | * Each instruction in a Dockerfile = 1 new layer. | ||
| - | * Lest look at a simple sample Dockerfile: | + | * Lets look at a simple sample Dockerfile: |
| <code javascript> | <code javascript> | ||
| FROM ubuntu | FROM ubuntu | ||
| Line 89: | Line 89: | ||
| * That’s why docker run is instant. It doesn' | * That’s why docker run is instant. It doesn' | ||
| + | ==== Volumes — where data actually lives ==== | ||
| + | * Problem: If container layer dies when container dies, where do you keep databases, uploaded files, etc? | ||
| + | * A volume is a folder on your host machine that is mounted into the container. It lives outside the container lifecycle. | ||
| + | <code bash> | ||
| + | # Without volume - data dies with container | ||
| + | docker run postgres | ||
| + | # With volume - data survives | ||
| + | docker run -v mydata:/ | ||
| + | </ | ||
| + | * mydata lives on your host in / | ||
| + | * Container writes to / | ||
| + | * Delete container → mydata still there. | ||
| + | * Start new container with same volume → your DB is still there. | ||
| + | |||
| + | ==== 3 types you'll see: ==== | ||
| + | - **Named volume** mydata:/ | ||
| + | - **Bind mount** ./ | ||
| + | - **Anonymous volume** - Docker creates random name, don't use it. | ||
| + | |||
| + | <WRAP center round tip 100%> | ||
| + | * The left side is on the host side | ||
| + | * The right side is on the container side. | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== Short Recap ===== | ||
| + | - **Image layers** = how the app is built (efficient, shared, read-only) | ||
| + | - **Container writable layer** = temporary scratch space (dies) | ||
| + | - **Volume** = permanent memory outside the container (survives) | ||
| + | |||
| + | * Image = blueprint | ||
| + | * Layers = pages of the blueprint | ||
| + | * Container = house built from blueprint + a whiteboard inside (writable layer) | ||
| + | * Volume = external garage where you store stuff so it doesn' | ||
| + | |||
| + | ===== Dockerfile and docker-compose.yml ===== | ||
| + | <WRAP center round tip 100%> | ||
| + | * Dockerfile = how to BUILD one image | ||
| + | * docker-compose.yml = how to RUN many containers together | ||
| + | </ | ||
| + | ==== Dockerfile ==== | ||
| + | * Recipe to create an image. One file = one image. | ||
| + | <code bash> | ||
| + | FROM python:3.11 | ||
| + | WORKDIR /app | ||
| + | COPY requirements.txt . | ||
| + | RUN pip install -r requirements.txt | ||
| + | COPY . . | ||
| + | CMD [" | ||
| + | </ | ||
| + | * You build it: | ||
| + | <code bash> | ||
| + | docker build -t my-app . | ||
| + | </ | ||
| + | * Result: an image called my-app. | ||
| + | * It knows nothing about ports, volumes, networks, other containers, environment. | ||
| + | * It only cares about what's inside that one container. | ||
| + | |||
| + | ==== docker-compose.yml ==== | ||
| + | * Blueprint for your whole stack. How containers connect and run together. | ||
| + | <code yaml> | ||
| + | services: | ||
| + | web: | ||
| + | build: . # <- uses your Dockerfile to build | ||
| + | ports: | ||
| + | - " | ||
| + | volumes: | ||
| + | - .:/app | ||
| + | depends_on: | ||
| + | - db | ||
| + | networks: | ||
| + | - app-net | ||
| + | |||
| + | db: | ||
| + | image: postgres: | ||
| + | environment: | ||
| + | POSTGRES_PASSWORD: | ||
| + | volumes: | ||
| + | - pgdata:/ | ||
| + | networks: | ||
| + | - app-net | ||
| + | |||
| + | networks: | ||
| + | app-net: | ||
| + | |||
| + | volumes: | ||
| + | pgdata: | ||
| + | </ | ||
| + | * You run it: | ||
| + | <code bash> | ||
| + | docker compose up | ||
| + | </ | ||
| + | * Result: 2 containers running, connected on same network, with volume. | ||
| + | * It doesn' | ||
| + | |||
| + | ==== Analogy: ==== | ||
| + | * You're building a house. | ||
| + | * **Dockerfile** = instructions for how to build one brick type — what clay, how hot, how long in oven. | ||
| + | * **docker-compose.yml** = architectural plan — where bricks go, where plumbing and electrical go, how 3 houses connect into a neighborhood. | ||
| + | |||
| + | ==== When to use what: ==== | ||
| + | * You write a Dockerfile once per app/service you create. | ||
| + | * You write a docker-compose.yml once per project to run all your services together locally. | ||
| + | |||
| + | You can use Dockerfile without compose: | ||
| + | * docker build + docker run | ||
| + | You cannot use compose without images — either you build them via Dockerfile, or pull them from Hub. | ||
| + | * In short: | ||
| + | * **Dockerfile** -> //docker build// -> Image | ||
| + | * **docker-compose.yml** -> //docker compose up// -> Running containers (built from Dockerfiles or Hub images) | ||
| + | |||
| + | |||
| + | ===== Networking with Docker ===== | ||
| + | * Because networking is usually hands-on, we will cover the Docker networking in the pages which will do hands on exercises. | ||
| + | <WRAP center round tip 100%> | ||
| + | * Network can be specified when you issue the //docker run// command | ||
| + | * Alternatively it can be specified in the docker-compose.yml file and then you issue the //docker compose up// command. | ||
| + | </ | ||