• Как решаете проблему отсутствия локального smtp сервера в docker?

    Tyranron
    @Tyranron
    Ну, вообщем, Вы всё сами правильно ответили.

    Я использую указанный Вами 2й вариант. В Dockerfile добавляется слой с ssmtp и всё. В качестве ENTRYPOINT небольшой sh-скрипт, который конфигурирует sssmtp при старте контейнера в зависимости от переменных окружения. Все письма пересылаются на внешний центральный Postfix, который уже крутит всю бодягу с DKIM подписями и прочими email-прибамбасами.

    Если Вы посадите этот Postfix внешний на ту же машину, где у Вас крутится и приложение, то вероятность потери такая же, как и в "традиционном" случае без Докера (ведь у Вас на машине Postfix или Exim все равно крутятся).

    Также, как вариант, если есть возможность, можно предусмотреть retries для отправки email в самом коде приложения, если это настолько критично.

    По поводу примерного docker-compose.yml:
    version: '3'
    
    services:
      fpm:
        container_name: fpm
        image: my/app
        depends_on:
          - mailserver
        expose:
          - "9000"     # php-fpm
        environment:
          - SMTP_SERVER=mailserver:587
          - SMTP_USER=testing@moderation.test
          - SMTP_PASSWORD=qweqweqwe
      nginx:
        container_name: nginx
        image: nginx:stable-alpine
        depends_on:
          - fpm
        ports:
          - "80:80"    # http
        volumes:
          - .dev/nginx.vhost.conf:/etc/nginx/conf.d/default.conf:ro
      mailserver:
        container_name: mailserver
        image: tvial/docker-mailserver:v2
        hostname: mail
        domainname: mydomain.test
        ports:
          - "25:25"    # smtp
          - "143:143"  # imap
          - "587:587"  # smtp-auth
          - "993:993"  # imap-secure
        volumes:
          - .dev/mail/accounts.cf:/tmp/docker-mailserver/postfix-accounts.cf:ro
    Ответ написан
  • Авторские права на GitHub?

    Tyranron
    @Tyranron
    Не пойму какое реальное практическое применение имеет сервис github и как обстоят дела с авторскими правами?


    Это хостинг Git репозиториев, который, помимо непосредственно удаленного Git репозитория, предоставляет ещё целый ворох удобных инструментов коллаборации и интеграции (code smell, code coverage, CI, Docker Hub'ы, Zapier'ы, боты, и вот всё это вкусное). Всё это позволяет удобно вести разработку проектов.
    К слову сказать, Github используют и для закрытых проектов тоже. Но это уже идет за денюжку.
    Авторские права регулируются лицензией, которую каждый уважающий себя репозиторий имеет.

    1) В чем логика выкладывать свой код на всеобщее обозрение, чтобы его скопировали и потом продавали? Или там реальные вещи, которые несут материальную ценность не выкладываются? Или там что-то типа: о посмотрите, я написал новый супер-аудиоплеер, качайте на здоровье и пользуйтесь. Или сервис наполовину коммерческий, типа вот ограниченные версии кода, можете пользоваться, а если хотите что-то нормальное - покупайте лицензию?


    Есть как закрытые (код доступен только членам команды), так и открытые (код доступен всем) проекты. В чем смысл открытых проектов и open source как такового - это отдельная огромная тема.
    Открытый исходный код, как минимум, дает следующие преимущества проекту:
    - Доверие и прозрачность. Любой желающий может изучить исходники и удостовериться, что там нет ничего вредного. Может сам взять и скомпилировать код, если не доверяет чужим бинарникам.
    - Рост за счет сообщества. 1 команда - хорошо, но тысячи контрибъюторов - лучше.

    Не все проекты являются "аудиоплеером на продажу". Не все проекты монетизируются. Более того, зарабатывать деньги - тоже далеко не цель каждого проекта. Open source - это просто другая модель разработки ПО. И с помощь неё разрабатываются достаточно серьезные вещи: Linux, Kubernetes, MySQL, PostgreSQL, тысячи их... Без open source не было бы такого бурного развития программных продуктов. Он является фундаментом и базой для всего остального. Назовите мне хотя бы один закрытый большой и известный проект, который не использует ни одного open source продукта вообще. Ведь open source на самом деле вездесущ =)

    2) И что понимается под авторскими правами на GitHub-e, да и вообще впринципе. Верстка сайта (сами блоки, расположение), если скопировать (кроме дизайна) - это считается нарушением авторских прав? С дизайном понятно, если макет один в один - это вроде как нарушение авторских прав. И кстати, сам дизайн макет по сути налеплен из разных фоток, зачастую с лицами людей - сами-то дизайнеры откуда берут это все, тупо качают из интернета чужие фотки?


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

    Откуда дизайнеры берут фотки - вопрос к ним. Как Вы должны понимать, ситуаций разных целый ворох. Одни просто берут фотки из интернета. Другие, более добросовестные, получают согласие автора на использование фотки, если она не выложена под свободной лицензией.

    3) Если взять код с функционалом типа CMS - это тоже нарушение авторских прав? Может я что-то не понимаю, но принцип CMS же примерно одинаковый, генерить статичные страницы, каталог и прочее взаимодействие? Взять тот же Bitrix, это что-то супер-уникальное чего нет в открытом доступе? Неужели за столько лет развития интернета в сети не появилось бесплатного качественного аналога платной CMS?


    Это будет нарушением прав, если Вы этот код будете использовать не согласно лицензии.

    Вопрос про принцип не понятен. Лицензирование принципов - это уже патенты. Если проект нарушает патент, то он его нарушает будь хоть открытым, хоть закрытым. И наоборот тоже, если в проекте реализовано что-то запатентованое его авторами - то копирование будет нарушением патента (если в условиях лицензии не указано другое). Но вообще open source и патенты как-то плохо смотрятся в одной корзине. Как говорится - ни рыба, ни мясо.

    За аналоги Bitrix не скажу, но вообще бесплатных CMS - пруд пруди. Гугл "в зубы" и вперед выбирать.
    Ответ написан
    5 комментариев
  • Golang Redis получить значения?

    Tyranron
    @Tyranron
    Ну так Вы же их (данные) явно и удаляете. У Вас что в коде producer'а, что в коде consumer'а, в функции init() идет вызов client.FlushDB().

    Подозреваю, Вы добавили этот вызов в producer чтобы обеспечить "чистоту эксперимента". А когда переносили код в consumer просто забыли убрать. В результате, когда у Вас запускается consumer, он подключается, вычищает всю БД, а потом пытается уже что-то из неё вычитать, и, естественно, читать уже нечего.
    Ответ написан
    Комментировать
  • Docker и базовые образы с разными дистрибутивами Linux?

    Tyranron
    @Tyranron
    Я понимаю что ядро одно, но окружение слишком разнообразное, мне нужна одна система.

    Зачем?

    Как использование кучи дистрибутивов скажется на производительности, если она очень важна вопреки удобству?

    Вообще никак.

    У Вас в контейнерах запускаются не дистрибутивы, и не "линуксы".
    В контейнерах запускаются процессы. И если это не кастомный образ, куда понапихано куча процессов с супервизором всего этого дела, то процесс запускается один. Вопрос производительности - это вопрос производительности Вашего процесса, и того как он работает. Если Вы запускаете, к примеру, mysqld, то какие там файлы остальные в контейнере лежат - по-барабану, потому что производительность mysqld зависит от него самого, его конфигурации, и ресурсов машины, а не от того, по чьему фэн-шую разложены файлы, CentOS'овскому, или Debian'овскому.
    Ответ написан
    Комментировать
  • Как настроить Debug режим, если исходники лежат в Docker?

    Tyranron
    @Tyranron
    У Вас в конфиге Xdebug указан порт 9001.
    xdebug.remote_port=9001

    А в контейнере этот порт у Вас выставлен наружу через expose.
    expose:
          - "9000"
          - "9001"

    Документация ясно говорит что в этом случае порт доступен только другим сервисам из docker-compose.yml.
    Expose ports without publishing them to the host machine - they’ll only be accessible to linked services.


    PHPStorm'а в docker-compose.yml не видно, а значит он и не может видеть Xdebug на том порту, что Вы ему скармливаете.

    Что нужно сделать?
    1. Перенести порт 9001 в ports:.
    2. В настройках IDEA указать Host: localhost для Xdebug (сейчас у Вас там какой-то левый IP).
    Ответ написан
  • Есть ли аналог curl для Rust?

    Tyranron
    @Tyranron
    Если пишете в web на Rust, то маст-хэв эту ссылку:
    www.arewewebyet.org
    Там расписано большинство аспектов касающихся web и текущее состояние экосистемы Rust по ним.

    Касательно Вашего вопроса, то это к HTTP Clients:
    www.arewewebyet.org/topics/clients
    Пишет "getting there, stable but still maturing", значит все достаточно неплохо.
    Ответ написан
    Комментировать
  • Как запустить filebeat внутри Docker контейнера?

    Tyranron
    @Tyranron
    По умолчанию предполагается, что в одном контейнере бежит всего один процесс. Если Вам нужно более одного процесса - либо разносите по отдельным контейнерам (Tomcat отдельно, Filebeat отдельно), либо добавляйте в контейнер какой-то супервизор, который будет курировать несколько процессов и смотреть дабы они не падали. Для Docker образов обычно используют s6 супервизор, который можно удобно использовать через s6-overlay.
    Ответ написан
  • Как запустить многоконтейнерное Docker приложение локально?

    Tyranron
    @Tyranron
    Не допускать опечаток в именах образов.

    У Вас в выводе docker images название iqmen_ru/iqpr-postrgres, а в docker-compose.yml уже iqmen_ru/iqpr-postgres.

    Ещё раз, наглядно:
    iqmen_ru/iqpr-postrgres
    iqmen_ru/iqpr-postgres
    Ответ написан
    Комментировать
  • Минимальные настройки безопасности Linux на VPS?

    Tyranron
    @Tyranron
    Ряд моментов Вы уже сделали, но я все равно их опишу для полноты списка.

    1. Создать отдельного пользователя и хороший пароль на sudo. Не использовать больше root напрямую. Совсем.

    2. SSH. Отключаем метод аутентификации по паролю. Если Вам не нужны другие методы, то их тоже можно отключить, оставив только publickey. Отключаем возможность аутентификации root'ом. Включаем использование только 2й версии SSH протокола.

    3. Устанавливаем Fail2Ban и настраиваем чтобы после нескольких неуспешных попыток подключения по SSH банило по IP на длительное время. Кол-во попыток и время бана можно тюнить в меру своей паранойи. У меня, например, банит на час после 2х неуспешных попыток.

    4. Iptables. Действуем по принципу "запрещено все, что не разрешено". Запрещаем по умолчанию весь INPUT и FORWARD трафик снаружи. Открываем на INPUT'е 22 порт. В дальнейшем открываем порты/forwarding по мере необходимости. Если у нас предполагаются сервисы на соседних серверах нужные только для внутренней коммуникации (Memcached, Redis, и т.д.), то открываем для них порты только для определенных IP. Просто так торчать наружу для всех они не должны.

    5. Настраиваем автоматические обновления apt-пакетов. Уровень security. То есть так, чтобы обновления безопасности накатывались автоматически, но при этом не выполнялись обновления со сменой мажорной версии (дабы обезопасить себя от "само сломалось").

    6. Устанавливаем ntpd. Серверное время должно быть точным. Также временную зону сервера лучше всего установить в UTC.

    7. TLS (не SSL) используем везде где можем. Через Let's Encrypt получаем бесплатные валидные сертификаты. В конфигах веб-серверов, mail-серверов, и других приложений торчащих наружу (в том числе и OpenVPN), запрещаем/убираем использование слабых шифров. Все ключи/параметры генерируем не менее 2048 бит. Самоподписные сертификаты подписываем с помощью SHA-256 (не SHA-1). Diffie-Hellman параметры (dh.pem) под каждый сервис лучше сгенерить отдельно. Проверяем TLS сервисов через Nmap. Минимальный grade должен быть A, не должно быть warning'ов.

    8. Правильный менеджмент пользователей/групп. Приложения/сервисы не должны запускаться под root'ом (разве что они действительно этого требуют и иначе никак). Для каждого сервиса создается свой пользователь.

    9. Если предполагается upload файлов через PHP (либо другие скриптовые языки), в директории, куда эти файлы загружаются (и которая доступна снаружи), должно быть жестко отключено любое выполнение скриптов/бинарников, что на уровне ОС (x права), что на уровне веб-сервера.

    Это была база.
    Дальше, в меру своей паранойи можно за'harden'ить сервер ещё следующими моментами:
    - SELinux, chroot
    - доступ к SSH только с определенных IP (нужно иметь 3-4 VPN-сервера под рукой)

    UPD И да, все это помнить/настраивать руками каждый раз может быть запарно. Используйте Ansible и автоматизируйте процесс (там родные и YAML, Jinja2 и Python).
    Ответ написан
    10 комментариев
  • Как лучше генерировать соль рандомно или по каким нибудь данным пользователя?

    Tyranron
    @Tyranron
    Соль не является секретным параметром.
    Единственная её задача - исключить вариант использования радужных таблиц. Для этого соль должна быть сложно угадываемой.

    Потому данные пользователя - так себе соль. Лучше не морочиться и сгенерировать случайную строку вменяемой длинны. Хранить вместе с хэшом.

    Для каждого пароля - своя отдельная соль.

    Все это уже реализовано в том же алгоритме хэширования паролей Bcrypt.

    Подробный ответ на вопрос о хэшировании паролей давался уже в этом вопросе:
    Как лучше всего шифровать пароли для сохранения в БД?
    Вопрос соли там разобран тоже.
    Ответ написан
  • Как разрешить доступ к MongoDB, которая находится в Docker'е, только определенным ip адресам?

    Tyranron
    @Tyranron
    Через iptables и делается. Все правильно пробовали.
    Осталось только чуть больше исследовать тему. Вам нужно использовать FORWARD chain, а не INPUT, а INPUT только если Вы делаете --network=host.
    Эта статья должна прояснить ситуацию:
    tomasre.com/2016/03/07/securing-coreos-with-iptables
    Ответ написан
    Комментировать
  • Как установить imagick для PHP7.1 (docker, alpine)?

    Tyranron
    @Tyranron
    В таких случаях через sub-shell можно скормить команде то, чего просит.
    Например:
    # Install Xdebug
    RUN apk add --update --no-cache --virtual .tools-deps \
                autoconf g++ libtool make \
     && (yes | pecl install xdebug) \
     && apk del .tools-deps \
     && rm -rf /var/cache/apk/*
    Ответ написан
    2 комментария
  • Как лучше всего шифровать пароли для сохранения в БД?

    Tyranron
    @Tyranron
    Чтобы лучше понять "как" и "почему", для начала следует сформулировать задачу и рассмотреть пути решения.

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

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

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

    Давайте поставим теперь себя на место злоумышленника. Располагая всем этим, как бы мы взламывали пароль?
    1. Радужные таблицы (заранее сгенерированные таблицы "хэш -> значение").
    2. Атака по словарю (сначала делается перебор по наиболее вероятным значениям).
    3. Полный перебор.
    Полный перебор хоть и решит задачу 100%, но это крайняя мера, крайне неэффективная, и, как правило, не рабочая, потому что пусть пароль и можно подобрать за десятки тысяч лет, злоумышленник столько не проживет (как и сама взламываемая система, и сам пользователь). Потому если мы обезопасились от пунктов 1 и 2 кое-как, то задачу, считай, решили.

    Если мы просто возьмем какую-то хэш-функцию (например, sha256) и захэшируем пароль, то сделаем очень плохо. Почему? Потому что злоумышленник, видя это, просто возьмет хэш и подставит в радужную таблицу, и, если пользователь не заморачивался с паролем (а как правило так и есть), то пароль будет получен практически сразу.

    Что нужно сделать, дабы исключить вариант использования радужных таблиц?
    Сделать так, чтобы значения, подаваемые на вход хэш-функции, гарантированно в них отсутствовали. Для этого и придумали соль. В связи с этим к соли есть одно простое требование: соль должна быть сложно угадываемой.
    То есть, если у нас есть пароль "password" и соль "111", то вероятность попадания строки "password111" в радужную таблицу все ещё очень высока, а значит подобная соль плохая. А вот соль "t%Lp-,DU4=w],9c7F.N$" хороша, потому что строку "passwordt%Lp-,DU4=w],9c7F.N$" в радужную таблицу никто записывать не будет.
    Вывод: нам нужна соль для того, чтобы исключить поиск по хэшу в радужных таблицах.

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

    Далее в арсенале злоумышленника остается атака по словарю.
    Увы, полностью исключить данный вариант может только пользователь, если будет использовать стойкие и сложные к угадыванию пароли, у которых вероятность попадания в словари "крайне мала"(с).
    Но на благоразумие всех пользователей надеятся не стоит, а обезопасить их как-то надо. И здесь у нас остается возможность "вставить палку в колесо" злоумышленнику, увеличив время выполнения алгоритма. То есть просто берем и хэшируем результат повторно надцать раз, пока время выполнения алгоритма не станет достаточно длинным, например, 500ms. Нам при аутентификации пользователя (да и самому пользователю) 500ms ждать не проблема, а вот злоумышленнику делать подбор пароля со скоростью 2 пароля за секунду, уже "ой-какая-головная-боль".
    Вывод: повторяем хэширование много раз, дабы увеличить время выполнения алгоритма, что замедлит подбор паролей.

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

    Дабы реализовать все вышесказанное, к велосипеду ручонки тянуть не нужно, именно из-за вышеуказанных "заморочек" в деталях алгоритмов. Криптография дилетанства не прощает. Тем более, что уже есть де-факто промышленные стандарты.
    Например, bcrypt алгоритм (спасибо kpa6uu за упоминание). В PHP он реализован посредством стандартной password_hash() функции. В других языках тоже хватает реализаций.

    Ну и наконец-то отвечая на Ваш вопрос "как лучше всего?", то на данный момент это алгоритм Argon2, победитель последнего Password Hashing Competition. С реализациями в языках, к сожалению, пока что не так все радужно как у bcrypt.
    Ответ написан
    2 комментария
  • Docker: alpine+nginx+php-fpm - не взлетает nginx?

    Tyranron
    @Tyranron
    Запихнуть в один контейнер больше одного процесса можно, но не самая хорошая идея, так как уже требуется супервизор для управления ими.
    В данном случае, считаю, Вам не нужно устанавливать nginx в этот же контейнер. Просто запустите официальный nginx образ отдельным контейнером и слинкуйте директорию Вашего приложения туда.
    Важные моменты:
    • Ваши файлы должны располагаться под одинаковым путем в обоих контейнерах.
    • Лучше чтобы nginx и php-fpm бежали от имени одного и того же пользователя. Для этого можно использовать уже присутствующего в обоих образах пользователя nobody.
    Ответ написан
    2 комментария
  • Как правильно настроить gcc для gobot?

    Tyranron
    @Tyranron
    Потому что Вы не подтянули зависимости (dependencies) для сорцов gobot. Их можно установить через go get. Смотрим официальную доку.
    Ответ написан
  • Как защитить код?

    Tyranron
    @Tyranron
    Теоретически, Docker при этом может помочь:
    1. Исходный код проекта закрыт и нигде не публикуется, то же касается Dockerfile. Вы распространяете только уже готовые Docker-образы.
    2. При сборке Docker-образа шифруем файлы самой программы, будь то .jar'ник, бинарник или голые php'шные сорцы.
    3. Для расшифровки требуется лицензионный ключ, который должен пробрасываться в контейнер при старте через переменные окружения. Ним файлы программы расшифровуются и программа стартует.


    На практике же, получится то же самое что и с пиратством различного софта сегодня:
    • Тот, кто обладает ключем, может выложить его в открытый доступ. Этот момент можно обойти, если придумать какую-либо централизованую верификацию ключа на своих серверах (см. как делают JetBrains). Или под каждый ключ генерить отдельный уникальный Docker-образ. Опять же, тот кто обладает ключем, обладает и соответствующим образом, и ним он тоже может поделиться.
    • Тот, кто обладает ключем, может спокойно расковырять контейнер через docker exec. И если файлы программы сами по себе отражают хорошо исходный код (например PHP-скрипты, или бинарники Go), то тут утекает уже и исходный код Вашего продукта, что не комильфо. Так что обфускацией кода и другими техниками защиты результатов компиляции пренебрегать не стоит.


    В общем, палок в колеса вставлять можно "ого-го-го", но полного решения данной проблемы, ИМХО, нету. Потому пиратство и процветает, ибо оно возможно.
    Ответ написан
    4 комментария
  • Как заставить systemd запускать контейнеры через docker-compose?

    Tyranron
    @Tyranron
    1. Чтобы при перезапуске машины контейнеры сами стартовали, нужно всего лишь соответствующий systemd service сделать enabled. Cron здесь не нужен.
    sudo systemctl enable docker-project.service

    2. Любой systemd service - это всего лишь абстракция. А что именно он выполняет - решать именно Вам. Что у Вас ExecStart'ом будет стартовать один контейнер через docker run, что связка контейнеров через docker-compose up, для systemd и CoreOS принципиальной разницы нет.

    3. В приведенной Вами декларации systemd service'а в секции [Unit] есть следующие строки:
    Requires=docker-project.service
    After=docker-project.service

    Они означают, что декларируемый Вами service должен быть запущен только после того, как был запущен docker-project.service. Но, насколько я понимаю из Вашего описания, это и есть декларация docker-project.service. То есть Вы говорите systemd что сервис должен быть запущен после запуска самого себя. Это не есть гуд. Эти строки, судя по всему, должны быть такими:
    Requires=docker.service
    After=docker.service

    Дабы systemd пытался запустить этот сервис только после того, как будет запущен Docker daemon.

    4. В файлике docker-up.sh у Вас docker-compose up запускается в foreground'е. Первая связка контейнеров то запустится, а что со второй - не понятно. Наверное, все же стоило их запускать с -d ключиком, а в systemd декларации в секции [Service] указать Type=forking, если прям так нужно обе связки контейнеров запускать одним systemd service. Но вообще, имхо, на каждый docker-compose.yml должен быть свой отдельный systemd service, и никаких forking.
    Также, заворачивать docker-compose команды внутрь docker-up.sh было не самой хорошей идеей. Вам ничего не мешало написать несколько ExecStart'ов подряд, тем самым не размазывая декларацию по нескольким файлам, и было бы видно на каком именно шаге оно отваливается при systemctl start docker-project.service.

    5. Логи наше все. Используйте journalctl --unit=docker-project.service дабы глянуть что там вообще произошло, и кто на кого ругается.

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

    К размышлению:
    Раз уж Вы используете CoreOS, посмотрите в сторону Kubernetes для запуска сервисов/контейнеров. Ставится на CoreOS он в пол-оборота, а возможностей, гибкости и вкусных абстракций уж гораздо поболее, нежели у systemd/fleet.
    Ответ написан
    1 комментарий
  • Как использовать докер для разового выполнения приложений?

    Tyranron
    @Tyranron
    Можно. Но приложения внутри контейнера видят только файловую систему контейнера. Вам нужно подмонтировать Ваш файлик test.py внутрь контейнера сначала.
    docker run --rm -it -v $(pwd)/test.py:/test.py:ro python python34 /test.py

    Если в результате выполнения test.py у Вас создаются какие-то файлы, позаботьтесь о том, чтобы они тоже писались в подмонтированую директорию, иначе по завершению работы они останутся закупорены внутри контейнера (и удалены вместе с контейнером, т.к. используется --rm флаг).
    Ответ написан
    2 комментария
  • Как запустить внутри docker "composer require" добавив ssh-key?

    Tyranron
    @Tyranron
    Попробуйте подмонтировать в контейнер ключ (и ssh.config, по желанию).

    Если команда php composer.phar install выполняется от имени root внутри контейнера, то примерно следующие строки должны быть в `docker-compose.yml`:
    version: '2'
    services:
      php:
        ...
        volumes:
          ...
          - /path/to/my.key:/root/.ssh/repo.key:ro
          ...
        ...
    Ответ написан
  • Как правильно делать deploy с помощью docker registry?

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

    Давайте разберемся с инструментами и их предназначением, которые Вы используете:
    • Комманда docker - это консольный интерфейс (CLI) для работы с Docker
    • docker build создает по заданному Dockerfile образ контейнера
    • docker tag присваивает указанному образу указанный тег (опция -t для build делает то же самое)
    • docker pull скачивает указанный образ из удаленного регистра на текущую машину
    • docker push заливает указанный образ в удаленный регистр
    • docker run запускает новый контейнер из указанного образа
    • docker ps выводит список текущих "бегущих" контейнеров

    Команда docker не жонглирует файлами, она жонглирует образами и контейнерами, а они от нас абстрагированы Docker'ом, как что-то эфемерное. То есть выполняя комманду docker pull Вы не скачиваете образ в ту папку, где выполняете команду, и уж точно не скачиваете какие-либо файлы. Все что Вы делаете этой командой - это скачиваете образ в локальное хранилище Docker'а, дабы Docker daemon мог запустить контейнер на основании этого образа.

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

    У Вас в манифесте указана директива build:. Таким образом docker-compose пытается сначала собрать контейнер, вместо того, чтобы просто запустить его из образа.

    Касательно совета docker-compose.yml под каждый env, все правильно советовали. Именно так это и задумывалось. Вы в манифесте указываете отнюдь не разные окружения (development, production), а набор контейнеров, которые должны бежать в одной связке одной логической единицей (концепция POD'ов). Ничего не запрещает делать и так, как сделали Вы, но это сродни использованию дуршлага в роли миски для еды: сегодня Вы нормально из него наворачиваете пельмени, а завтра супчик в нем уже куда-то не туда утекает.

    Воркфлоу в Вашем случае можно организовать следующим образом:
    1. На dev-машине у Вас один docker-compose.yml, согласно которому контейнер перед запуском собирается из сорцов.
    2. Когда у Вас готова новая версия приложения, Вы его собираете через docker build, присваиваете ему номер версии через docker tag и отправляете в удаленный регистр образов через docker push.
    3. На prod-машине у Вас отдельный docker-compose.ymlв котором указано запускать конкретную версию образа (и никаких build). Новая версия приложения - меняем тег образа в манифесте и перезапускаем контейнеры. При выполнении docker-compose образ автоматически скачается перед запуском, если его нет локально. Если же Вы обновили образ конкретной версии, которая уже была скачана ранее, то да, нужно выполнить docker pull перед стартом, дабы скачать новый образ.


    Дополнительный совет:
    Сборку образа и его заливку в удаленный регистр часто удобно автоматизировать с помощь Makefile'ов.
    Ответ написан
    3 комментария