Docker за 10 хвилин (Посібник для початківців)

pic

Фото з Pixabay

Зміст

  • Вступ до Docker та контейнерів
  • Важливі терміни Docker
  • Основні команди Docker — запуск і керування образами та контейнерами Docker
  • Що таке "Dockerfile"?
  • Створення та запуск власних Docker-образів
  • Висновок

Вступ до Docker та контейнерів

Уявіть таку ситуацію: ви розробник, який створив додаток на своєму комп'ютері. Він працює чудово! Але коли ваш колега намагається його запустити, у нього виникають помилки, тому що його комп’ютер відрізняється від вашого. Розчарування, чи не так?

Ось тут і приходить на допомогу Docker. Docker дозволяє вам пакувати додаток у «контейнер» — подумайте про це, як про вантажний контейнер, в якому є все, що потрібно для запуску вашого додатка:

  • сам додаток
  • усе необхідне програмне забезпечення
  • файли конфігурацій
  • налаштування системи

Чому це корисно?

  1. Працює скрізь: ваш контейнер працює однаково на будь-якому комп'ютері
  2. Без конфліктів: кожен контейнер ізольований, тому додатки не заважають один одному
  3. Легко поділитися: надішліть контейнер комусь, і він запрацює миттєво
  4. Економія ресурсів: легший за віртуальні машини

Приклад із реального життя ??? Подумайте про контейнер як про коробку для доставки їжі. Вона містить:

  • основну страву (ваш додаток)
  • усі необхідні інгредієнти (залежності)
  • інструкції по приготуванню (конфігурація)
  • власний простір (ізоляція)

Точно так, як ця коробка гарантує, що ваша їжа приїде точно такою, як її приготував шеф-кухар, так і Docker гарантує, що ваш додаток працюватиме саме так, як ви його створили.

Важливі терміни Docker

pic

Фото з Pixabay

Ось кілька ключових термінів / компонентів / понять, з якими ви часто зіткнетеся, працюючи з Docker:

  • Docker Image (Docker образ): Шаблон, доступний лише для читання, що містить операційну систему, код і залежності.
  • Docker Container (Docker контейнер) (або просто Container (Контейнер)): Запущений екземпляр Docker образу.
  • Image Registry (Реєстр образів): Система зберігання та розповсюдження Docker образів.
  • Dockerfile (Dockerfile): Скрипт, що визначає, як створюється Docker образ.
  • Layer (Шар): Модифікація або доповнення до Docker образу, що формує частину його структури.

Давайте розглянемо кожен термін / компонент / концепцію (з використанням простих прикладів):

i. Docker Image (Docker образ)

Подумайте про це, як про рецепт:

  • Містить точні інструкції для створення середовища вашого додатка
  • Включає код, середовище виконання, бібліотеки, залежності
  • Не можна змінити після створення (тільки для читання)
  • Приклади: образ Ubuntu, образ Node.js або ваш власний образ додатка

ii. Docker Container (Docker контейнер)

Подумайте про це, як про ресторан, що працює:

  • Це ваш образ у дії
  • Можна запускати кілька контейнерів з одного образу
  • Кожен контейнер ізольований від інших
  • Має власні ресурси (ЦП, пам’ять, мережа)

iii. Docker Registry (Реєстр образів)

Подумайте про це, як про магазин додатків:

  • Тут зберігаються і розповсюджуються Docker образи
  • Docker Hub — найпопулярніший реєстр
  • Компанії часто мають приватні реєстри
  • Можна завантажувати/відправляти образи з реєстрів

iv. Dockerfile (Dockerfile)

Подумайте про це, як про набір інструкцій для будівництва:

  • Текстовий файл, що створює Docker образи
  • Перераховує кроки для налаштування вашого середовища
  • Кожна інструкція створює шар
  • Називається точно «Dockerfile»

v. Docker Daemon (Docker демон)

Подумайте про це, як про менеджера кухні:

  • Працює у фоновому режимі на вашому комп’ютері
  • Створює і запускає контейнери
  • Керує Docker об'єктами
  • Контролює життєвий цикл контейнерів

vi. Docker Client (Docker клієнт)

Подумайте про це, як про офіціанта, що приймає замовлення:

  • Інструмент командного рядка (docker)
  • Спілкується з Docker демоном
  • Клієнт надсилає команди Docker демону
  • Демон виконує їх і надсилає результати

vii. Layers (Шари)

Подумайте про це, як про етапи в рецепті:

  • Кожна інструкція в Dockerfile створює шар
  • Шари кешуються для пришвидшення створення образів
  • Шари можуть бути спільними між образами, щоб заощадити місце

✅ Пам’ятайте:

Ці компоненти працюють разом, як добре налаштований механізм.
Images are your blueprints, containers are running instances, registry stores them, Dockerfile creates them, daemon manages them, and client controls them.

Основні команди Docker — запуск і керування Docker образами та контейнерами

pic

Фото від Lech Pierchała

Docker надає тисячі, якщо не мільйони, готових образів (як готові рецепти), які ви можете використовувати для вашого конкретного випадку. Ви можете або використовувати ці образи в їхньому первісному вигляді (як слідування рецепту точно), або використовувати їх як відправну точку для створення свого власного образу (аналогічно коригуванню рецепту під власний смак).

Наприклад, якщо вам потрібно протестувати ваш код на Ubuntu, ви можете просто завантажити готовий образ Ubuntu та запустити його замість того, щоб налаштовувати цілу віртуальну машину з Ubuntu.

У цьому розділі ми розглянемо наступне:

  • Завантаження та видалення Docker образів
  • Запуск контейнерів з Docker образу з різними налаштуваннями
  • Керування запущеними контейнерами

Перед тим, як продовжити, переконайтеся, що Docker встановлено на вашому локальному комп’ютері. Щоб перевірити, запустіть команду docker у вашому терміналі. Якщо Docker встановлений правильно, ви повинні побачити виведення, схоже на це:

pic

Якщо ви не побачили цього, це означає, що Docker не встановлений. Слідуйте інструкціям у цьому посібнику для налаштування: Посібник з встановлення Docker.

Тепер, коли Docker налаштовано на вашому комп'ютері, давайте почнемо з запуску готового Docker образу та взаємодії з контейнерами!!

Подумайте про Docker як про систему франшизи ресторанів.

Давайте зрозуміємо, як запускати та керувати Docker образами:

Завантаження та керування Docker образами

Завантажити образ з Docker Hub:

docker pull python:3.9

Завантажити конкретну версію:

docker pull python:3.9-slim

Виведення виглядатиме приблизно так:

pic

Переглянути всі локальні (включаючи завантажені готові) образи:

docker images

Виведення виглядатиме приблизно так:

pic

Також можна видалити конкретний Docker образ:

docker rmi python:3.9-slim

Видалити всі невикористовувані образи (для звільнення місця):

docker image prune

Запуск контейнерів з образу

Щоб запустити Docker контейнер, використовуйте команду docker run, після якої йде тег образу, ось так: docker run image_tag/image_name.

Ви також можете налаштувати контейнер за допомогою різних параметрів.
Ось деякі часто використовувані параметри, які ви можете використовувати:

  • -it: Отримати інтерактивний термінал (коли потрібно вводити команди)
  • -d: Запуск у фоновому режимі (для сервісів/серверів)
  • -v: Обмін файлами між вашим комп'ютером та контейнером
  • --name: Призначити контейнеру зручне ім’я
  • --memory: Встановити максимальне використання оперативної пам'яті
  • --cpus: Обмежити використання CPU
  • --gpus: Увімкнути доступ до GPU

Я поясню ці параметри за допомогою різних команд.

Базова команда запуску:

docker run python:3.9-slim

Запуск контейнера в інтерактивному терміналі:

docker run -it python:3.9 bash

Виведення виглядатиме приблизно так:

pic

Запуск контейнера у фоновому режимі (відключений):

docker run -d python:3.9

Запуск з ім'ям:

docker run --name my-python python:3.9

Запуск контейнера з визначеними лімітами ресурсів:

docker run -memory=512m -cpus=2 python:3.9

Запуск з мапуванням портів:

docker run -p 5000:5000 python:3.9

Встановлення змінних середовища під час запуску контейнера:

docker run -e DB_HOST=localhost python:3.9

Монтування тому (обмін файлами) в контейнер:

docker run -v /local/path:/container/path python:3.9

Дозволити доступ до GPU для контейнера:

docker run --gpus all python:3.9

Керування запущеними/зупиненими контейнерами

Є кілька команд для керування контейнерами, як для запущених, так і для зупинених. Розглянемо їх по черзі.

Переглянути, що зараз працює:

docker ps

Виведення виглядатиме приблизно так:

pic

Переглянути всі контейнери (включаючи зупинені):

docker ps -a

Виведення виглядатиме приблизно так:

pic

Зупинити контейнер:

docker stop container_id

Запустити вже зупинений контейнер:

docker start container_id

Перезапустити запущений або зупинений контейнер:

docker restart container_id

Видалити зупинений контейнер:

docker rm container_id

Моніторинг використання ресурсів запущеного контейнера:

docker stats container_name_or_id

Виведення виглядатиме приблизно так:

pic

Декілька корисних порад, які варто пам'ятати:

  • Завжди надавайте контейнерам ім'я за допомогою --name для зручності посилання
  • Використовуйте docker ps -a, щоб знайти контейнери, які займають місце
  • Очищуйте регулярно за допомогою docker system prune
  • Починайте з інтерактивного режиму (-it), коли вивчаєте або налагоджуєте
  • Використовуйте фоновий режим (-d) для запуску сервісів

Що таке “Dockerfile”?

pic

Фото від Antoni Shkraba

Dockerfile — це як рецепт, який говорить Docker, як створити образ. Це фактично текстовий файл, який містить серію інструкцій, що визначають, що повинно бути включено в образ і як він має поводитись. Кожна інструкція в Dockerfile створює новий шар в результатуючому Docker образі.

Давайте подивимося на 👇🏻

Основні ролі Dockerfile:

i. Специфікація базового образу (FROM):

  • Визначає стартову точку для образу, таку як конкретна операційна система або попередньо побудоване середовище (наприклад, ubuntu, node, python).
  • Приклад: FROM ubuntu:20.04

ii. Інтеграція коду додатку (COPY):

  • Копіює ваш код додатку та файли в образ.
  • Приклад: COPY . /app

iii. Налаштування середовища (RUN):

  • Дозволяє встановлювати програмне забезпечення, копіювати файли та налаштовувати параметри, необхідні для додатку.
  • Приклад: Встановлення залежностей за допомогою RUN apt-get install -y curl або RUN pip install -r requirements.txt

iv.
Оголошення порту (EXPOSE):

  • Визначає мережеві порти, на яких контейнер слухатиме під час виконання.
  • Приклад: EXPOSE 5000 оголошує, що контейнер слухає порт 5000.
  • Примітка: Щоб зробити цей порт доступним ззовні контейнера, потрібно явно мапувати його під час запуску контейнера, використовуючи -p параметр.

v. Специфікація команди (CMD):

  • Визначає команди, які потрібно виконати при запуску контейнера, такі як запуск сервера чи додатку.
  • Приклад: CMD ["python", "app.py"]

Приклад Dockerfile

Dockerfile виглядає приблизно так:

# Використовуємо офіційне середовище Python як базовий образ  
FROM python:3.9-slim  

# Встановлюємо змінні середовища  
ENV APP_ENV=production  
ENV APP_PORT=5000  

# Встановлюємо робочий каталог всередині контейнера  
WORKDIR /app  

# Копіюємо код додатку в контейнер  
COPY . /app  

# Встановлюємо залежності  
RUN pip install -r requirements.txt  

# Оголошуємо порт, на якому працюватиме додаток  
EXPOSE 5000  

# Визначаємо команду для запуску додатку  
CMD ["python", "app.py"]

Зазвичай Dockerfile починається з визначення базового образу, після чого копіюється код додатку в образ. Потім додаються всі необхідні команди RUN, які виконуються під час побудови образу, наприклад, для встановлення залежностей. Наприкінці визначається точка входу для Docker образу, щоб вказати, як має запускатися контейнер.

Кілька моментів щодо Dockerfile:

  • Має бути названим точно “Dockerfile”
  • Кожна інструкція створює шар
  • Інструкції виконуються по черзі, згортаючись згори вниз

Тепер, коли ми чітко розуміємо, що таке Dockerfile, давайте перейдемо до створення власного кастомного образу за допомогою нього.

Створення та запуск власного Docker образу

pic

Фото від David Kanigan

Щоб краще зрозуміти, як створювати кастомні образи, ми створимо Flask API, побудуємо для нього образ і запустимо Flask API в контейнері.

Ми пройдемо через це крок за кроком.

Код проєкту можна знайти тут: https://github.com/rumanxyz/docker-flask-app

1. Структура проєкту

Спочатку налаштуємо наш проєкт:

./docker-flask-app/  
├── Dockerfile  
├── app.py  
└── requirements.txt

2. Файли додатку

requirements.txt

Тут ми вказуємо всі необхідні Python пакети, які потрібні для запуску API.

flask==2.3.3

app.py

Flask API, яке працюватиме на порту 5000.

from flask import Flask, jsonify  

app = Flask(__name__)  

@app.route('/api/hello', methods=['GET'])  
def hello():  
 return jsonify({"message": "Hello from Docker!"})  

if __name__ == '__main__':  
 app.run(host='0.0.0.0', port=5000)

Dockerfile

# визначаємо базовий образ  
FROM python:3.10-slim  

# встановлюємо робочий каталог  
WORKDIR /app  

# спочатку копіюємо requirements (для кращого кешування)  
COPY requirements.txt .  

# встановлюємо залежності  
RUN pip install -r requirements.txt  

# копіюємо код додатку  
COPY . .  

# оголошуємо порт для доступу до контейнера  
EXPOSE 5000  

# команда для запуску  
CMD ["python", "app.py"]

Тепер, коли ми написали файли додатку, давайте спочатку протестуємо їх локально. Коли ви запустите Flask додаток, ви побачите виведення, подібне до цього:

pic

Якщо ми відкриємо http://127.0.0.1:5000/api/hello локально, ми побачимо відповідь API, подібну до цієї:

pic

Тепер, коли ми переконалися, що наш API працює, давайте перейдемо до створення Docker образу для нього.

3.

Створення Docker образу

Давайте створимо образ без кешу (чисте створення)

docker build --no-cache -t my-flask-api:1.0 .

Зверніть увагу:

  • -t тегує ваш образ (ім'я:версія)
  • . означає використання поточної директорії
  • Завжди версіонуйте свої образи (1.0, 1.1 тощо)

Після запуску команди побудови ви побачите щось подібне:

pic

Тепер давайте перевіримо Docker образи та подивимось, чи був створений образ. Це можна зробити за допомогою команди docker images. І ось ви побачите образ my-flask-api з версією 1.0, який був створений нещодавно.

Тепер давайте перевіримо Docker образи, щоб побачити, чи був успішно створений образ. Це можна зробити за допомогою команди docker images. Ви повинні побачити образ my-flask-api з версією 1.0, який був створений нещодавно.

pic

4. Запуск вашого контейнера

Запуск контейнера з змінними середовища та кастомним ім'ям

# Запуск з змінними середовища  
docker run -d -p 5000:5000 \  
 --name my-api-test \  
 -e FLASK_ENV=development \  
 my-flask-api:1.0

Тут “my-flask-api:1.0” — це Docker образ, який ми створили.

Якщо ми запустимо docker ps, ви побачите контейнер, який працює.

pic

Тепер давайте протестуємо API.

5. Тестування вашого API

Ми можемо протестувати це за допомогою команди curl:

curl http://localhost:5000/api/hello

Виведення, яке я отримав після виконання цієї команди:

pic

Ми успішно створили Flask додаток, запакували його в Docker за допомогою Dockerfile, запустили контейнер з образом і нарешті протестували API.

Але ось деякі поширені проблеми, з якими ви можете стикнутися, і [можливі] рішення:

Порт вже використовується:

  • Зупиніть інші контейнери, які використовують порт 5000
  • Або використовуйте інший порт: -p 5001:5000

Контейнер відразу зупиняється:

  • Перевірте журнали: docker logs my-api
  • Переконайтеся, що команда CMD вірна
  • Спробуйте запустити в інтерактивному режимі

Не вдається отримати доступ до API:

  • Перевірте, чи працює контейнер
  • Перевірте мапування портів
  • Переконайтесь, що host='0.0.0.0' у Flask додатку

Висновок

Docker став важливим інструментом у сучасній розробці програмного забезпечення, спрощуючи процес створення, доставки та запуску додатків. В рамках цієї статті ми охопили основи — від розуміння контейнерів та образів до запуску вже готових образів і створення власних кастомних контейнерів. Завдяки знанню базових команд Docker та синтаксису Dockerfile, ви тепер готові контейнеризувати свої додатки.

Пам'ятайте, що справжня сила Docker полягає в його послідовності та портативності —

“це працює на моєму комп'ютері” перетворюється на “це працює скрізь”.

Продовжуючи свою подорож з Docker, вивчайте Docker Compose для управління кількома контейнерами, досліджуйте мережі контейнерів і знайомтесь з оркестрацією контейнерів за допомогою таких інструментів, як Kubernetes. Офіційна документація Docker (docs.docker.com) є чудовим ресурсом для глибшого вивчення цих тем.

Якщо вам сподобалась ця стаття, ваші аплодисменти будуть дуже оцінені!

pic

Перекладено з: Docker in 10 Minute (Guide for Beginners)

Leave a Reply

Your email address will not be published. Required fields are marked *