rshaibakov
@rshaibakov
Web-разработчик

Как должен выглядеть процесс работы с Docker?

После длительных и постоянных мучений в ручном развертывании приложений на сервера для тестов и продакшена, у меня на работе появилось желание в автоматизации этого процесса.
Я обычный разработчик и с DevOps связан косвенно. Опыта в этом немного, а отдельного специалиста у нас для этого нет. Поэтому приходиться брать все в свои руки.
Сейчас у нас есть несколько приватных проектов, состоящие из бэкенда и фронтенда. По масштабу проекты не большие. Бэкенд создан на стеке NodeJS + MongoDB + ElasticSearch + Redis.

Что бы автоматизировать процесс развертывания, начал изучать Docker. Но столкнулся с некоторым непониманием как все должно работать. В основном все материалы в сети отвечают на вопрос: Что такое Docker? И лишь малая часть отвечает на вопрос: Как с ним работать? И даже в них все процессы описываются поверхностно.

Я разобрался с Docker клиентом и поднял docker-machine. Понял как устанавливать образы с Docker Hub и запускать контейнеры. А дальше все... Тупик.
Возникло много вопросов, что делать дальше?
Как мне создать свой контейнер состоящий из образов NodeJs, MongoDB, ElasticSearch, Redis?
Где это все хранить?
Как мне расшарить папки проектов для Docker?
Как мне это интегрировать с CI и CD?
Я запутался. Возникают мысли, а нужно ли мне это? Может все таки по старинке деплоить через FTP?

В общем прошу помощи разобраться в том, как должен быть построен процесс развертывания проектов на Docker?
Или поделиться материалами, где на практике показано что и как нужно делать.
  • Вопрос задан
  • 11090 просмотров
Решения вопроса 3
@paldraken
Попробую описать простыми словами без серьезной терминологии (Devops'ы не бейте ногами).

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

Например у нас такая структура. Я использую php но для nodejs может быть похоже.
project
   - scr/   #Код проета под контролем версий в git
        - Dockerfile
        - phpfile1.php
        - phpfile2.php
        - etc.php
   - db_data/ #папка где будут сохранятся база данных. (иначе каждый запуск контейнера будет ее обнулять)
   - docker-compose.yml
   - site.conf   #конфиг для виртуального хоста nginx
   - nginx.conf #конфиг nginx


Настраивается взаимодействие в специальном файле.
docker-compose.yml
version: '2'
services:
  nginx:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - ../src/:/app
      - ./site.conf:/etc/nginx/conf.d/site.conf
      - ./nginx.conf:/etc/nginx/nginx.conf
    links:
      - php
  db:
    image: mysql:5.7
    volumes:
      - ./db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: 123
      MYSQL_DATABASE: changeme
      MYSQL_USER: changeme
      MYSQL_PASSWORD: 123
    ports:
      - "33306:3306"
  php:
    build: ../src
    volumes:
      - ../src:/app
    depends_on:
      - db
    environment:
      PHP_DB_HOST: db:3306
      PHP_DB_USER: changeme
      PHP_DB_PASSWORD: 123


Тут я использую контейнер nginx и mysql из DockerHub и свой контейнер для php описанный в
src/Dockerfile
FROM php:fpm

RUN apt-get update && \
  apt-get install -y \
    openssl \
    git \
    curl \
    unzip

RUN docker-php-ext-install pdo pdo_mysql

ADD . /app
WORKDIR /app


Теперь использовав docker-compose up мы удобно запустим все контейнеры с нужной конфигурацией.
Взаимодействие между контейнерами будет происходить по алиасам
например из php соединение с БД происходит так:

db.php
return [
    'class' => 'yii\db\Connection',
    'dsn' => "mysql:host=db:3306;dbname=donor", // db:3306 - это services имя контейнера с mysql в docker-compose.yml 
    'username' => getenv('PHP_DB_USER'), // это переменные окружения для контейнера тоже из docker-compose.yml
    'password' => getenv('PHP_DB_PASSWORD'),
    'charset' => 'utf8',
];



Код прокидываем в 2 контейнера php и nginx (раздел volumes). То есть внутри контейнера создается директория /app которая ссылается на директорию на хост машине. Для разработки очень удобно, вы изменяете код и сразу можно обновлять страницу.

На продакшен я обновляю код через git из репозитория и перезапускаю контейнеры (если надо).

ps. Это один из самых простых способов, разумеется существуют более "взрослые" и "правильные" методы. Но надеюсь мое описание позволит вам сдвинутся с мертвой точки в изучении докера.
Ответ написан
vyachin
@vyachin
Ищу работу
как я понял по ответам тут собрались адепты докера. В этой церкви последователь должен появиться атеист. Только сегодня был большой срач насчет какие проблемы можно получить при переходе на докер https://habrahabr.ru/post/332450/ очень советую почитать.

Теперь к вашему вопросу. Докер НЕЛЬЗЯ использовать для персистентный образов. Т.к. если его правильно готовить никакой уверенности нет на какой ноде будет запускаться ваш контейнер физический. Т.е. все что пишет в память или на диск нельзя оборачивать в докер контейнер. Потом есть системы оркестрации, которые ваш контейнер могут с одной ноды на другую перебросить, что вы думаете будет с памятью контейнера - правильно, она очистится.

Тут мне могут возразить что у нас все работает на "отлично" - это вы господа с проблемами не сталкивались. Читаем статью по ссылке выше и начинаем готовиться.

Давайте разберем ваш стек и посмотрим что можно упаковать в докер контейнер.
- NodeJS - не знаю как это у вас работает, если нет состояния - то можно
- MongoDB - база, пишет в файлы, однозначно нельзя
- ElasticSearch - этого зверя точно нельзя он и в память и на диск пишет
- Redis - пишет в память, точно нельзя

И что в итоге вы хотите обернуть в контейнер? И зачем вам докер? Чтоб mongodb была запущена от имени root? При этом мы помним о проблемах с безопасностью самой mongodb. Или elasticsearch завернуть в докер, он физический сервер способен утилизировать на 100% по памяти, пропускной способности дисковой подсистемы и 100% процессорного времени, а вы ему хотите еще один уровень абстракции в лице докера? ))

Одно дело на компьютере разработчика использовать docker-composer и совсем другое дело в продакшене.
Ответ написан
amelihovv
@amelihovv
Фулстек веб разработчик
Как мне создать свой контейнер состоящий из образов NodeJs, MongoDB, ElasticSearch, Redis?

Используйте docker-compose. Вот посмотрите пример https://docs.docker.com/compose/wordpress/#bring-u...
Где это все хранить?

Хранить можно в облаках, но за это нужно платить. Проще таскать с собой docker-compose.yml, и на тестовых серверах собирать.
Как мне расшарить папки проектов для Docker?

Для этого существуют volumes.
volumes:
       - /home/user/Projects/folder1:/var/www/html

Теперь папка folder1 на вашем компьютере доступна в контейнере по пути /var/www/html.
Как мне это интегрировать с CI и CD?

Да все просто. Качаете gitом ваш проект, собираете контейнеры на ваших тестовых серверах и вперед. Можете jenkins еще поставить, он бесплатный. Вот тут есть видосы, как это сделать https://serversforhackers.com/series/jenkins
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
@tupen
Для продакшена удобнее готовое решение, например, легкий вариант (с поддержкой многосерверности) это Flynn.io.
Или Dokku для одного сервера.

А для девелопероского окружения не Докер, а Вагрант.

Идея Докера, что контейнер, нужный вам создается КАЖДЫЙ РАЗ ЗАНОВО для очередной версии вашего ПО.
Это факт частенько упускают из виду, пытаясь создать Докер-контейнер навечно.

CI/CD работает так:

Пушите код в Git,
а, к примеру, Gitlab запускает по гит-хукам воркеры для тестирования.
Воркеры создают новые контейнера на основании одного и того же файла описания Докера Dockerfile (каждый раз заново - для "чистоты эксперимента", то есть для стабильности отладки).
Если тесты проходят удачно, то тот же самый контейнер отправляется в DockerRegistry продакшн-системы,
откуда его забирает система оркестрации/управления кластером (тот же Flynn).

Как вводную по разработке архитектуры вашей системы под контейнерами рекомендую прочитать этот кратенький текст:
https://12factor.net/ru/

Какие СУБД в Докер, перекреститесь...
https://habrahabr.ru/post/332450/#comment_10299122

Да и вообще подумайте нужен ли вам этот гемор:
soar.name/ru/pro/half-a-year-with-docker-swarm-mod...
Польза очевидно большая.
Но Докер - не серебряная пуля.
Ответ написан
Комментировать
copyhold
@copyhold
По моему скромному мнению...
не должно быть одного контейнера который содержит все - и базу и ноде и еластик. Это должны быть отдельные контейнеры, которые соединяются через расшаренные свои адреса и порты.
Поскольку контейнеров несколько , и управлять этим сложно , применять Docker compose, который как раз и описывает это все хозяйство.
Там же описывать внешние папки монтируемые к контейнеру. Или есть еще какие то Docker Storage ( не пробовал )
То есть , код всё равно придётся заливать на сервер и после растартовать контейнер/ы.
Ответ написан
daager
@daager
Тут очень много ответов, в том числе и про Docker compose(инструмент для определения и запуска много-контейнерных приложений.)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы