Содержит инструкции по развертыванию проекта в нескольких контейнерах

Введение

Docker стал одним из самых популярных инструментов для контейнеризации, предоставляя возможность изолирования приложений в лёгкие контейнеры. Это упрощает разработку, тестирование и развертывание. Работа с несколькими проектами в Docker может показаться сложной задачей, особенно для тех, кто только начинает своё знакомство с этой технологией. В этой статье мы подробно рассмотрим, как управлять несколькими проектами в Docker, используя различные подходы и инструменты, чтобы упростить этот процесс.

Работа с несколькими проектами

Работа с несколькими проектами в Docker требует от нас понимания основ Docker и некоторых продвинутых возможностей, таких как docker-compose, сети и управление образами. Давайте разберем основные элементы, которые помогут вам в этой задаче.

Установка и настройка Docker

Первый шаг к работе с Docker — его установка. Убедитесь, что на вашем компьютере установлена последняя версия Docker. Docker доступен для большинства операционных систем, таких как Windows, macOS и различные дистрибутивы Linux.

После установки Docker, можно проверить успешность установки, выполнив команду:

docker --version

Это покажет установленную версию Docker и подтвердит, что все работает корректно.

Dockerfile для каждого проекта

Каждый проект в Docker основывается на Dockerfile. Это текстовый файл, содержащий инструкции по сборке Docker-образа. Один из простейших примеров таков:

# Используем базовый образ Node.js
FROM node:14

# Устанавливаем рабочую директорию
WORKDIR /app

# Копируем package.json и package-lock.json
COPY package*.json ./

# Устанавливаем зависимости
RUN npm install

# Копируем исходный код в контейнер
COPY . .

# Запускаем приложение
CMD ["node", "index.js"]

В этом Dockerfile описывается процесс сборки образа для приложения на Node.js. Он определяет базовый образ, рабочую директорию, устанавливает зависимости и копирует код в контейнер.

Docker Compose для оркестрации

Когда у вас несколько проектов или сервисов, было бы удобно их оркестровать с помощью docker-compose. Этот инструмент позволяет запускать многоконтейнерные приложения. Создайте файл docker-compose.yml, в котором будет описано ваше приложение.

Пример для приложения, состоящего из API и базы данных:

version: '3.8'

services:
  api:
    build: ./api
    ports:
      - "5000:5000"
  
  db:
    image: postgres
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password

Здесь мы используем два сервиса: api, который будет собран из локальной директории, и db, использующий стандартный образ Postgres из Docker Hub. Это упрощает настройку и запуск среды разработки.

Сети и коммуникация между контейнерами

Docker автоматически создает сеть для каждого docker-compose проекта. Это позволяет контейнерам взаимодействовать друг с другом. Например, сервис api может обращаться к базе данных db по её имени, что существенно упрощает настройку.

Общие объемы (Volumes)

Для организации совместного использования данных между контейнерами и персистенции данных часто используются объемы. Volumes позволяют вам сохранять данные за пределами жизненного цикла контейнера.

Пример конфигурации в docker-compose.yml с использованием volume:

services:
  api:
    # ...
    volumes:
      - app-data:/usr/src/app/data

volumes:
  app-data:

Volume app-data хранит данные, которые не потеряются при перезапуске контейнера.

Управление образами и хранение

Когда в работе несколько проектов, важно правильно управлять образами, чтобы они не занимали слишком много места. Часто используемые команды:

  • docker images — показывает все локально сохранённые образы.
  • docker rmi [image_name] — удаляет не используемый образ.

Вы можете также использовать docker prune для автоматической очистки неиспользуемых объектов.

Здесь мы видим, как просто управлять образами, но важно уделять этому внимание, чтобы избежать лишнего использования дискового пространства.

Заключение

Docker предоставляет множество инструментов и возможностей для работы с несколькими проектами одновременно, что делает его мощным инструментом в арсенале современного разработчика. Работая с Dockerfile, docker-compose, сетями и объемами, вы сможете эффективно управлять и развивать свои приложения. Экспериментируйте с настройками и инструментами Docker, чтобы извлечь максимальную выгоду из контейнерной инфраструктуры и улучшить свои рабочие процессы.

В этой статье рассмотрим, как использовать Docker Compose для управления многоконтейнерными приложениями. Разберем, зачем нужен Docker Compose и как он помогает решать задачи разработки, тестирования и развертывания. Узнаем, как создавать и настраивать контейнеры для приложений с помощью файла docker-compose.yml. Расскажем, какие команды будут полезны в работе с контейнерами и как настраивать пользовательские сети для взаимодействия компонентов внутри проекта.

Зачем нужен Docker Compose

Docker Compose — это инструмент управления многоконтейнерными приложениями. Он упрощает разработку, развертывание и тестирование сложных проектов, где используются несколько сервисов. Ими могут быть веб-серверы, базы данных, приложения и другие компоненты.

В отличие от Docker, который работает с отдельными контейнерами, Docker Compose ориентирован на управление несколькими контейнерами одновременно. Он описывает их конфигурацию в одном файле — docker-compose.yml. Это делает его незаменимым инструментом для разработчиков и DevOps-инженеров, которые хотят автоматизировать сборку, запуск и настройку сети между контейнерами.

Сравнивать Docker Compose с Docker корректно, но важно понимать их различия. Docker — это инструмент для создания и управления отдельными контейнерами. Docker Compose же предназначен для работы с группами контейнеров, объединенных в сервисы.

Например, с помощью Docker Compose можно одной командой запустить весь проект, включая веб-сервер, базу данных и приложение, а также настроить сеть между ними.

docker-compose up

Это значительно ускоряет разработку и упрощает управление зависимостями между компонентами. За это Docker Compose и ценят в современных IT-проектах.

Что такое YAML

YAML — это человекочитаемый формат данных, который часто используется для создания конфигурационных файлов, например docker-compose.yml. Формат прост и имеет понятный синтаксис. Это делает его идеальным для описания конфигураций сервисов, сетей, портов и других параметров в Docker Compose. 

В YAML используются отступы для обозначения структуры, что позволяет легко описывать сложные зависимости и настройки. Например, из файла docker-compose.yml можно указать, какие образы использовать, как настроить сеть между контейнерами, какие порты открыть на хосте и как управлять переменными окружения. Благодаря своей гибкости и удобству, YAML стал стандартом для работы с Docker Compose и другими инструментами в сфере разработки и DevOps.

Создание проекта для запуска в Docker Compose

Запуск проекта с использованием Docker Compose предполагает создание и настройку нескольких контейнеров, которые работают вместе. В этом разделе мы рассмотрим, как создать контейнеры для Nginx и PHP, чтобы они могли взаимодействовать друг с другом. Это типичный сценарий для веб-приложений, где Nginx выступает в роли веб-сервера, а PHP обрабатывает backend-логику.

Создание контейнера для Nginx

Nginx — высокопроизводительный веб-сервер, который часто используется для обслуживания статических файлов и проксирования запросов к backend-сервисам. Для создания контейнера с Nginx необходимо:

  1. создать Dockerfile,
  2. настроить конфигурацию Nginx,
  3. описать сервис в docker-compose.yml.

Пример Dockerfile для Nginx:

    FROM nginx:latest
COPY nginx.conf /etc/nginx/nginx.conf
COPY ./html /usr/share/nginx/html

Пример минимальной конфигурации для проксирования запросов к PHP (nginx.conf):

    server {
    listen 80;
    server_name localhost;

    root /var/www/html;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass php:9000;  # Связь с PHP-контейнером
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

Описание сервиса в docker-compose.yml:

    services:
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./html:/var/www/html
    depends_on:
      - php
    networks:
      - app_network

Создание контейнера для PHP

PHP-контейнер будет обрабатывать backend-логику приложения. Для его создания необходимо:

  1. использовать официальный образ PHP с поддержкой FPM (FastCGI Process Manager),
  2. настроить PHP для работы с Nginx,
  3. описать сервис в docker-compose.yml.

Пример Dockerfile для PHP:

    FROM php:8.2-fpm
RUN docker-php-ext-install pdo_mysql

Описание сервиса в docker-compose.yml:

    services:
  php:
    image: php:8.2-fpm
    container_name: php
    volumes:
      - ./php:/var/www/html  # Проброс директории с PHP-кодом
    networks:
      - app_network

Создание файла docker-compose.yml и настройка проекта

Чтобы Nginx мог передавать запросы PHP-FPM, необходимо:

  1. убедиться, что оба контейнера находятся в одной сети (app_network),
  2. указать в конфигурации Nginx правильный адрес PHP-контейнера (в нашем примере это php:9000, где php — имя сервиса в docker-compose.yml).

Итоговый docker-compose.yml:

    version: '3.8'
services:
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/html:/var/www/html
    depends_on:
      - php
    networks:
      - app_network

  php:
    image: php:8.2-fpm
    container_name: php
    volumes:
      - ./php:/var/www/html
    networks:
      - app_network

networks:
  app_network:
    driver: bridge

Создайте файл index.php в директории php/:

    <?php
echo "Hello from PHP!";
?>

Запустите проект командой:

docker-compose up -d

Откройте браузер и перейдите по адресу http://localhost. Вы увидите сообщение «Hello from PHP!». Оно означает успешную работу связки Nginx и PHP.

Пример структуры проекта:

    project/
├── docker-compose.yml
├── nginx/
│   ├── nginx.conf
│   └── html/
├── php/
│   └── index.php

Работа с контейнерами в Docker Compose

Docker Compose предоставляет удобный способ управления контейнерами, начиная от их сборки и запуска, заканчивая остановкой и удалением. 

Сборка контейнеров в Docker Compose

Используйте команду:

docker-compose build

Она позволяет создать образы на основе инструкций, указанных в docker-compose.yml.

Запуск всех сервисов

docker-compose up

Запуск контейнеров в фоновом режиме

Для этой задачи можно добавить в команду флаг -d:

docker-compose up -d

Это особенно полезно для развертывания приложений на сервере.

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

Это делается командой:

docker-compose stop

Она приостанавливает работу всех сервисов, описанных в docker-compose.yml, но сохраняет их состояние.

Остановка и полное удаление контейнеров, сети и тома

Выполните команду:

docker-compose down

Удаление образов

Чтобы удалить образы, необходим дополнительный флаг —rmi all:

docker-compose down --rmi all

Удаление томов

А для удаления томов добавьте флаг —volumes:

docker-compose down --volumes

Выполнение команд внутри запущенного контейнера

Для выполнения команд внутри запущенного контейнера используется команда:

docker-compose exec <service_name> <command>

Здесь <service_name> — это имя сервиса, а <command> — команда, которую нужно выполнить. Например, чтобы открыть терминал в контейнере с PHP, выполните:

docker-compose exec php bash

Зависимости между сервисами

Зависимости между сервисами задаются в docker-compose.yml с помощью опции depends_on. Например, чтобы база данных запускалась перед приложением:

    services:
  app:
    depends_on:
      - db

Для запуска контейнера от имени определенного пользователя, нужно настроить опцию user в конфигурации:

    services:
  app:
    user: "<user_id_or_user_name>:<group_id_or_group_name>"

Проброс папок между хостом и контейнером настраивается через volumes. Например:

    services:
  app:
    volumes:
      - ./app:/var/www/html

Переменные окружения задаются с помощью environment в docker-compose.yml:

    services:
  db:
    environment:
      MYSQL_ROOT_PASSWORD: password

Для просмотра логов конкретного сервиса применяется команда:

docker-compose logs <service_name>

Например, если нужно, чтобы nginx показал логи веб-сервера, нужно запустить команду:

docker-compose logs nginx

Проброс портов настраивается через ports. Например, чтобы связать порт 80 на хосте с портом 8080 в контейнере, выполните:

    services:
  web:
    ports:
      - "80:8080"

Лимиты на использование CPU и памяти задаются через deploy.resources.limits:

    services:
  app:
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

Метки добавляются для удобства управления контейнерами. Например:

    services:
  web:
    labels:
      com.example.description: "Web service"

Docker Compose делает процесс работы с контейнерами простым и эффективным, автоматизируя множество рутинных задач.

Работа с сетью

Создание пользовательских сетей

Docker Compose позволяет создавать пользовательские сети для улучшения управления коммуникацией между контейнерами. По умолчанию Compose создает одну сеть для всех сервисов, но можно определить дополнительные сети в файле docker-compose.yml. Например, чтобы создать сеть с именем app_network, используется следующий код:

    networks:
  app_network:
    driver: bridge

Чтобы подключить к этой сети нужные сервисы, нужно указать их в разделе networks каждого сервиса. Это полезно для сложных проектов, где требуется разделение сетевых ресурсов.

Изоляция сетей

Изоляция сетей позволяет ограничить взаимодействие между контейнерами, что повышает безопасность и упрощает управление. В Docker Compose можно создать несколько сетей и подключить к ним только определенные сервисы. Например, база данных может быть изолирована в отдельной сети, доступной только для backend-сервисов. Это делается через конфигурацию networks в docker-compose.yml:

    services:
  db:
    networks:
      - db_network
  backend:
    networks:
      - db_network
      - app_network

Здесь сервис db изолирован в сети db_network, а backend имеет доступ как к db_network, так и к app_network.

Коммуникация между контейнерами

Docker Compose упрощает коммуникацию между контейнерами, автоматически настраивая DNS-имена для каждого сервиса. Это позволяет обращаться к контейнерам по имени сервиса, указанному в docker-compose.yml. Например, если у вас есть сервис db, вы можете подключиться к нему из другого контейнера, используя имя db как хост. Пример:

    services:
  db:
    image: postgres
  app:
    image: my_app
    environment:
      DB_HOST: db

В этом случае сервис app сможет подключиться к базе данных, используя db как хост. Docker Compose автоматически настроит сеть и DNS, чтобы обеспечить корректную коммуникацию между контейнерами.

Читайте также:

Время на прочтение9 мин

Количество просмотров986K

Автор статьи, перевод которой мы сегодня публикуем, говорит, что она предназначена для тех разработчиков, которые хотят изучить Docker Compose и идут к тому, чтобы создать своё первое клиент-серверное приложение с использованием Docker. Предполагается, что читатель этого материала знаком с основами Docker. Если это не так — можете взглянуть на эту серию материалов, на эту публикацию, где основы Docker рассмотрены вместе с основами Kubernetes, и на эту статью для начинающих.

image

Что такое Docker Compose?

Docker Compose — это инструментальное средство, входящее в состав Docker. Оно предназначено для решения задач, связанных с развёртыванием проектов.

Изучая основы Docker, вы могли столкнуться с созданием простейших приложений, работающих автономно, не зависящих, например, от внешних источников данных или от неких сервисов. На практике же подобные приложения — редкость. Реальные проекты обычно включают в себя целый набор совместно работающих приложений.

Как узнать, нужно ли вам, при развёртывании некоего проекта, воспользоваться Docker Compose? На самом деле — очень просто. Если для обеспечения функционирования этого проекта используется несколько сервисов, то Docker Compose может вам пригодиться. Например, в ситуации, когда создают веб-сайт, которому, для выполнения аутентификации пользователей, нужно подключиться к базе данных. Подобный проект может состоять из двух сервисов — того, что обеспечивает работу сайта, и того, который отвечает за поддержку базы данных.

Технология Docker Compose, если описывать её упрощённо, позволяет, с помощью одной команды, запускать множество сервисов.

Разница между Docker и Docker Compose

Docker применяется для управления отдельными контейнерами (сервисами), из которых состоит приложение.

Docker Compose используется для одновременного управления несколькими контейнерами, входящими в состав приложения. Этот инструмент предлагает те же возможности, что и Docker, но позволяет работать с более сложными приложениями.

Docker (отдельный контейнер) и Docker Compose (несколько контейнеров)

Типичный сценарий использования Docker Compose

Docker Compose — это, в умелых руках, весьма мощный инструмент, позволяющий очень быстро развёртывать приложения, отличающиеся сложной архитектурой. Сейчас мы рассмотрим пример практического использования Docker Compose, разбор которого позволит вам оценить те преимущества, которые даст вам использование Docker Compose.

Представьте себе, что вы являетесь разработчиком некоего веб-проекта. В этот проект входит два веб-сайта. Первый позволяет людям, занимающимся бизнесом, создавать, всего в несколько щелчков мышью, интернет-магазины. Второй нацелен на поддержку клиентов. Эти два сайта взаимодействуют с одной и той же базой данных.

Ваш проект становится всё популярнее, и оказывается, что мощности сервера, на котором он работает, уже недостаточно. В результате вы решаете перевести весь проект на другую машину.

К сожалению, нечто вроде Docker Compose вы не использовали. Поэтому вам придётся переносить и перенастраивать сервисы по одному, надеясь на то, что вы, в процессе этой работы, ничего не забудете.

Если же вы используете Docker Compose, то перенос вашего проекта на новый сервер — это вопрос, который решается выполнением нескольких команд. Для того чтобы завершить перенос проекта на новое место, вам нужно лишь выполнить кое-какие настройки и загрузить на новый сервер резервную копию базы данных.

Разработка клиент-серверного приложения с использованием Docker Compose

Теперь, когда вы знаете о том, для чего мы собираемся использовать Docker Compose, пришло время создать ваше первое клиент-серверное приложение с использованием этого инструмента. А именно, речь идёт о разработке небольшого веб-сайта (сервера) на Python, который умеет выдавать файл с фрагментом текста. Этот файл у сервера запрашивает программа (клиент), тоже написанная на Python. После получения файла с сервера программа выводит текст, хранящийся в нём, на экран.

Обратите внимание на то, что мы рассчитываем на то, что вы владеете основами Docker, и на то, что у вас уже установлена платформа Docker.

Приступим к работе над проектом.

▍1. Создание проекта

Для того чтобы построить ваше первое клиент-серверное приложение, предлагаю начать с создания папки проекта. Она должна содержать следующие файлы и папки:

  • Файл docker-compose.yml. Это файл Docker Compose, который будет содержать инструкции, необходимые для запуска и настройки сервисов.
  • Папка server. Она будет содержать файлы, необходимые для обеспечения работы сервера.
  • Папка client. Здесь будут находиться файлы клиентского приложения.

В результате содержимое главной папки вашего проекта должно выглядеть так:

.
├── client/
├── docker-compose.yml
└── server/
2 directories, 1 file

▍2. Создание сервера

Тут мы, в процессе создания сервера, затронем некоторые базовые вещи, касающиеся Docker.

2a. Создание файлов

Перейдите в папку server и создайте в ней следующие файлы:

  • Файл server.py. В нём будет находиться код сервера.
  • Файл index.html. В этом файле будет находиться фрагмент текста, который должно вывести клиентское приложение.
  • Файл Dockerfile. Это — файл Docker, который будет содержать инструкции, необходимые для создания окружения сервера.

Вот как должно выглядеть содержимое вашей папки server/:

.
├── Dockerfile
├── index.html
└── server.py
0 directories, 3 files

2b. Редактирование Python-файла.

Добавим в файл server.py следующий код:

#!/usr/bin/env python3

# Импорт системных библиотек python.
# Эти библиотеки будут использоваться для создания веб-сервера.
# Вам не нужно устанавливать что-то особенное, эти библиотеки устанавливаются вместе с Python.

import http.server
import socketserver

# Эта переменная нужна для обработки запросов клиента к серверу.

handler = http.server.SimpleHTTPRequestHandler

# Тут мы указываем, что сервер мы хотим запустить на порте 1234. 
# Постарайтесь запомнить эти сведения, так как они нам очень пригодятся в дальнейшем, при работе с docker-compose.

with socketserver.TCPServer(("", 1234), handler) as httpd:

    # Благодаря этой команде сервер будет выполняться постоянно, ожидая запросов от клиента.

   httpd.serve_forever()

Этот код позволяет создать простой веб-сервер. Он будет отдавать клиентам файл index.html, содержимое которого позже будет выводиться на веб-странице.

2c. Редактирование HTML-файла

В файл index.html добавим следующий текст:

Docker-Compose is magic!

Этот текст будет передаваться клиенту.

2d. Редактирование файла Dockerfile

Сейчас мы создадим простой файл Dockerfile, который будет отвечать за организацию среды выполнения для Python-сервера. В качестве основы создаваемого образа воспользуемся официальным образом, предназначенным для выполнения программ, написанных на Python. Вот содержимое Dockerfile:

# На всякий случай напоминаю, что Dockerfile всегда должен начинаться с импорта базового образа.
# Для этого используется ключевое слово 'FROM'.
# Здесь нам нужно импортировать образ python (с DockerHub).
# В результате мы, в качестве имени образа, указываем 'python', а в качестве версии - 'latest'.

FROM python:latest

# Для того чтобы запустить в контейнере код, написанный на Python, нам нужно импортировать файлы 'server.py' и 'index.html'.
# Для того чтобы это сделать, мы используем ключевое слово 'ADD'.
# Первый параметр, 'server.py', представляет собой имя файла, хранящегося на компьютере.
# Второй параметр, '/server/', это путь, по которому нужно разместить указанный файл в образе.
# Здесь мы помещаем файл в папку образа '/server/'.

ADD server.py /server/
ADD index.html /server/

# Здесь мы воспользуемся командой 'WORKDIR', возможно, новой для вас.
# Она позволяет изменить рабочую директорию образа.
# В качестве такой директории, в которой будут выполняться все команды, мы устанавливаем '/server/'.

WORKDIR /server/

Теперь займёмся работой над клиентом.

▍3. Создание клиента

Создавая клиентскую часть нашего проекта, мы попутно вспомним некоторые основы Docker.

3a. Создание файлов

Перейдите в папку вашего проекта client и создайте в ней следующие файлы:

  • Файл client.py. Тут будет находиться код клиента.
  • Файл Dockerfile. Этот файл играет ту же роль, что и аналогичный файл в папке сервера. А именно, он содержит инструкцию, описывающую создание среды для выполнения клиентского кода.

В результате ваша папка client/ на данном этапе работы должна выглядеть так:

.
├── client.py
└── Dockerfile
0 directories, 2 files

3b. Редактирование Python-файла

Добавим в файл client.py следующий код:

#!/usr/bin/env python3

# Импортируем системную библиотеку Python.
# Она используется для загрузки файла 'index.html' с сервера.
# Ничего особенного устанавливать не нужно, эта библиотека устанавливается вместе с Python.

import urllib.request

# Эта переменная содержит запрос к 'http://localhost:1234/'.
# Возможно, сейчас вы задаётесь вопросом о том, что такое 'http://localhost:1234'.
# localhost указывает на то, что программа работает с локальным сервером.
# 1234 - это номер порта, который вам предлагалось запомнить при настройке серверного кода.

fp = urllib.request.urlopen("http://localhost:1234/")

# 'encodedContent' соответствует закодированному ответу сервера ('index.html').
# 'decodedContent' соответствует раскодированному ответу сервера (тут будет то, что мы хотим вывести на экран).

encodedContent = fp.read()
decodedContent = encodedContent.decode("utf8")

# Выводим содержимое файла, полученного с сервера ('index.html').

print(decodedContent)

# Закрываем соединение с сервером.

fp.close()

Благодаря этому коду клиентское приложение может загрузить данные с сервера и вывести их на экран.

3c. Редактирование файла Dockerfile

Как и в случае с сервером, мы создаём для клиента простой Dockerfile, ответственный за формирование среды, в которой будет работать клиентское Python-приложение. Вот код клиентского Dockerfile:

# То же самое, что и в серверном Dockerfile.

FROM python:latest

# Импортируем 'client.py' в папку '/client/'.

ADD client.py /client/

# Устанавливаем в качестве рабочей директории '/client/'.

WORKDIR /client/

▍4. Docker Compose

Как вы могли заметить, мы создали два разных проекта: сервер и клиент. У каждого из них имеется собственный файл Dockerfile. До сих пор всё происходящее не выходит за рамки основ работы с Docker. Теперь же мы приступаем к работе с Docker Compose. Для этого обратимся к файлу docker-compose.yml, расположенному в корневой папке проекта.

Обратите внимание на то, что тут мы не стремимся рассмотреть абсолютно все команды, которые можно использовать в docker-compose.yml. Наша главная цель — разобрать практический пример, дающий вам базовые знания по Docker Compose.

Вот код, который нужно поместить в файл docker-compose.yml:

# Файл docker-compose должен начинаться с тега версии.
# Мы используем "3" так как это - самая свежая версия на момент написания этого кода.

version: "3"

# Следует учитывать, что docker-composes работает с сервисами.
# 1 сервис = 1 контейнер.
# Сервисом может быть клиент, сервер, сервер баз данных...
# Раздел, в котором будут описаны сервисы, начинается с 'services'.

services:

  # Как уже было сказано, мы собираемся создать клиентское и серверное приложения.
  # Это означает, что нам нужно два сервиса.
  # Первый сервис (контейнер): сервер.
  # Назвать его можно так, как нужно разработчику.
  # Понятное название сервиса помогает определить его роль.
  # Здесь мы, для именования соответствующего сервиса, используем ключевое слово 'server'.

  server:
 
    # Ключевое слово "build" позволяет задать
    # путь к файлу Dockerfile, который нужно использовать для создания образа,
    # который позволит запустить сервис.
    # Здесь 'server/' соответствует пути к папке сервера,
    # которая содержит соответствующий Dockerfile.

    build: server/

    # Команда, которую нужно запустить после создания образа.
    # Следующая команда означает запуск "python ./server.py".

    command: python ./server.py

    # Вспомните о том, что в качестве порта в 'server/server.py' указан порт 1234.
    # Если мы хотим обратиться к серверу с нашего компьютера (находясь за пределами контейнера),
    # мы должны организовать перенаправление этого порта на порт компьютера.
    # Сделать это нам поможет ключевое слово 'ports'.
    # При его использовании применяется следующая конструкция: [порт компьютера]:[порт контейнера]
    # В нашем случае нужно использовать порт компьютера 1234 и организовать его связь с портом
    # 1234 контейнера (так как именно на этот порт сервер 
    # ожидает поступления запросов).

    ports:
      - 1234:1234

  # Второй сервис (контейнер): клиент.
  # Этот сервис назван 'client'.

  client:
    # Здесь 'client/ соответствует пути к папке, которая содержит
    # файл Dockerfile для клиентской части системы.

    build: client/

    # Команда, которую нужно запустить после создания образа.
    # Следующая команда означает запуск "python ./client.py".
 
    command: python ./client.py

    # Ключевое слово 'network_mode' используется для описания типа сети.
    # Тут мы указываем то, что контейнер может обращаться к 'localhost' компьютера.

    network_mode: host

    # Ключевое слово 'depends_on' позволяет указывать, должен ли сервис,
    # прежде чем запуститься, ждать, когда будут готовы к работе другие сервисы.
    # Нам нужно, чтобы сервис 'client' дождался бы готовности к работе сервиса 'server'.
 
    depends_on:
      - server

▍5. Сборка проекта

После того, как в docker-compose.yml внесены все необходимые инструкции, проект нужно собрать. Этот шаг нашей работы напоминает использование команды docker build, но соответствующая команда имеет отношение к нескольким сервисам:

$ docker-compose build

▍6. Запуск проекта

Теперь, когда проект собран, пришло время его запустить. Этот шаг нашей работы соответствует шагу, на котором, при работе с отдельными контейнерами, выполняется команда docker run:

$ docker-compose up

После выполнения этой команды в терминале должен появиться текст, загруженный клиентом с сервера: Docker-Compose is magic!.

Как уже было сказано, сервер использует порт компьютера 1234 для обслуживания запросов клиента. Поэтому, если перейти в браузере по адресу http://localhost:1234/, в нём будет отображена страница с текстом Docker-Compose is magic!.

Полезные команды

Рассмотрим некоторые команды, которые могут вам пригодиться при работе с Docker Compose.

Эта команда позволяет останавливать и удалять контейнеры и другие ресурсы, созданные командой docker-compose up:

$ docker-compose down

Эта команда выводит журналы сервисов:

$ docker-compose logs -f [service name]

Например, в нашем проекте её можно использовать в таком виде: $ docker-compose logs -f [service name].

С помощью такой команды можно вывести список контейнеров:

$ docker-compose ps

Данная команда позволяет выполнить команду в выполняющемся контейнере:

$ docker-compose exec [service name] [command]

Например, она может выглядеть так: docker-compose exec server ls.

Такая команда позволяет вывести список образов:

$ docker-compose images

Итоги

Мы рассмотрели основы работы с технологией Docker Compose, знание которых позволит вам пользоваться этой технологией и, при желании, приступить к её более глубокому изучению. Вот репозиторий с кодом проекта, который мы здесь рассматривали.

Уважаемые читатели! Пользуетесь ли вы Docker Compose в своих проектах?

В директории нашего проекта my_project создайте файл docker-compose.yml, в который необходимо добавить следующее содержимое

$ cat docker-compose.yml
web:
 build: ./my_flask_app
 ports:
   - "5000:5000"
 volumes:
   - ./my_flask_app:/app 

Описание содержания docker-compose.yml

web:

Название компонента приложения, управляемого Docker Compose. Каждый компонент запускается в отдельном контейнере или их группе

 build: ./my_flask_app

Обозначение того, что данный компонент будет запускаться из образа, который необходимо собрать. Инструкции по сборке будут искаться в Dockerfile в директории ./my_flask_app относительно docker-compose.yml файла


			 ports:
			   - "5000:5000"
		

Обозначение того, что необходимо выполнить публикацию порта 5000 данного компонента в порт 5000, доступный по внешнему IP-адресу хоста (или виртуальной машины), на котором будет запущено приложение.


			 volumes:
			   - ./my_flask_app:/app
		

Обозначение того, что внутрь контейнера, отвечающего за данный компонент приложения, необходимо подключить Docker диск (Docker Volume). В данном случае в роли Docker диска будет выступать директория ./my_flask_app, которая будет cмонтирована в директорию /app внутрь контейнера. Эта операция выполнена для того, чтобы можно было легко менять Flask приложение и наблюдать изменения обновляя окно браузера, а не выполняя пересборку всего контейнера целиком. Попробуйте изменить вывод функции hello_world в файле ./my_flask_app/app.py, чтобы в этом убедиться.

Если вы еще не остановили запущенный в прошлой статье контейнер, сделайте это, чтобы не возникло конфликта с использованием порта 5000 в процессе запуска нового контейнера, который будет управляться Docker Compose.

Contents

  • 1 Docker и Docker-Compose — Tutorial и подборка видео по темам
    • 1.1 Что такое Docker и зачем он нужен?
      • 1.1.1 Видео — Что такое Docker за 200 секунд
      • 1.1.2 Сущности Docker: docker daemon, container, image, Dockerfile, Docker Registry
    • 1.2 Что такое docker image (образ)
    • 1.3 Что такое docker container (контейнер)
    • 1.4 Управление контейнерами. Схема Lifecycle of Docker Container
    • 1.5 Что такое Docker Hub?
    • 1.6 Как создать свой образ? Что такое Dockerfile?
      • 1.6.1 Пример dockerfile
      • 1.6.2 Команды Dockerfile
      • 1.6.3 Пример dockerfile для приложения flask app python
      • 1.6.4 Видео Tutorials — Dockerfile
    • 1.7 Что такое Docker Volume?
      • 1.7.1 Команды Docker Volume
      • 1.7.2 Подборка видео по Docker Volume
    • 1.8 Как взаимодействовать с контейнером?
    • 1.9 Docker Networking
    • 1.10 Что такое Docker Compose?
    • 1.11 docker-compose.xml
    • 1.12 Дополнительные подборки видео по Docker
  • 2 Примеры создания приложений с помощью Docker или Docker-Compose
      • 2.0.1 Docker + ReactJS tutorial: Development to Production workflow + multi-stage builds + docker compose
  • 3 Краткий экскурс в Linux
    • 3.1 Базовый список команд Linux
    • 3.2 Linux File System/Structure Explained
    • 3.3 Основы Ubuntu Linux: apt-get, bash, командная строка
    • 3.4 Linux command line for beginners
    • 3.5 Права Доступа и владения файлами и директориями
  • 4 Установка Докера на Linux. Install Docker on Ubuntu 20.04
  • 5 Portainer — что это такое?
    • 5.1 Установка Portainer внутри Docker
  • 6 GitHub Actions — CI/CD Pipeline with Docker
  • 7 Использованные источники для подготовки статьи и другие полезные статьи

Что такое Docker и зачем он нужен?

Официальный сайт docker.com.

Docker — это платформа для разработки, развертывания и запуска приложений внутри контейнеров.

Docker – это технология с открытым исходным кодом, которая решает проблемы развертывания и масштабирования путем отделения приложений от зависимостей инфраструктуры. Она решает эти проблемы благодаря применению контейнеров, позволяющих упаковать приложение со всеми его зависимостями, включая структуру каталогов, метаданные, пространство процессов, номера сетевых портов и т. д. Приложение, упакованное в контейнер, запускается одинаково на любых машинах и в любых окружениях. Именно эта особенность сделала технологию Docker особенно интересной и обеспечила ей стремительный взлет.

И еще одно определение докера:

Docker — это инструмент с открытым исходным кодом, который позволяет вам включать и хранить ваш код и его зависимости в удобном пакете, который называется образом. Затем этот образ можно использовать для создания экземпляра вашего приложения (сервиса) — контейнера. Основное различие между контейнерами и виртуальными машинами заключается в том, что контейнеры охватывают только уровень приложения и полагаются на базовое ядро ​​операционной системы, в случае виртуальной машины создается новый экземпляр операционной системы.

Видео — Что такое Docker за 200 секунд

Сущности Docker: docker daemon, container, image, Dockerfile, Docker Registry

В Docker используется архитектура клиент/сервер, в соответствии с которой клиент взаимодействует с демоном Docker, а тот предоставляет все необходимые клиенту услуги.

Рассмотрим компоненты рабочего процесса и инструменты для управления контейнерами и их развертывания, составляющие экосистему Docker:

  • Daemon Docker (Сервер): Выполняется в хост-системе и управляет всеми запущенными контейнерами. Docker Daemon — это сервер Docker, который прослушивает запросы Docker API. Docker Daemon управляет образами, контейнерами, сетями и томами.
  • Docker Container (Контейнер): Автономная виртуальная система, содержащая выполняющийся процесс, все файлы, зависимости, адресное пространство процесса и сетевые порты, необходимые приложению. Так как каждый контейнер имеет свое пространство портов, следует организовать их отображение в фактические порты на уровне Docker;
  • Docker Client (Клиент): Пользовательский интерфейс, или интерфейс командной строки, для взаимодействий с демоном Docker. Клиент Docker — это основной способ взаимодействия с Docker. Когда вы используете интерфейс командной строки (CLI) Docker, вы вводите в терминал команду, которая начинается сdocker. Затем клиент Docker использует API Docker для отправки команды демону Docker.
  • Docker Image (Образ): это шаблон только для чтения, который содержит набор инструкций по созданию контейнера, который может работать на платформе Docker. Он предоставляет удобный способ упаковать приложения и предварительно настроенные серверные среды, которые вы можете использовать для личного использования или публично публиковать с другими пользователями Docker. Также можно воспользоваться командой docker diff, чтобы увидеть различия между двумя образами. Каждый образ состоит из нескольких уровней, или слоев, которые могут совместно использоваться несколькими образами.
  • Реестр Docker: Репозиторий для хранения и распространения образов контейнеров Docker. Пример известного реестра — Docker Hub, куда можно помещать и откуда можно извлекать образы.
  • Dockerfile: Это очень простой текстовый файл, содержащий команды, которые выполняют сборку образов Docker. Посредством этих команд можно устанавливать дополнительные программные компоненты, настраивать переменные окружения, рабочие каталоги и точку входа ENTRYPOINT, а также добавлять новый код;
  • Docker Swarm: По сути своей, это готовый к использованию механизм кластеризации, позволяющий объединить несколько узлов Docker в один большой хост Docker.
  • Docker Compose: Приложения часто состоят из множества компонентов, и соответственно они будут выполняться в нескольких контейнерах. В состав Docker входит инструмент Compose, с помощью которого можно легко запустить приложение в нескольких контейнерах. Вы можете определить окружение для приложения в общем файле Dockerfile и определить перечень служб в файле docker-compose.yml, после чего Docker автоматически будет создавать и запускать необходимые контейнеры, как определено в этих файлах.

Что такое docker image (образ)

Образ Docker — это шаблон только для чтения, который содержит набор инструкций по созданию контейнера, который может работать на платформе Docker. Образ — это главный шаблон, который используется для запуска одинаковых контейнеров. Если выразиться кратко, то docker image — это переносимый формат для одного контейнера.

Образ Docker состоит из набора файлов, которые объединяют воедино все необходимое, например installations, application code, и dependencies, необходимые для настройки полностью работоспособной среды контейнера. Вы можете создать образ Docker одним из двух способов:

  • Интерактивный: запустив контейнер из существующего образа Docker, вручную изменив среду контейнера с помощью серии активных шагов и сохранив полученное состояние как новый образ.

  • Dockerfile: путем создания текстового файла, известного как Dockerfile, который предоставляет спецификации для создания образа Docker.

Dockerfile — это файл с инструкциями о том, как Docker должны строить свой image.

С физической точки зрения docker image состоит из набора слоев, доступных только для чтения (read-only layers). Слои image работают следующим образом:

  • Каждый слой image является результатом одной команды в файле Dockerfile. Образ докера представляет собой сжатый (tar) файл, содержащий серию слоев.
  • Каждый дополнительный слой image включает только набор отличий от предыдущего слоя (попробуйте запустить для docker image команду docker history, которая выведет все его слои и те команды, которые их создало).

Пример Dockerfile:

FROM node:13.12.0alpine

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

Что такое docker container (контейнер)

Docker Container — это исполняемый экземпляр образа. Образ Docker плюс команда docker run image_name создает и запускает контейнер из образа.

Контейнеры предлагают виртуальную среду, в которую упаковываются процесс приложения, метаданные и файловая система, т.е. все, что необходимо приложению для работы. В отличие от виртуальных машин, контейнеры не требуют собственной операционной системы — это всего лишь обертки вокруг процессов UNIX, которые непосредственно взаимодействуют с ядром.

Контейнеры обеспечивают полную изоляцию приложений и процессов, когда одно приложение ничего не знает о существовании других приложений. Но все процессы используют одно и то же ядро операционной системы.

Управление контейнерами. Схема Lifecycle of Docker Container

Образ Docker — это статическая модель, содержащая предустановленное приложение. При запуске этого образа создается контейнер . Образ можно использовать для запуска любого количества контейнеров. На следующей диаграмме показан жизненный цикл контейнера Docker и связанных команд.

Пример схемы docker container lifecycle 1:

Пример схемы docker container lifecycle 2:

Create container

Создайте контейнер, чтобы в дальнейшем запустить его с нужным образом.

docker create name <containername> <imagename>

Run docker container

Запустите контейнер докера с требуемым образом и указанной командой / процессом. Флаг -d используется для запуска контейнера в фоновом режиме.

docker run it d name <containername> <imagename> bash 

Pause container

Используется для приостановки процессов, запущенных внутри контейнера.

docker pause <containerid/name> 

Unpause container

Используется для возобновления процессов внутри контейнера.

docker unpause <containerid/name> 

Start container

Запустите контейнер, если он находится в остановленном состоянии.

docker start <containerid/name> 

Stop container

Остановить контейнер и процессы, запущенные внутри контейнера:

docker stop <containerid/name> 

Чтобы остановить все запущенные контейнеры докеров

docker stop $(docker ps a q)

Restart container

Используется для перезапуска контейнера, а также процессов, работающих внутри контейнера.

docker restart <containerid/name> 

Kill container

Мы можем убить работающий контейнер.

docker kill <containerid/name> 

Destroy container

Лучше уничтожать контейнер, только если он находится в остановленном состоянии, вместо того, чтобы принудительно уничтожать работающий контейнер.

docker rm <containerid/name> 

Чтобы удалить все остановленные контейнеры докеров

docker rm $ (docker ps q f status = exited)

Что такое Docker Hub?

Docker Hub — это облачная служба реестра, которая позволяет загружать образы Docker, созданные другими сообществами. Вы также можете загрузить свои собственные образы, созданные Docker, в Docker Hub.

Как создать свой образ? Что такое Dockerfile?

Что такое Dockerfile?

  • Dockerfile — это текстовый файл конфигурации, написанный с использованием специального синтаксиса.
  • В нем описываются пошаговые инструкции по всем командам, которые необходимо выполнить для сборки образа Docker.
  • Команда docker build обрабатывает этот файл, создавая образ Docker в вашем локальном кэше образов, который затем можно запустить с помощью docker run команды или отправить в постоянный репозиторий образов (push).

Как создать Dockerfile?

Dockerfile создается в любом текстовом редакторе. Далее пишутся инструкции.

Пример dockerfile

Пример dockerfile для NGINX:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

# Каждая инструкция в этом файле генерирует новый слой, который помещается в ваш локальный кеш docker image

# Строки, которым предшествует #, считаются комментариями и игнорируются

# В строке ниже указано, что мы будем основывать наш новый образ на последней официальной версии Ubuntu

FROM ubuntu: latest

# Указываем, кто поддерживает docker image (автор)

LABEL Maintainer = «myname@somecompany.com»

# Обновляем образ до последних пакетов

RUN aptget update && aptget upgrade y

# Устанавливаем NGINX

RUN aptget install nginx y

# Выставить порт 80

EXPOSE 80

# Последний пункт — это команда для запуска NGINX в нашем контейнере

CMD [«nginx», «-g», «daemon off;»]

Команды Dockerfile

ADD — определяет файлы для копирования из файловой системы хоста в контейнер

ADD ./local/config.file /etc/service/config.file

CMD — это команда, которая будет запускаться при запуске контейнера

CMD [nginx, g, daemon off;]

ENTRYPOINT — устанавливает приложение по умолчанию, используемое каждый раз, когда контейнер создается из образа. Если используется вместе с CMD, вы можете удалить приложение и просто определить там аргументы

CMD Hello World!

ENTRYPOINT echo

ENV — установка / изменение переменных среды в контейнерах, созданных из образа

EXPOSE — Определите, какие порты контейнера открывать

FROM — Выберите базовый образ, чтобы построить новый образ поверх

LABEL Maintainer — необязательное поле, чтобы вы могли идентифицировать себя как maintainer этого образа. Это просто ярлык

LABEL maintainer=someone@xyz.xyz

RUN — укажите команды для внесения изменений в ваш образ, а затем контейнеры, запускаемые с этого образа. Это включает в себя обновление пакетов, установку программного обеспечения, добавление пользователей, создание исходной базы данных, настройку сертификатов и т. д. Это команды, которые вы должны запускаться из командной строки для установки и настройки вашего приложения. Это одна из самых важных директив dockerfile

RUN aptget update && aptget upgrade y && aptget install y nginx && rm rf/var/lib/apt/lists/*

USER — Определите пользователя по умолчанию, все команды будут запускаться, как в любом контейнере, созданном из вашего образа. Это может быть либо UID, либо имя пользователя.

VOLUME — создает точку монтирования в контейнере, связывая ее с файловыми системами, доступными хосту Docker. Новые тома заполняются уже существующим содержимым указанного места на image. Особенно уместно упомянуть, что определение томов в Dockerfile может привести к проблемам. Томами следует управлять с помощью команд docker-compose или docker run. Volumes не являются обязательными. Если у вашего приложения нет состояния (и большинство веб-приложений работают так), вам не нужно использовать тома. Volume требуются для баз данных, например, или для сохранения логов приложения.

WORKDIR — Определите рабочий каталог по умолчанию для команды, определенной в инструкциях «ENTRYPOINT» или «CMD».

Пример dockerfile для приложения flask app python

FROM python:3.6.4alpine3.6

ENV FLASK_APP=minitwit

COPY . /app

WORKDIR /app

RUN pip install editable .

RUN flask initdb

EXPOSE 5000

CMD [ «flask», «run», «—host=0.0.0.0» ]

Видео Tutorials — Dockerfile

Video: Dockerfile Tutorial — Docker in Practice

Видео: Docker создаем собственный образ

Видео: Dockerfile. Формат и создание образа контейнера

Что такое Docker Volume?

Контейнеры Docker используются для запуска приложений в изолированной среде. По умолчанию все изменения внутри контейнера теряются при остановке контейнера. Если мы хотим сохранить данные между запусками, могут помочь Docker Volume.

Когда мы запускаем новый контейнер, Docker добавляет слой чтения-записи поверх слоев image, позволяя контейнеру работать как в стандартной файловой системе Linux .

Таким образом, любое изменение файла внутри контейнера создает рабочую копию на уровне чтения-записи. Однако, когда контейнер останавливается или удаляется, этот уровень чтения-записи теряется.

При монтировании привязки (bind mount) используется файловая система хоста, но Docker Volumes встроены в Docker. Данные хранятся где-то в хранилище, подключенном к хосту — часто в локальной файловой системе:

Volumes — это предпочтительный механизм сохранения данных, генерируемых и используемых контейнерами Docker. Volumes часто является лучшим выбором, чем сохранение данных в доступном для записи слое контейнера, поскольку том не увеличивает размер контейнеров, использующих его, и содержимое тома существует вне жизненного цикла данного контейнера.

В docker-compose.ymlvolumes может появляться в двух разных местах:

version: «3.7»

services:

  database:

    # …

    volumes: # Вложенный ключ. Настраивает тома для определенной службы.

volumes: # Ключ верхнего уровня. Объявляет тома, на которые можно ссылаться из нескольких сервисов.

  # …

Команды Docker Volume

Command Description
docker volume create Create a volume
docker volume inspect Display detailed information on one or more volumes
docker volume ls List volumes
docker volume prune Remove all unused local volumes
docker volume rm Remove one or more volumes

Подборка видео по Docker Volume

Docker Volumes explained in 6 minutes

Docker Volumes (Тома) урок 8

Attaching volumes to containers

Как взаимодействовать с контейнером?

Docker не открывает порты по умолчанию, вы должны настроить каждый открытый порт самостоятельно!

Чтобы сопоставить порт на хосте с контейнером, нам нужно использовать флаг -p команды docker run:

docker run p <port_number_on_host>:<port_number_on_container> <image>

или

docker run v <порт_на_хосте>:<порт_в_контейнере> <образ>

Следующая команда запустит контейнер для mlflow и сопоставит порт 7000 этого контейнера с портом 7000 хоста докера:

docker run p 7000:7000 mlflow

Аналогичным образом будет работать контейнер для POSTGRESQL и порта 5432 этого контейнера в порт 5432 от DOCKER хоста:

docker run p 5432:5432 postgresql

Из-за того, что многие контейнеры связаны с одним хостом, когда служба уже запущена на порту на хосте, мы не можем запустить другой контейнер с этим же портом. Следовательно, чтобы запустить другой экземпляр postgresql на хосте, мы должны выбрать порт, который не используется.

docker run p 1234:5432 postgresql

Открытие всех портов Docker, как правило, не является хорошей идеей, поскольку по умолчанию все порты закрыты.

Чтобы открыть только один порт, выполните следующую строку:

docker container run p 8080:80 d nginx

Порт 80 контейнера Nginx доступен для внешнего мира через порт хоста 8080.

По умолчанию Docker предоставляет порты контейнера IP-адресу 0.0.0.0 (это соответствует любому IP-адресу в системе). Вы также можете указать Docker, какой IP-адрес нужно привязать. Это может быть 127.0.0.1 или другой IP-адрес.

Чтобы привязать порт 80 контейнера Docker к порту 8000 хост-системы и IP-адресу 127.0.0.1 (он же localhost), просто выполните следующую команду:

docker run d p 127.0.0.1:8000:80 nginx

Docker Networking

Docker Networking позволяет соединять контейнеры Docker вместе. Подключенные контейнеры Docker могут находиться на одном или нескольких хостах.

Docker Networking

Docker Networking Tutorial

Что такое Docker Compose?

Docker Compose — это инструмент, который упрощает запуск приложений, состоящих из нескольких контейнеров.

Docker Compose позволяет записывать команды в docker-compose.yml файл для повторного использования. Интерфейс командной строки Docker Compose (cli) упрощает взаимодействие с вашим многоконтейнерным приложением. Docker Compose поставляется бесплатно с установленным вами Docker.

Схема работы Docker-Compose:

Docker-Compose in 12 Minutes

docker-compose.xml

docker-compose.yml — это файл Docker-Compose, который содежит инструкции, используемые для запуска и настройки сервисов (отдельных контейнеров нашего многоконтейнерного приложения).

Структура файла docker-compose.xml (источник — Руководство по Docker Compose для начинающих):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

# Файл docker-compose должен начинаться с тега версии.

# Мы используем «3» так как это — самая свежая версия на момент написания этого кода.

version: «3»

# Следует учитывать, что docker-composes работает с сервисами.

# 1 сервис = 1 контейнер.

# Сервисом может быть клиент, сервер, сервер баз данных…

# Раздел, в котором будут описаны сервисы, начинается с ‘services’.

services:

  # Как уже было сказано, мы собираемся создать клиентское и серверное приложения.

  # Это означает, что нам нужно два сервиса.

  # Первый сервис (контейнер): сервер.

  # Назвать его можно так, как нужно разработчику.

  # Понятное название сервиса помогает определить его роль.

  # Здесь мы, для именования соответствующего сервиса, используем ключевое слово ‘server’.

  server:

    # Ключевое слово «build» позволяет задать

    # путь к файлу Dockerfile, который нужно использовать для создания образа,

    # который позволит запустить сервис.

    # Здесь ‘server/’ соответствует пути к папке сервера,

    # которая содержит соответствующий Dockerfile.

    build: server/

    # Команда, которую нужно запустить после создания образа.

    # Следующая команда означает запуск «python ./server.py».

    command: python ./server.py

    # Вспомните о том, что в качестве порта в ‘server/server.py’ указан порт 1234.

    # Если мы хотим обратиться к серверу с нашего компьютера (находясь за пределами контейнера),

    # мы должны организовать перенаправление этого порта на порт компьютера.

    # Сделать это нам поможет ключевое слово ‘ports’.

    # При его использовании применяется следующая конструкция: [порт компьютера]:[порт контейнера]

    # В нашем случае нужно использовать порт компьютера 1234 и организовать его связь с портом

    # 1234 контейнера (так как именно на этот порт сервер

    # ожидает поступления запросов).

    ports:

       1234:1234

  # Второй сервис (контейнер): клиент.

  # Этот сервис назван ‘client’.

  client:

    # Здесь ‘client/ соответствует пути к папке, которая содержит

    # файл Dockerfile для клиентской части системы.

    build: client/

    # Команда, которую нужно запустить после создания образа.

    # Следующая команда означает запуск «python ./client.py».

    command: python ./client.py

    # Ключевое слово ‘network_mode’ используется для описания типа сети.

    # Тут мы указываем то, что контейнер может обращаться к ‘localhost’ компьютера.

    network_mode: host

    # Ключевое слово ‘depends_on’ позволяет указывать, должен ли сервис,

    # прежде чем запуститься, ждать, когда будут готовы к работе другие сервисы.

    # Нам нужно, чтобы сервис ‘client’ дождался бы готовности к работе сервиса ‘server’.

    depends_on:

       server

Пример сложного файла docker-compose.xml:

Если хотите реально разобраться в docker — очень рекомендую курс Docker и Docker Compose — Деплой проекта с нуля

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

version: ‘3’

services:

  frontend:

    build:

      dockerfile: Dockerfile.prod

      context: ./frontend

    container_name: dockerfrontend

    restart: unlessstopped

    command: serve s build l 3000

    networks:

       dockernetwork

  api:

    build: ./api

    container_name: dockerapi

    command: npm run start

    restart: unlessstopped

    environment:

       PORT=3001

       MONGO_URL=mongodb://api_db:27017/api

       AUTH_API_URL=http://auth:3002/api

    depends_on:

       api_db

    networks:

       dockernetwork

  auth:

    build: ./auth

    container_name: dockerauth

    command: npm run start

    restart: unlessstopped

    environment:

       PORT=3002

       MONGO_URL=mongodb://auth_db:27017/auth

       API_URL=http://api:3001/api

    depends_on:

       auth_db

    networks:

       dockernetwork

  api_db:

    image: mongo:latest

    container_name: dockerapidb

    volumes:

       mongodb_api:/data/db

    networks:

       dockernetwork

  auth_db:

    image: mongo:latest

    container_name: dockerauthdb

    volumes:

       mongodb_auth:/data/db

    networks:

       dockernetwork

  nginx:

    image: nginx:stablealpine

    container_name: dockernginx

    ports:

       «80:80»

    volumes:

       ./nginx/nginx.conf.prod:/etc/nginx/conf.d/nginx.conf

    depends_on:

       frontend

       api

       auth

    networks:

       dockernetwork

volumes:

  mongodb_api:

  mongodb_auth:

networks:

  dockernetwork:

    driver: bridge

Дополнительные подборки видео по Docker

Что такое Docker? Вечерняя школа Слёрма по Kubernetes.

Основы Docker. Большой практический выпуск

Docker Tutorial for Beginners [FULL COURSE in 3 Hours]

Docker-compose что это?

Примеры создания приложений с помощью Docker или Docker-Compose

Docker + ReactJS tutorial: Development to Production workflow + multi-stage builds + docker compose

Краткий экскурс в Linux

Базовый список команд Linux

1. Команда help
Запомнить все возможные параметры, которые можно использовать для команды, невозможно. Если вы не использовали команду ранее или в течение длительного времени, у вас есть возможность изучить возможные варианты, которые можно передать. Большинство команд поддерживают передачу справки в качестве опции и отображают небольшое сообщение о том, как использовать команду.

<command_name> help

Чтобы получить всю возможную помощь, есть команда man. Страница руководства (сокращенно man) — это документ, который иллюстрирует, что делает команда, возможные параметры, примеры использования и т. Д. Это вся помощь, которую вы можете получить для команды

man <command_name>

2. pwd: pwd печатает имя текущего рабочего каталога. Когда вы открываете терминал, вы попадаете в домашний каталог пользователя, под которым вы вошли в систему. pwdпечатает абсолютный путь. Он начинается с /корневого каталога файловой системы Linux.

3. ls: ls распечатывает все файлы, которые присутствуют в каталоге, в котором вы находитесь. Вы можете получить дополнительную информацию о файлах, а также увидеть скрытые файлы с помощью этой -al опции.

4. cd: cd означает смену каталога. Если вы хотите перейти в другой каталог, используйте эту команду. При использовании без аргументов cd приведет вас в ваш домашний каталог. Вы можете передать абсолютный или относительный путь команде cd. Также обратите внимание, что это . представляет текущий каталог и .. родительский каталог.

# takes you to your home directory (comment)

cd

# To navigate to the parent directory

cd ../

# To change to previous working directory

cd ~

5. mv: mv (расширяется при перемещении) используется для перемещения файлов / каталогов из location1 в location2. Его также можно использовать для переименования файла.

# Renaming file a.txt to b.txt

mv a.txt b.txt

# move file from directory test in your current directory to tmp

mv test/test.txt /tmp/test.txt

# move multiple files in your current directory to /tmp

mv a.txt b.txt c.txt /tmp

# move file from a dir A to dir B by specifying the absolute paths

mv /var/log/test.log /tmp/test.log

6. cp: скопируйте файлы из location1 в location2. Каталоги можно копировать с помощью -R опции.

# copy file from your home to directory to another location

cp test.txt /tmp/bckup

# copy contents of directories recursively

cp R test_dir /tmp/bckup

7. rm: rm (расширяется как remove) используется для удаления файла или каталога. При удалении файла нет отмены. Так что будьте осторожны, когда хотите что-то удалить

# rm a file in a location

rm /home/test_user/test.txt

# rm a directory that is empty

rm r <location_of_dir>

# rm a directory with contents in it

rm rf <location_of_dir>

8. mkdir: mkdir (расширенный как каталог make) используется для создания нового каталога в определенном месте.

# create a directory

mkdir test_dir

# create intermediate directory (test_directory) when creating a directory (test_directory_child)

mkdir p /home/test_user/test_directory/test_directory_child

9. rmdir: удалить каталог. Это альтернативная команда дляrm -rf

# delete a directory test_directory_child

rmdir /home/test_user/test_directory/test_directory_child

# Delete the intermediate directories in the path. It only works if # the intermediate directories don’t contain any other child

# directories other than the one specified

rmdir p test_dir/test_dir_child/test_dir_child2

10. cat: распечатывает содержимое файлов на терминале и возвращает обратно в командную строку. Существуют различные редакторы, которые вы можете использовать для просмотра содержимого файла (например, vim, nano и т. Д.), Но эта команда выводит содержимое в STDOUT (стандартный вывод).

# Print contents of a file.

cat test.sh

11. touch: Изменить file timestamps. Обновляет отметки времени в существующих файлах или создает файлы с текущей отметкой времени, если она не существует.

# Assuming file1.txt doesn’t exist, it creates a new file

touch file1.txt

12. sudo: Сокращение от SuperUser Do , эта команда помогает вам выполнять задачи, требующие административных разрешений. Однако не рекомендуется использовать эту команду случайным образом без причины, потому что любая ошибка, сделанная пользователем root, необратима.

# Read the contents of syslog

sudo cat /var/log/syslog

13. find: эта команда ищет в иерархии папок файл или каталог, соответствующий указанному имени или шаблону. Он выполняет рекурсивный поиск во всех каталогах вниз по дереву.

# find a file with name test.txt in a folder

find /home/test_user name test.txt

# find file of specific pattern recursively

find . type f name «*.sh» R

# find and remove multiple files following a same pattern

find . type f name «*.py» exec rm f {}

14.grep: эта команда печатает все строки в файле, соответствующие определенному шаблону.

# recursively grep for a pattern in a directory tree

grep r search_field /etc/

# search two different words

egrep w ‘x|y’ /home/test_user/*

15.df: Эта команда сообщает об использовании дискового пространства файловой системы.

# lists all the file system, use -a option in human readable format i.e., power of 1024

df ah

16. du: оценка использования файлового пространства. Он имеет различные параметры для отображения вывода в желаемом формате.

# Display disk usage of all files and directories in the current directory

du ah

# sum of sizes of files and directories in the directory specified

du sh /home/test_user

17. uname: Распечатать системную информацию. Есть несколько вариантов, которые можно передать, если вам нужна конкретная информация о системе, такая как версия ядра, тип процессора, аппаратная платформа и т. Д.

# Prints all the information about the system

uname a

18. lsblk: lsblk (Expanded as list block devices) используется для отображения всех блочных устройств в виде дерева. Он также предоставляет информацию о разделах, имеющихся на блочном устройстве.

NAME    MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT

sda       8:0    0  55.9G  0 disk

└─sda1    8:2    0  55.9G  0 part  /

sdb       8:16   0 111.8G  0 disk

└─sdb1    8:17   0 111.8G  0 part

19. hostname: распечатать / установить имя хоста машины. Только суперпользователь может обновить имя хоста

# print hostname of system

hostname

# set hostname

hostname set name <host_name>

20. tail: отображает последнюю часть файлов. По умолчанию, если файл передан, он печатает последние 10 строк

# output appended data as the file grows;

tail f /var/log/syslog

Linux File System/Structure Explained

Основы Ubuntu Linux: apt-get, bash, командная строка

Linux command line for beginners

Права Доступа и владения файлами и директориями

Установка Докера на Linux. Install Docker on Ubuntu 20.04

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

# Обновляем существующий список пакето

sudo apt update

# Далее устанавливаем пакеты, которые позволят apt использовать пакеты через HTTPS:

sudo apt install apttransporthttps cacertificates curl softwarepropertiescommon

# Далее добавим ключ GPG для официального репозитория Docker

curl fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add —

# Добавляем ремозиторий докер в источники apt

sudo addaptrepository «deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable»

# Обновляем базу данных пакетов и добавим в нее пакеты Docker из недавно добавленного репозитория

sudo apt update

# Далее проверим, что установка будет выполняться из репозитория Docker, а не из репозитория Ubuntu по умолчанию

aptcache policy dockerce

# Мы должны получить следующий ответ (номер версии Docker может отличаться):

# root@apache1superset:~# apt-cache policy docker-ce

# docker-ce:

#   Installed: (none)

#   Candidate: 5:20.10.6~3-0~ubuntu-focal

#   Version table:

#      5:20.10.6~3-0~ubuntu-focal 500

#         500 https://download.docker.com/linux/ubuntu focal/stable amd64 Packages

#      5:20.10.5~3-0~ubuntu-focal 500

#         500 https://download.docker.com/linux/ubuntu focal/stable amd64 Packages

#      5:20.10.4~3-0~ubuntu-focal 500

#         500 https://download.docker.com/linux/ubuntu focal/stable amd64 Packages

#      5:20.10.3~3-0~ubuntu-focal 500

# …

# Далее устанавливаем докер командой (на доп.вопрос отвечаем «yes»)

sudo apt install dockerce

# Docker будет автоматически установлен, также запустится демон-процесс и будет активирован запуск при загрузке.

# Проверить статус докера можно командой (что он running/active):

sudo systemctl status docker

# Загружаем текущую стабильную версию Docker Compose

sudo curl L «https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-$(uname -s)-$(uname -m)» o /usr/local/bin/dockercompose

# Применяем разрешения для исполняемого файла к двоичному файлу

sudo chmod +x /usr/local/bin/dockercompose

# Чтобы протестировать docker-compose (установилась версия или нет), запустим команду

dockercompose version

Portainer — что это такое?

Portainer — это легкий пользовательский интерфейс управления, который позволяет легко управлять различными средами Docker и docker-containers. С помощью Portainer вы сможете в несколько кликов запустить на вашем сервере готовые контейнеры с популярным ПО и связать их между собой.

Описание с Github: Making Docker and Kubernetes management easy. На момент написания статьи 18.7k stars

Этот мощный набор инструментов с открытым исходным кодом, насчитывающий более полумиллиона постоянных пользователей, позволяет легко создавать и управлять контейнерами в Docker, Swarm, Kubernetes и Azure ACI.

По умолчанию мы управляем Docker через командную строку. Portainer предоставляет отличный и очень информативный пользовательский интерфейс для управления всеми аспектами Docker. Это диаграммы и информационные панели, которые предоставляют диаграммы использования ресурсов контейнера в реальном времени. Запуск и управление контейнерами и стеками можно выполнить несколькими щелчками мыши.

После установки portainer и захода внутрь вы видете первое окно настройки. У меня докер развернут локально, поэтому я подключаюсь через пункт local, нажимаю connect и попадаю в админку.

Домашняя страница админки выглядит следующим образом. Экземпляры Docker, о которых знает Portainer, отображаются в центральной части экрана.

Щелкните экземпляр Local Docker, чтобы увидеть панель мониторинга (Dashboard), на которой отображается общий обзор того, что в настоящее время выполняется в Docker.

Здесь нам открывается вся суть инструмента:

  • Можно создать в несколько кликов из шаблонов приложения в докере

  • Можно управлять сетью, контейнерами.
  • Также можно создавать и настраивать Volumes:

Portainer — отличный инструмент, который можно использовать для управления контейнерами Docker, службами Swarm и другими ресурсами с помощью простого и интуитивно понятного пользовательского веб-интерфейса. Portainer предоставляет несколько бесплатных функций и платных плагинов, которые могут улучшить взаимодействие с пользователем при управлении кластерами Docker.

Установка Portainer внутри Docker

#portainer install

sudo docker volume create portainer_data

docker run d p 8000:8000 p 9443:9443 name portainer \

    restart=always \

    v /var/run/docker.sock:/var/run/docker.sock \

    v portainer_data:/data \

    portainer/portainerce:2.9.3

Далее нужно перейти по ссылке https://68.133.234.42:9443/ (замените 68.133.234.42 на ваш адрес).

GitHub Actions — CI/CD Pipeline with Docker

Использованные источники для подготовки статьи и другие полезные статьи

  • https://medium.com/@BeNitinAgarwal/lifecycle-of-docker-container-d2da9f85959
  • Микросервисы и контейнеры Docker. Парминдер Сингх Кочер. Addison-Wesley. ДМК
  • Learn Enough Docker to be Useful
  • Building Docker Images with Dockerfiles
  • [Docker] Основы Docker: Dockerfile и docker-compose.yml
  • 20 Basic Linux Commands for Beginners!

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Реорганизация путем присоединения бюджетных учреждений пошаговая инструкция
  • Клареол гель эксфолиант гель инструкция
  • Артонео инструкция по применению
  • Перегон спирта сырца с дефлегматором пошаговая инструкция
  • Hiwatch ds t101 инструкция