Show pageOld revisionsBacklinksBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. <nav type="pills" justified="false"> * [[:user_manuals|Back to Documentation]] * [[:technical:api-intro|Docker Introduction]] </nav> ----- ====== Docker Introduction ====== * If you are like me and a late-comer to the Docker party, the following pages should help you find your way around in the Docker world. <WRAP center round tip 100%> Read this section every day for the next couple of days for some of the buzzwords to stick. </WRAP> ===== What is Docker ===== * Docker is an open-source platform that simplifies building, shipping, and running applications by using **containerization**. * It packages an application with everything it needs to run—code, runtime, libraries, and system tools—into a single, portable unit called a **container**. ===== Images and Containers ===== There are two primary items that can trip you up. - An Image. - A Container. * The **image** comes first and are used to produce one or more **containers**. * **Image** = recipe / blueprint. * **Container** = actual meal / house built from that blueprint. ==== Docker Image ==== * Read-only template. * Contains the OS, code, libraries, env variables — everything needed to run. * You build it or pull it: //(e.g. docker pull nginx)// * It sits there, does nothing until you run it. * You can make 100 copies from one image. * Like a class in programming. ==== Docker Container ==== * Running instance of an image. * When you do docker run nginx — Docker creates a container from the nginx image. * It's alive, has its own process, file system, IP, can be started, stopped, deleted. * You can change stuff inside a container, but those changes don't affect the image unless you commit them. * Like an object created from a class. ==== Docker Image and Container Relationship ==== <code bash> docker run <image> -> creates a -> container </code> ==== Analogy: ==== * Image is like an ISO file for Ubuntu. * Container is Ubuntu actually installed and running on your server. * You can install Ubuntu 10 times from the same ISO. ===== Layers and Volumes ===== ==== Layers ==== * Each Docker image consist of various layers. * This makes images small and fast. * A Docker image is NOT one big file. * It's a stack of layers, like a lasagna. * Each instruction in a Dockerfile = 1 new layer. * Lets look at a simple sample Dockerfile: <code javascript> FROM ubuntu # Layer 1 - base OS RUN apt install python # Layer 2 - adds python COPY app.py . # Layer 3 - adds your code CMD python app.py # Layer 4 - what to run </code> === Why this is genius: === - **Cache:** If you only change app.py, Docker reuses Layer 1 and 2. **It only rebuilds Layer 3**. Super fast. - **Sharing:** If you have 10 images all FROM ubuntu, you only store that ubuntu layer once on disk. - **Read-only:** Image layers are read-only. === Running a Container === * When you run a container, Docker adds one thin writable layer on top. * All your changes inside the container go there. * When you delete the container, that writable layer is gone. * The image layers stay clean. <WRAP center round info 100%> * The image thus typically contains a couple of layers. * When this image is used to produce a container, another writable layer is added specific as part of the container. </WRAP> <code bash> [ Writable Container Layer ] <- you write here, deleted when container dies [ Layer 3 - app.py ] <- read-only [ Layer 2 - python ] <- read-only [ Layer 1 - ubuntu ] <- read-only </code> * That’s why docker run is instant. It doesn't copy anything, it just adds a writable layer. ==== 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:/var/lib/postgresql/data postgres </code> * mydata lives on your host in /var/lib/docker/volumes/ * Container writes to /var/lib/postgresql/data → actually writes to mydata on host. * Delete container → mydata still there. * Start new container with same volume → your DB is still there. ==== 3 types you'll see: ==== - **Named volume** mydata:/app/data - managed by Docker, best for databases. - **Bind mount** ./mycode:/app - you link your local folder to container. Great for development, edit code locally, container sees it instantly. - **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. </WRAP> ===== 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't get lost when you demolish the house. ===== 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 </WRAP> ==== 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 ["python", "app.py"] </code> * You build it: <code bash> docker build -t my-app . </code> * 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: - "5000:5000" volumes: - .:/app depends_on: - db networks: - app-net db: image: postgres:15 # <- uses existing image from Docker Hub environment: POSTGRES_PASSWORD: secret volumes: - pgdata:/var/lib/postgresql/data networks: - app-net networks: app-net: volumes: pgdata: </code> * You run it: <code bash> docker compose up </code> * Result: 2 containers running, connected on same network, with volume. * It doesn't build anything new (unless you tell it build: .). It just orchestrates. ==== 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. </WRAP> technical/docker-intro.txt Last modified: 2026/09/13 20:12by system