Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| technical:docker-intro [2026/09/11 17:17] – created system | technical:docker-intro [2026/09/13 20:12] (current) – [3 types you'll see:] system | ||
|---|---|---|---|
| Line 7: | Line 7: | ||
| ====== Docker Introduction ====== | ====== 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. | + | * 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. | ||
| + | </ | ||
| ===== What is Docker ===== | ===== What is Docker ===== | ||
| * Docker is an open-source platform that simplifies building, shipping, and running applications by using **containerization**. | * 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**. | * It packages an application with everything it needs to run—code, runtime, libraries, and system tools—into a single, portable unit called a **container**. | ||
| - | ===== Key Concepts | + | ===== Images and Containers |
| - | * I would recommend if the following terms are all new to you that you read this section every day for the newt couple of days so some of the buzzwords stick | + | |
| There are two primary items that can trip you up. | There are two primary items that can trip you up. | ||
| - | - An Image | + | - An Image. |
| - | - A Container | + | - A Container. |
| * The **image** comes first and are used to produce one or more **containers**. | * The **image** comes first and are used to produce one or more **containers**. | ||
| - | * **Image** = recipe / blueprint | + | * **Image** = recipe / blueprint. |
| - | * **Container** = actual meal / house built from that blueprint | + | * **Container** = actual meal / house built from that blueprint. |
| ==== Docker Image ==== | ==== Docker Image ==== | ||
| - | * Read-only template | + | * Read-only template. |
| - | * Contains the OS, code, libraries, env variables — everything needed to run | + | * Contains the OS, code, libraries, env variables — everything needed to run. |
| * You build it or pull it: //(e.g. docker pull nginx)// | * You build it or pull it: //(e.g. docker pull nginx)// | ||
| - | * It sits there, does nothing until you run it | + | * It sits there, does nothing until you run it. |
| - | * You can make 100 copies from one image | + | * You can make 100 copies from one image. |
| - | * Like a class in programming | + | * 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 < | ||
| + | </ | ||
| + | |||
| + | ==== 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 | ||
| + | RUN apt install python | ||
| + | COPY app.py . # Layer 3 - adds your code | ||
| + | CMD python app.py | ||
| + | </ | ||
| + | === 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: | ||
| + | - **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. | ||
| + | </ | ||
| + | <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 | ||
| + | </ | ||
| + | * 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: | ||
| + | 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 | ||
| - | ==== Image ==== | + | networks: |
| - | + | | |
| + | volumes: | ||
| + | pgdata: | ||
| + | </ | ||
| + | * You run it: | ||
| + | <code bash> | ||
| + | docker compose up | ||
| + | </ | ||
| + | * Result: 2 containers running, connected on same network, with volume. | ||
| + | * It doesn' | ||
| - | * RADIUSdesk is designed in such a way that there is a hard separation between the GUI and the web application providing data to the GUI. | + | ==== Analogy: ==== |
| - | * We use Ext JS for the GUI. | + | * You're building a house. |
| - | * Ext JS Classic is used with laptop and desktop browsers. | + | * **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. |
| - | | + | |
| - | | + | |
| - | * This also means that the API calls can be done by any other system thus making third party integration a snap. | + | |
| - | | + | |
| - | | + | |
| - | ====== Common Actions ====== | + | ==== When to use what: ==== |
| - | * Many larger ISPs that makes use of RADIUSdesk prefer it above the commercial one size fits all solutions that already includes CRM and billing components. | + | * You write a Dockerfile once per app/service you create. |
| - | * RADIUSdesk allows for easy integration with existing CRM systems and middle-ware. | + | * You write a docker-compose.yml once per project to run all your services together locally. |
| - | * See the diagram below which illustrates the possibilities. | + | |
| - | <panel type=" | + | 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) | ||
| - | {{: | ||
| - | </ | ||
| - | * Common actions include: | ||
| - | * Adding Profiles. | ||
| - | * Adding Realms. | ||
| - | * Adding Permanent Users. | ||
| - | * Disabling and Enabling Permanent Users. | ||
| - | * Changing Permanent User Profiles. | ||
| - | * Terminating a Permanent User's session. | ||
| - | * Deleting a Permanent User. | ||
| - | * We will cover how to do these actions using the API in dedicated Wiki pages. | ||
| - | + | ===== 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. | ||
| + | </ | ||