Skip to content
Snippets Groups Projects

Docker для початківців у DevOps

  • Clone with SSH
  • Clone with HTTPS
  • Embed
  • Share
    The snippet can be accessed without any authentication.
    Authored by Alexander Zavoloka

    Зміст

    Що таке Docker

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

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

    Проблеми, які вирішує Docker

    Docker вирішує ряд важливих проблем, з якими стикаються розробники та DevOps-інженери:

    1. Проблема "працює на моєму комп'ютері" — коли програма коректно працює в середовищі розробки, але виходить з ладу при перенесенні на тестування чи в продакшн.

    2. Складна налаштування середовища — коли потрібно витрачати багато часу на налаштування серверів та залежностей.

    3. Конфлікти залежностей — коли різні додатки потребують різних версій однієї й тієї ж бібліотеки.

    4. Неефективне використання ресурсів — порівняно з віртуальними машинами, які вимагають багато ресурсів.

    5. Складність масштабування — традиційний спосіб масштабування додатків вимагає більше зусиль і часу.

    Як виглядала розробка до Docker

    До появи Docker процес розробки та розгортання програмного забезпечення стикався з багатьма труднощами:

    1. Традиційне розгортання на фізичних серверах

    Розробник --> Тестувальник --> Адміністратор
    (Працює    --> Не працює   --> Потрібні додаткові зусилля)
    (Win/Mac)  --> (Linux)     --> (Продакшн сервер)
    • Для кожного додатка зазвичай виділявся окремий фізичний сервер
    • Ресурси використовувались неефективно
    • Розгортання займало дні або тижні
    • Складний процес оновлення та мігрування

    2. Віртуальні машини (VM)

    +---------------------------+
    | Додаток A | Додаток B     |
    +---------------------------+
    | Гостьова ОС | Гостьова ОС |
    +---------------------------+
    |        Hypervisor         |
    +---------------------------+
    |        Хост ОС            |
    +---------------------------+
    |        Сервер             |
    +---------------------------+
    • Кращий рівень ізоляції
    • Але вимагали повноцінну гостьову ОС для кожної VM
    • Споживали багато ресурсів (CPU, RAM, дисковий простір)
    • Займали час на завантаження
    • Вимагали ліцензій для кожної ОС
    • Складно автоматизувати

    3. Ручне налаштування середовища

    • Розробники писали документацію з інструкціями встановлення
    • Системні адміністратори вручну налаштовували кожен сервер
    • Складний процес відтворення ідентичного середовища
    • Багато часу на діагностику помилок середовища

    Переваги використання Docker

    Docker надає ряд значних переваг для сучасної розробки:

    1. Легка переносимість

      • "Build once, run anywhere" (Збирай один раз, запускай де завгодно)
      • Однакова поведінка в різних середовищах
    2. Швидкість

      • Контейнери запускаються за секунди
      • Швидкий процес розробки та тестування
    3. Ефективне використання ресурсів

      • Контейнери набагато легші за VM
      • Можливість запускати більше екземплярів на тому ж обладнанні
    4. Ізоляція

      • Додатки працюють незалежно один від одного
      • Зменшення конфліктів залежностей
    5. Повторюваність

      • Гарантовано однакове середовище в будь-який час
      • Декларативний опис середовища (Інфраструктура як код)
    6. Масштабованість

      • Легко масштабувати додатки горизонтально
      • Інтеграція з оркестраторами (Kubernetes, Docker Swarm)
    7. Версійність

      • Легко відстежувати зміни в інфраструктурі
      • Можливість швидкого відкату до попередньої версії

    Розробка з Docker

    Використання Docker істотно змінює процес розробки:

    1. Стандартизоване середовище

    +-------------------+    +-------------------+    +-------------------+
    | Середовище розр.  |    | Тестове середов.  |    | Продакшн середов. |
    +-------------------+    +-------------------+    +-------------------+
    |    Контейнер A    |    |    Контейнер A    |    |    Контейнер A    |
    +-------------------+    +-------------------+    +-------------------+
    |      Docker       |    |      Docker       |    |      Docker       |
    +-------------------+    +-------------------+    +-------------------+
    |   Windows/Mac/Lin |    |      Linux        |    |      Linux        |
    +-------------------+    +-------------------+    +-------------------+
    • Ідентичне середовище на всіх етапах
    • Менше помилок, пов'язаних із відмінностями середовищ

    2. DevOps практики

    • Пришвидшення циклу розробки
    • CI/CD інтеграція (легка автоматизація тестів та розгортання)
    • Інфраструктура як код (IaC)
    • Зручні відкати до попередніх версій

    3. Локальна розробка

    • Розробники можуть працювати з мікросервісами локально
    • Можливість репродукувати складні мультисервісні системи на одній машині
    • Швидкий старт для нових розробників у проекті

    Dockerfile

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

    Структура Dockerfile

    # Базовий образ
    FROM node:14
    
    # Метадані
    LABEL maintainer="example@gmail.com"
    LABEL version="1.0"
    
    # Встановлення робочої директорії
    WORKDIR /app
    
    # Копіювання файлів
    COPY package*.json ./
    
    # Виконання команд
    RUN npm install
    
    # Копіювання решти файлів
    COPY . .
    
    # Відкриття портів
    EXPOSE 3000
    
    # Змінні оточення
    ENV NODE_ENV=production
    
    # Команда для запуску
    CMD ["npm", "start"]

    Пояснення основних інструкцій

    • FROM — визначає базовий образ, з якого починається збірка
    • LABEL — додає метадані до образу
    • WORKDIR — встановлює робочу директорію для наступних інструкцій
    • COPY/ADD — копіює файли з хоста до контейнера
    • RUN — виконує команди під час збірки образу
    • EXPOSE — інформує про порти, які слухає контейнер
    • ENV — встановлює змінні оточення
    • CMD/ENTRYPOINT — визначає команду, яка виконується при запуску контейнера

    Приклад Dockerfile для Python застосунку

    # Базовий образ з Python 3.9
    FROM python:3.9-slim
    
    # Метадані
    LABEL maintainer="developer@example.com"
    LABEL description="Simple Flask application"
    
    # Встановлення робочої директорії
    WORKDIR /app
    
    # Встановлення залежностей
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    
    # Копіювання коду застосунку
    COPY . .
    
    # Визначення змінної оточення
    ENV FLASK_APP=app.py
    ENV FLASK_ENV=production
    
    # Відкриття порту
    EXPOSE 5000
    
    # Запуск застосунку
    CMD ["flask", "run", "--host=0.0.0.0"]

    Кроки для створення та використання Dockerfile

    1. Створіть файл з назвою Dockerfile (без розширення) у кореневій директорії вашого проекту
    2. Напишіть інструкції збірки образу
    3. Збудуйте образ за допомогою команди docker build
    4. Використовуйте образ для створення контейнерів
    # Створення образу
    docker build -t myapp:latest .
    
    # Перевірка створеного образу
    docker images

    Кращі практики для Dockerfile

    1. Використовуйте .dockerignore — для виключення непотрібних файлів
    2. Групуйте інструкції RUN — щоб зменшити кількість шарів
    3. Використовуйте багатоетапну збірку — для зменшення розміру фінального образу
    4. Встановлюйте конкретні версії — для забезпечення стабільності
    5. Мінімізуйте кількість шарів — об'єднуйте команди де це можливо

    Docker Image

    Docker Image (образ) — це легкий, автономний, виконуваний пакет, який включає все необхідне для запуску додатка: код, runtime, системні інструменти, бібліотеки та налаштування.

    Характеристики Docker Image

    • Незмінний (Immutable) — після створення не може бути змінений
    • Багатошаровий — складається з шарів, які можуть бути повторно використані
    • Базується на UnionFS — файлова система, що дозволяє шарам працювати як одне ціле
    • Може бути розповсюджений через Container Registry

    Структура Docker Image

    +---------------------------+
    |    Додаток (верхній шар)  |
    +---------------------------+
    |    Залежності             |
    +---------------------------+
    |    Налаштування           |
    +---------------------------+
    |    Базовий образ (ОС)     |
    +---------------------------+

    Команди для роботи з образами

    # Перегляд доступних образів
    docker images
    
    # Завантаження образу з Docker Hub
    docker pull nginx:latest
    
    # Збірка образу з Dockerfile
    docker build -t myapp:1.0 .
    
    # Перейменування образу
    docker tag myapp:1.0 username/myapp:1.0
    
    # Завантаження образу в Container Registry
    docker push username/myapp:1.0
    
    # Видалення образу
    docker rmi myapp:1.0
    
    # Перегляд історії шарів образу
    docker history myapp:1.0
    
    # Інспектування метаданих образу
    docker inspect myapp:1.0

    Приклад багатоетапної збірки

    Багатоетапна збірка дозволяє зменшити розмір фінального образу:

    # Етап збірки
    FROM node:14 AS builder
    WORKDIR /app
    COPY package*.json ./
    RUN npm install
    COPY . .
    RUN npm run build
    
    # Етап продакшн
    FROM nginx:alpine
    COPY --from=builder /app/build /usr/share/nginx/html
    EXPOSE 80
    CMD ["nginx", "-g", "daemon off;"]

    Приклад створення та використання образу

    1. Створіть просту Node.js програму
    # Створення директорії проекту
    mkdir docker-node-example
    cd docker-node-example
    
    # Створення файлу package.json
    cat > package.json << EOF
    {
      "name": "docker-node-example",
      "version": "1.0.0",
      "main": "index.js",
      "scripts": {
        "start": "node index.js"
      },
      "dependencies": {
        "express": "^4.17.1"
      }
    }
    EOF
    
    # Створення файлу index.js
    cat > index.js << EOF
    const express = require('express');
    const app = express();
    const PORT = process.env.PORT || 3000;
    
    app.get('/', (req, res) => {
      res.send('Hello from Docker!');
    });
    
    app.listen(PORT, () => {
      console.log(\`Server running on port \${PORT}\`);
    });
    EOF
    
    # Створення Dockerfile
    cat > Dockerfile << EOF
    FROM node:14-alpine
    WORKDIR /app
    COPY package*.json ./
    RUN npm install
    COPY . .
    EXPOSE 3000
    CMD ["npm", "start"]
    EOF
    1. Збудуйте образ та запустіть контейнер
    # Збірка образу
    docker build -t node-app:1.0 .
    
    # Перевірка створеного образу
    docker images
    
    # Запуск контейнера
    docker run -p 3000:3000 -d --name my-node-app node-app:1.0
    
    # Перевірка запущеного контейнера
    docker ps
    
    # Перевірка роботи програми
    curl http://localhost:3000

    Docker Container

    Docker Container (контейнер) — це запущений екземпляр Docker образу. Це легке, ізольоване середовище виконання, що містить все необхідне для роботи додатка.

    Характеристики контейнерів

    • Ізольовані — використовують namespace та cgroups Linux для ізоляції
    • Легкі — використовують образ на основі шарів і розділяють ядро ОС
    • Динамічні — можуть бути легко запущені, зупинені, переміщені
    • Стан — на відміну від образів, мають стан і можуть змінюватися

    Порівняння з віртуальними машинами

    +------------+  +------------+    +-------------+  +-------------+
    | Додаток A  |  | Додаток B  |    | Додаток A   |  | Додаток B   |
    +------------+  +------------+    +-------------+  +-------------+
    |    Bins/   |  |    Bins/   |    | Гостьова ОС |  | Гостьова ОС |
    |    Libs    |  |    Libs    |    +-------------+  +-------------+
    +------------+  +------------+    |         Hypervisor           |
    |       Docker Engine         |    +-----------------------------+
    +----------------------------+    |          Хост ОС             |
    |          Хост ОС           |    +-----------------------------+
    +----------------------------+    |         Інфраструктура       |
    |        Інфраструктура      |    +-----------------------------+
    +----------------------------+    
    
        Контейнери Docker                Віртуальні машини

    Життєвий цикл контейнера

         +--------+
         | Образ  |
         +--------+
             |
             v
    +-----------------+        +------------------+
    | Створення       | -----> | Запуск           |
    +-----------------+        +------------------+
                                       |
                                       v
                               +------------------+        +----------------+
                               | Робота           | -----> | Зупинка        |
                               +------------------+        +----------------+
                                                             |
                                                             v
                                                       +----------------+
                                                       | Видалення      |
                                                       +----------------+

    Основні команди для роботи з контейнерами

    # Запуск контейнера
    docker run -d --name web -p 80:80 nginx
    
    # Перегляд запущених контейнерів
    docker ps
    
    # Перегляд всіх контейнерів (включно зі зупиненими)
    docker ps -a
    
    # Зупинка контейнера
    docker stop web
    
    # Запуск зупиненого контейнера
    docker start web
    
    # Перезапуск контейнера
    docker restart web
    
    # Видалення контейнера (має бути зупинений)
    docker rm web
    
    # Видалення контейнера (навіть якщо запущений)
    docker rm -f web
    
    # Перегляд логів контейнера
    docker logs web
    
    # Виконання команди всередині контейнера
    docker exec -it web bash
    
    # Копіювання файлів в/з контейнер
    docker cp file.txt web:/path/in/container/
    docker cp web:/path/in/container/file.txt ./local-path/

    Приклад запуску та взаємодії з контейнером

    1. Запуск контейнера з веб-сервером nginx:
    # Запуск контейнера nginx
    docker run -d --name my-nginx -p 8080:80 nginx
    
    # Перевірка запущених контейнерів
    docker ps
    
    # Перевірка роботи веб-сервера
    curl http://localhost:8080
    1. Налаштування контейнера:
    # Створення HTML-файлу на хості
    echo "<h1>My Custom Nginx Page</h1>" > index.html
    
    # Копіювання файлу в контейнер
    docker cp index.html my-nginx:/usr/share/nginx/html/
    
    # Перевірка змін
    curl http://localhost:8080
    1. Збереження змін у новий образ:
    # Створення нового образу на основі змін у контейнері
    docker commit my-nginx my-custom-nginx:1.0
    
    # Перевірка нового образу
    docker images
    
    # Запуск контейнера з нового образу
    docker run -d --name custom-nginx -p 8081:80 my-custom-nginx:1.0
    
    # Перевірка
    curl http://localhost:8081

    Монтування томів (Volumes)

    Томи дозволяють зберігати дані поза контейнером:

    # Створення тому
    docker volume create my-data
    
    # Запуск контейнера з монтуванням тому
    docker run -d --name db -v my-data:/var/lib/mysql mysql:5.7
    
    # Прямий маппінг директорії з хоста
    docker run -d --name web -v $(pwd)/html:/usr/share/nginx/html -p 8080:80 nginx

    Обмеження ресурсів контейнера

    # Обмеження CPU та пам'яті
    docker run -d --name limited-app \
      --cpus=0.5 \
      --memory=512m \
      my-app:1.0

    Docker Compose

    Docker Compose — це інструмент для визначення та запуску багатоконтейнерних Docker додатків. Він використовує YAML-файл для налаштування сервісів, мереж та томів.

    Проблеми, які вирішує Docker Compose

    1. Складність управління багатьма контейнерами — через CLI потрібно виконувати багато команд
    2. Взаємозалежність контейнерів — контейнери потрібно запускати в певному порядку
    3. Повторюваність середовища — тяжко забезпечити однакові параметри запуску
    4. Складність в управлінні томами та мережами — потребує додаткових команд

    Структура docker-compose.yml файлу

    version: '3'
    
    services:
      web:
        image: nginx:latest
        ports:
          - "80:80"
        volumes:
          - ./html:/usr/share/nginx/html
        depends_on:
          - app
    
      app:
        build: ./app
        environment:
          - DB_HOST=db
          - DB_USER=root
          - DB_PASSWORD=example
        depends_on:
          - db
    
      db:
        image: mysql:5.7
        volumes:
          - db_data:/var/lib/mysql
        environment:
          - MYSQL_ROOT_PASSWORD=example
          - MYSQL_DATABASE=myapp
    
    volumes:
      db_data:
    
    networks:
      default:
        driver: bridge

    Основні секції та параметри

    • version — версія формату Compose файлу
    • services — визначення сервісів (контейнерів)
      • image — використовуваний Docker образ
      • build — шлях до Dockerfile для збірки образу
      • ports — публікація портів (хост:контейнер)
      • volumes — монтування томів
      • environment — змінні оточення
      • depends_on — залежності між сервісами
      • restart — політика перезапуску
    • volumes — визначення іменованих томів
    • networks — налаштування мереж

    Основні команди Docker Compose

    # Запуск всіх сервісів (в фоновому режимі)
    docker-compose up -d
    
    # Зупинка всіх сервісів
    docker-compose down
    
    # Зупинка і видалення всіх сервісів (включно з томами)
    docker-compose down -v
    
    # Перегляд статусу сервісів
    docker-compose ps
    
    # Перегляд логів
    docker-compose logs
    
    # Логі конкретного сервісу
    docker-compose logs app
    
    # Виконання команди в сервісі
    docker-compose exec app bash
    
    # Масштабування сервісу
    docker-compose up -d --scale web=3

    Приклад повноцінного веб-додатка з Docker Compose

    Створімо простий веб-додаток із трьома компонентами: веб-сервер, бекенд API та база даних.

    1. Структура проекту:
    my-docker-app/
    ├── docker-compose.yml
    ├── nginx/
    │   ├── Dockerfile
    │   └── default.conf
    ├── api/
    │   ├── Dockerfile
    │   ├── package.json
    │   ├── index.js
    │   └── ...
    ├── db/
    │   └── init.sql
    └── .env
    1. Файл .env з змінними оточення:
    DB_USER=appuser
    DB_PASSWORD=apppassword
    DB_NAME=appdb
    DB_PORT=5432
    1. Створення docker-compose.yml:
    version: '3'
    
    services:
      nginx:
        build: ./nginx
        ports:
          - "80:80"
        depends_on:
          - api
        networks:
          - frontend
    
      api:
        build: ./api
        environment:
          - DB_HOST=db
          - DB_USER=${DB_USER}
          - DB_PASSWORD=${DB_PASSWORD}
          - DB_NAME=${DB_NAME}
          - NODE_ENV=production
        depends_on:
          - db
        networks:
          - frontend
          - backend
    
      db:
        image: postgres:13
        volumes:
          - db_data:/var/lib/postgresql/data
          - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql
        environment:
          - POSTGRES_USER=${DB_USER}
          - POSTGRES_PASSWORD=${DB_PASSWORD}
          - POSTGRES_DB=${DB_NAME}
        ports:
          - "${DB_PORT}:5432"
        networks:
          - backend
    
    volumes:
      db_data:
    
    networks:
      frontend:
      backend:
    1. Створення Nginx конфігурації:
    # Створення директорії
    mkdir -p nginx
    
    # Створення конфігураційного файлу
    cat > nginx/default.conf << EOF
    server {
        listen 80;
        server_name localhost;
    
        location / {
            proxy_pass http://api:3000;
            proxy_set_header Host \$host;
            proxy_set_header X-Real-IP \$remote_addr;
        }
    }
    EOF
    
    # Створення Dockerfile для Nginx
    cat > nginx/Dockerfile << EOF
    FROM nginx:alpine
    COPY default.conf /etc/nginx/conf.d/default.conf
    EOF
    1. Створення Node.js API:
    # Створення директорії
    mkdir -p api
    
    # Створення package.json
    cat > api/package.json << EOF
    {
      "name": "docker-api-example",
      "version": "1.0.0",
      "main": "index.js",
      "scripts": {
        "start": "node index.js"
      },
      "dependencies": {
        "express": "^4.17.1",
        "pg": "^8.5.1"
      }
    }
    EOF
    
    # Створення index.js
    cat > api/index.js << EOF
    const express = require('express');
    const { Pool } = require('pg');
    const app = express();
    const PORT = process.env.PORT || 3000;
    
    // Підключення до PostgreSQL
    const pool = new Pool({
      user: process.env.DB_USER,
      host: process.env.DB_HOST,
      database: process.env.DB_NAME,
      password: process.env.DB_PASSWORD,
      port: 5432,
    });
    
    app.use(express.json());
    
    // Основний маршрут
    app.get('/', (req, res) => {
      res.json({ message: 'API працює!' });
    });
    
    // Запит до бази даних
    app.get('/users', async (req, res) => {
      try {
        const result = await pool.query('SELECT * FROM users');
        res.json(result.rows);
      } catch (err) {
        console.error(err);
        res.status(500).json({ error: 'Помилка бази даних' });
      }
    });
    
    app.listen(PORT, () => {
      console.log(\`API сервер запущено на порту \${PORT}\`);
    });
    EOF
    
    # Створення Dockerfile для API
    cat > api/Dockerfile << EOF
    FROM node:14-alpine
    WORKDIR /app
    COPY package*.json ./
    RUN npm install
    COPY . .
    EXPOSE 3000
    CMD ["npm", "start"]
    EOF
    1. Створення ініціалізаційного скрипта для бази даних:
    # Створення директорії
    mkdir -p db
    
    # Створення скрипта ініціалізації
    cat > db/init.sql << EOF
    CREATE TABLE IF NOT EXISTS users (
      id SERIAL PRIMARY KEY,
      name VARCHAR(100) NOT NULL,
      email VARCHAR(100) UNIQUE NOT NULL,
      created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );
    
    INSERT INTO users (name, email) VALUES
      ('Іван Петренко', 'ivan@example.com'),
      ('Марія Коваленко', 'maria@example.com');
    EOF
    1. Запуск додатка з Docker Compose:
    # Запуск всіх сервісів
    docker-compose up -d
    
    # Перевірка статусу
    docker-compose ps
    
    # Тестування API
    curl http://localhost/users
    1. Керування додатком:
    # Перегляд логів всіх сервісів
    docker-compose logs
    
    # Перегляд логів конкретного сервісу
    docker-compose logs api
    
    # Зупинка всіх сервісів
    docker-compose stop
    
    # Запуск сервісів знову
    docker-compose start
    
    # Зупинка і видалення всіх контейнерів
    docker-compose down
    
    # Зупинка, видалення контейнерів і томів
    docker-compose down -v

    Container Registry

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

    Типи Container Registry

    1. Публічні реєстри

      • Docker Hub — офіційний реєстр Docker
      • GitHub Container Registry — інтегрований з GitHub
      • Quay.io — від Red Hat
      • Google Container Registry — від Google Cloud
    2. Приватні реєстри

      • AWS Elastic Container Registry — від Amazon
      • Azure Container Registry — від Microsoft
      • GitLab Container Registry — інтегрований з GitLab
      • JFrog Artifactory — універсальний репозиторій
    3. Локальні реєстри

      • Docker Registry — базовий реєстр з відкритим кодом
      • Harbor — корпоративний реєстр з підтримкою безпеки
      • Nexus Repository — багатоцільовий репозиторій

    Docker Hub

    Docker Hub — це найпопулярніший публічний реєстр для Docker образів. Він містить більше мільйона офіційних та спільнотних образів.

    Можливості Docker Hub:

    • Публічні та приватні репозиторії
    • Офіційні образи — підтримуються Docker Inc
    • Автоматична збірка — інтеграція з GitHub/BitBucket
    • Команди — колективний доступ
    • Вебхуки — автоматизація CI/CD

    Робота з Docker Hub:

    1. Реєстрація на Docker Hub:

      • Відвідайте hub.docker.com
      • Створіть обліковий запис
    2. Авторизація в CLI:

    docker login
    1. Робота з образами:
    # Завантаження образу
    docker pull nginx:latest
    
    # Перейменування образу для відправки
    docker tag my-app:1.0 username/my-app:1.0
    
    # Відправка образу в Docker Hub
    docker push username/my-app:1.0
    
    # Пошук образів
    docker search nginx

    Локальний реєстр

    Локальний реєстр дозволяє зберігати образи в приватній мережі, що важливо для:

    • Зменшення залежності від зовнішніх сервісів
    • Підвищення безпеки
    • Пришвидшення завантаження образів

    Запуск локального реєстру з Docker:

    # Запуск простого реєстру
    docker run -d -p 5000:5000 --name registry registry:2
    
    # Запуск реєстру з постійним сховищем
    docker run -d -p 5000:5000 --name registry \
      -v $PWD/registry-data:/var/lib/registry \
      registry:2

    Використання локального реєстру:

    # Перейменування образу для локального реєстру
    docker tag my-app:1.0 localhost:5000/my-app:1.0
    
    # Відправка образу в локальний реєстр
    docker push localhost:5000/my-app:1.0
    
    # Завантаження образу з локального реєстру
    docker pull localhost:5000/my-app:1.0

    Налаштування безпеки реєстру:

    1. Створення сертифіката та ключа:
    mkdir -p certs
    openssl req -newkey rsa:4096 -nodes -sha256 \
      -keyout certs/domain.key -x509 -days 365 \
      -out certs/domain.crt
    1. Запуск реєстру з HTTPS:
    docker run -d -p 5000:5000 --name registry \
      -v $PWD/certs:/certs \
      -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
      -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
      registry:2
    1. Запуск реєстру з базовою автентифікацією:
    # Створення файлу з паролем
    mkdir auth
    docker run --entrypoint htpasswd registry:2 -Bbn myuser mypassword > auth/htpasswd
    
    # Запуск реєстру з автентифікацією
    docker run -d -p 5000:5000 --name registry \
      -v $PWD/auth:/auth \
      -e "REGISTRY_AUTH=htpasswd" \
      -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
      -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
      registry:2

    Комплексний приклад роботи з реєстрами

    Розглянемо сценарій розробки, збірки та розгортання додатку з використанням реєстрів:

    1. Локальна розробка

    # Розробка додатку та Dockerfile
    # ...
    
    # Збірка локального образу
    docker build -t my-web-app:dev .
    
    # Тестування
    docker run -p 8080:80 my-web-app:dev

    2. Відправка в приватний реєстр (для CI/CD)

    # Авторизація в приватному реєстрі
    docker login my-private-registry.example.com
    
    # Перейменування образу
    docker tag my-web-app:dev my-private-registry.example.com/project/my-web-app:1.0.0
    
    # Відправка образу
    docker push my-private-registry.example.com/project/my-web-app:1.0.0

    3. Розгортання в продакшн

    # На продакшн-сервері
    docker login my-private-registry.example.com
    
    # Завантаження образу
    docker pull my-private-registry.example.com/project/my-web-app:1.0.0
    
    # Розгортання
    docker run -d --restart unless-stopped -p 80:80 my-private-registry.example.com/project/my-web-app:1.0.0

    Сценарій повного циклу DevOps з Docker

    Розглянемо повний сценарій від розробки до розгортання, використовуючи Docker і GitLab CI/CD:

    1. Підготовка проекту

    # Клонування репозиторію
    git clone https://gitlab.com/myuser/my-web-app.git
    cd my-web-app
    
    # Створення Dockerfile
    cat > Dockerfile << EOF
    FROM nginx:alpine
    COPY ./html /usr/share/nginx/html
    EXPOSE 80
    CMD ["nginx", "-g", "daemon off;"]
    EOF
    
    # Створення простого веб-сайту
    mkdir -p html
    cat > html/index.html << EOF
    <!DOCTYPE html>
    <html>
    <head>
        <title>Docker DevOps Demo</title>
    </head>
    <body>
        <h1>Вітаємо в Docker DevOps Demo!</h1>
        <p>Версія: 1.0.0</p>
    </body>
    </html>
    EOF
    
    # Створення файлу .gitlab-ci.yml для CI/CD
    cat > .gitlab-ci.yml << EOF
    stages:
      - build
      - test
      - deploy
    
    variables:
      DOCKER_REGISTRY: registry.gitlab.com/myuser
      IMAGE_NAME: my-web-app
      IMAGE_TAG: $CI_COMMIT_SHORT_SHA
    
    build:
      stage: build
      image: docker:20.10
      services:
        - docker:20.10-dind
      script:
        - docker build -t $DOCKER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG .
        - docker tag $DOCKER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG $DOCKER_REGISTRY/$IMAGE_NAME:latest
        - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
        - docker push $DOCKER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG
        - docker push $DOCKER_REGISTRY/$IMAGE_NAME:latest
    
    test:
      stage: test
      image: docker:20.10
      services:
        - docker:20.10-dind
      script:
        - docker pull $DOCKER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG
        - docker run -d --name test-container -p 8080:80 $DOCKER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG
        - apk add --no-cache curl
        - sleep 5
        - curl -s http://localhost:8080 | grep "Docker DevOps Demo"
    
    deploy-staging:
      stage: deploy
      image: docker:20.10
      services:
        - docker:20.10-dind
      script:
        - apk add --no-cache openssh-client
        - eval $(ssh-agent -s)
        - echo "$SSH_PRIVATE_KEY" | tr -d '\\r' | ssh-add -
        - mkdir -p ~/.ssh
        - echo -e "Host *\\n\\tStrictHostKeyChecking no\\n\\n" > ~/.ssh/config
        - ssh user@staging-server "docker pull $DOCKER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG && 
                                 docker stop web-app || true && 
                                 docker rm web-app || true && 
                                 docker run -d --name web-app -p 80:80 $DOCKER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG"
      only:
        - master
    EOF
    
    # Додавання файлів та комміт
    git add .
    git commit -m "Initial commit with Docker setup"
    git push

    2. Створення докер-композ файлу для локальної розробки

    # Створення docker-compose.yml
    cat > docker-compose.yml << EOF
    version: '3'
    
    services:
      web:
        build: .
        ports:
          - "8080:80"
        volumes:
          - ./html:/usr/share/nginx/html
    EOF
    
    # Запуск локального середовища
    docker-compose up -d
    
    # Перевірка
    curl http://localhost:8080

    3. Внесення змін та перевірка CI/CD

    # Внесення змін
    cat > html/index.html << EOF
    <!DOCTYPE html>
    <html>
    <head>
        <title>Docker DevOps Demo</title>
    </head>
    <body>
        <h1>Вітаємо в Docker DevOps Demo!</h1>
        <p>Версія: 1.0.1</p>
        <p>Нові зміни в проекті!</p>
    </body>
    </html>
    EOF
    
    # Перевірка локально
    docker-compose restart
    
    # Комміт і пуш змін
    git add html/index.html
    git commit -m "Update version to 1.0.1"
    git push

    Найкращі практики використання Docker

    1. Безпека

    • Використовуйте офіційні образи — вони регулярно оновлюються
    • Сканування вразливостей — використовуйте інструменти на кшталт Trivy, Clair
    • Не запускайте контейнери від імені root — використовуйте користувача без привілеїв
    • Підписування образів — використовуйте Docker Content Trust
    # Приклад запуску контейнера не від root
    docker run -d --user 1000:1000 nginx

    2. Оптимізація образів

    • Багатоетапна збірка — зменшує розмір фінального образу
    • Мінімальні базові образи — використовуйте alpine або slim варіанти
    • Об'єднання шарів — групуйте команди RUN
    • Використання .dockerignore — виключення непотрібних файлів
    # Приклад багатоетапної збірки
    FROM node:14 AS builder
    WORKDIR /app
    COPY package*.json ./
    RUN npm install
    COPY . .
    RUN npm run build
    
    FROM nginx:alpine
    COPY --from=builder /app/build /usr/share/nginx/html

    3. Моніторинг та логування

    • Централізоване логування — використовуйте ELK Stack або Grafana Loki
    • Моніторинг контейнерів — Prometheus, Grafana, cAdvisor
    • Health checks — перевірка стану контейнерів
    # Приклад додавання health check в docker-compose.yml
    services:
      web:
        image: nginx
        healthcheck:
          test: ["CMD", "curl", "-f", "http://localhost"]
          interval: 30s
          timeout: 10s
          retries: 3
          start_period: 40s

    4. CI/CD інтеграція

    • Автоматизована збірка — інтеграція з CI/CD системами
    • Тегування за commit hash — унікальні ідентифікатори образів
    • Сканування коду та образів — частина піпелайну

    5. Продакшн налаштування

    • Обмеження ресурсів — встановлюйте ліміти CPU і пам'яті
    • Restart policies — автоматичний перезапуск при збоях
    • Оркестрація — використовуйте Kubernetes або Docker Swarm
    # Приклад запуску з обмеженням ресурсів
    docker run -d --name api \
      --cpus=0.5 \
      --memory=512m \
      --restart=unless-stopped \
      my-api:1.0

    Висновок

    Docker революціонізував спосіб розробки, доставки та запуску програмного забезпечення. Він вирішує проблему "Працює на моєму комп'ютері", забезпечує ізоляцію, ефективне використання ресурсів та повторюваність середовища.

    Ключові компоненти екосистеми Docker:

    • Dockerfile — інструкції для побудови образів
    • Docker Images — незмінні пакети з кодом та залежностями
    • Docker Containers — запущені екземпляри образів
    • Docker Compose — інструмент для багатоконтейнерних додатків
    • Container Registry — репозиторії для збереження образів

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

    Edited
    snippetfile1.txt 97 B
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Please register or to comment