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?
Или поделиться материалами, где на практике показано что и как нужно делать.
  • Вопрос задан
  • 4622 просмотра
Решения вопроса 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
    Ищу работу
    как я понял по ответам тут собрались адепты докера. В этой церкви последователь должен появиться атеист. Только сегодня был большой срач насчет какие проблемы можно получить при переходе на докер 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
    Ответ написан
Пригласить эксперта
Ответы на вопрос 4
  • @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...
    Польза очевидно большая.
    Но Докер - не серебряная пуля.
    Ответ написан
  • Как мне создать свой контейнер состоящий из образов NodeJs, MongoDB, ElasticSearch, Redis?

    Docker спроектирован так, что каждый процесс должен быть развёрнут в отдельном контейнере. Таким образом, для бэкенда вам потребуется создать образ на базе NodeJS. Проще всего создавать образы через Dockerfile. Первой инструкцией в нём будет идти FROM, указывающая, какой образ взять базовым. Для ноды 8 можно взять node:8-alpine из официального репозитория. Alpine Linux - микродистрибутив, не содержит ничего лишнего, поэтому очень удобен.

    Таким образом, минимальный Dockerfile будет примерно таким:
    FROM node:8-alpine
    MAINTAINER yourcompany
    ADD . . # копирует все файлы из рабочей директории проекта в рабочую директорию контейнера за исключением описанных в .dockerignore
    # ADD (в отличие от COPY) также умеет автоматически распаковывать архивы и скачивать файлы из интернета
    CMD ["node", "./server.js"] # команда, которая выполнится при запуске контейнера; можно не указывать и передавать команду вручную


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

    Где это все хранить?

    Есть официальный репозиторий hub.docker.io. Разумеется, приватное размещение образов там платное. Можно поднять свой репозиторий на своём сервере.

    Как мне расшарить папки проектов для Docker?

    Не совсем понял, что именно вы хотите. В докере есть монтирование volume, но, мне кажется, это не то, что вам в данном случае нужно.

    Как мне это интегрировать с CI и CD?

    В простейшем случае CI-сервер может скачать проект из Git, установить зависимости, прогнать автотесты, затем запустить `docker build`, а после сборки - `docker push`. Лучше всего при этом взять версию приложения из package.json, чтобы затем указать её как tag у имени пакета. Полное имя образа тогда будет что-то вроде `docker.yourcompany.com/yourapp:1.2.3`, где `docker.yourcompany.com` - доменное имя вашего репозитория. docker push использует его, чтобы понять, куда ему загружать образ. Дальнейшее развёртывание зависит от того, как вы оркестрируете свои контейнеры. У нас для этого CI командует Mesos / Marathon, чтобы они загрузили новую версию.

    Это очень вкратце. Задавайте вопросы :)
    Ответ написан
  • copyhold
    @copyhold
    По моему скромному мнению...
    не должно быть одного контейнера который содержит все - и базу и ноде и еластик. Это должны быть отдельные контейнеры, которые соединяются через расшаренные свои адреса и порты.
    Поскольку контейнеров несколько , и управлять этим сложно , применять Docker compose, который как раз и описывает это все хозяйство.
    Там же описывать внешние папки монтируемые к контейнеру. Или есть еще какие то Docker Storage ( не пробовал )
    То есть , код всё равно придётся заливать на сервер и после растартовать контейнер/ы.
    Ответ написан
Ваш ответ на вопрос

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

Войти через TM ID
Похожие вопросы
Вакансии с Моего Круга Все вакансии
Заказы с Фрилансим Все заказы