amorphine Да, линкую из хост системы, либо из других мест. Зависит.
Зашивать конкретный конфиг в образ - плохая идея. Ведь при изменении конфига Вам придется пересобирать образ. Смотрите на контейнеры как на функции, а на конфиги, порты, переменные окружения, и volumes, как на входные/выходные параметры этой функции. Хардкодить параметры в функцию - плохая практика. То же самое и с контейнерами.
Забыли самый простой и очевидный вариант - использовать системный (или любой другой) супервизор: systemd, supervisord, runit, SysVinit, и т.д.
Как минимум один всегда присутствует в системе, потому не надо ставить никакого дополнительного софта и модифицировать саму программу. Просто создаем манифест и пользуемся благами.
crmMaster: А проводили ли Вы собственное предварительное исследование на данную тему? Если да, поделились бы сразу своими результатами.
ИМХО, надо накидать бенчи, и прогнать им известные/интересующие либы, дабы увидеть реальных выхлоп интересующих Ваc метрик.
Alister O: Все что я мог посоветовать - я и описал выше. Причем это не конкретные советы (ибо реального опыта разработки и продвижения подобного продукта у меня нету), а всего лишь размышления на тему, и направление в котором можно копать дальше (обфускация, защита результатов компиляции, лицензирование по ключам, серверная верификация/валидация ключей).
На чем реализовывать?
1) На чем умеете
2) На чем есть годные средства для защиты результатов компиляции
+1 к комментарию выше
Если Вам нужно несколько процессов внутри одного контейнера - уже нужно впихивать супервизор, иначе что Вы будете делать если какой-то процесс упадет?
Alister O: с виртуальной машиной примерно то же самое что и с Docker-образом, да и с любым образом в принципе, хоть с запароленым архивом =)
При использовании Docker'а производительность падать не должна, так как образ бежит напрямую на ядре Linux, просто в своем изолированном пространстве. Если запускать не на Linux, то будет прослойка в виде неявной виртуальной машины (кроме Win10, они вроде нативную поддержку запилили почти).
Уникальный ключ - да, но во-первых, нарушителя надо ещё вычислить, а для этого надо разрабатывать дополнительные механизмы. Во-вторых, нужно ещё достоверно понять, нарушитель ли это, а не "я просто запустил на втором своем компьютере". Это ввязывает Вас в целый класс проблем, с которыми приходится считаться, которые нужно предусматривать, решать, и полного решения, опять же, нету, потому что человеческая природа может быть достаточно гнусной =/
romy4: видимо дело вкусовщины. Каждому удобен свой инструмент. Мой опыт как раз противоположен Вашему. Расход памяти меньше, работает шустрее, простые и понятные примитивы, которые удобно компонуются. С памятью проблем не было, не текло, управление ею ведь не ручное. В C шарю на уровне "понять что делает строка кода, с гуглением". После синхронного PHP, конечно же, понадобилось въехать в асинхронщину и concurrency, чтобы нормально писать на Go, но это дело наживное. Чего-то неочевидного и неявного я особо не встречал, да и у создателей одна из основных позиций "явное лучше неявного".
Я понимаю, что у Go не самый выразительные и изящные синтаксис и система типов, мягко сказано. Но как платформа по шустрости он очень даже ниче. А учитывая то кол-ва софта которое на нем пишется, причем далеко не только закрытыми компаниями, а огромными опенсорс-комьюнити, учитывая те решения, что на нем уже написаны и как они работают, я обьективно никак не могу сказать, что Go недопилен, недоразвит или сырой. Определенно ему есть куда развиваться. Но его и так в продакшне уже тоннами.
romy4 серьезно? Можно пруфы? Ничего, что разработчики с момента выхода стабильной версии Go 1.0 только и делают фактически что вместо ввода 100500 фич, топят в улучшение производительности и оптимизацию? Как Вам хотя бы это https://habrahabr.ru/company/mailru/blog/305614/ ?
А кластер чего? Есть memcached cluster, есть Percona Galera Cluster, а есть CoreOS + fleet, или Kubernetes. И все из них можно поднять на выделенных серверах. Только "кластер" - это обобщенное понятие, которое подразумевает управление стаей машин/сервисов/приложений как одной. Какие задачи Вы хотите решить кластеризацией?
Ну тогда либо собирать приложение вне контейнера, а потом уже собранное заливать внутрь, либо установить ssh через соответствующий пакетный менеджер образа (apt get для debian/ubuntu, apk add для alpine, yum install для centos, и т.д.), но ssh'у в результирующем образе Вашего приложения, который будет крутится в продакшене, вообще говоря делать нечего и он там не нужен.
Если по фэн-шую, то должен быть отдельный образ (builder) в котором Вы собираете свое приложение (с предустановленными ssh'ами и прочим) и отдельный образ который и является результатом сборки.
Грубо говоря, pipeline сборки будет выглядеть следующим образом:
запускаем контейнер (из builder-образа), который собирает приложение и складывает результат сборки в подмонтированую папку, и далее запускаем сборку образа нашего приложения при которой мы просто заливаем собранное приложение в чистое runtime окружение.
Таким образом нам кроме docker на локальной машине (или build-сервере) ничего не нужно, и в то же время имеем воспроизводимые runtime и compiletime среды.
Prod и stag - это не версии приложения. Это окружения, где приложение запускается. У MySQL же нет, к примеру, версий prod и stag, у него есть конкретные версии 5.5.41, 5.6.1 и так далее. Но в prod и stage MySQL запускается с разными конфигами. Потому Ваши контейнеры не должны хранить конфигурацию внутри (разве что дефолтную), а получать её снаружи.
Как приложения откатывать, как версионировать, как доставлять на сервера, как управлять зависимостями, куда писать логи, как доставлять на сервера конфигурации окружений, что будет если сервер ребутнется, что делать если приложение упадет - это вопросы не к Docker, это вопросы администрирования и деплоя. Я очень Вам советую нагуглиться и начитаться на эту тему по самое "не хочу", дабы у Вас в голове был ясный ответ на все эти вопросы и Вы знали точно, что должно быть конечным итогом Вашей реализации. Docker лишь помогает в некоторых моментах, но не предоставляет и не навязывает подход к решению этой проблемы.
Ответы на Ваши вопросы зависят от того, чем именно Вы собираетесь запускать контейнеры на продакшене. Если руками, то да: docker pull -> docker stop -> docker run. Если через docker-compose, то docker-compose pull -> docker-compose restart. Если через супервизор какой (systemd, к примеру), то там все это нужно уже задекларировать в описании service. Если ещё что-то, то смотрите там.
Makefile'ы помогают автоматизировать сборку артефактов, а не их запуск. Можно, конечно извернуться и использовать и для этого, но опять же, неудобно применять инструмент не по назначению.
Для автоматизации деплоя и жонглирования версиями, конфигурациями, состояниями серверов, да и инфраструктурой в целом, посмотрите в сторону Ansible, Capistrano, Salt Stack, Chef, Puppet.
Затем, что хардкодить параметры конфигурации внутри приложения/контейнера банально неудобно.
"Не работает" мне не говорит ни о чем. Вы бы написал характер ошибки хотя бы, или по каким параметрам пробуете подключиться. Подозреваю, что Вы пытаетесь подключиться на localhost изнутри контейнера. Так не работает. У контейнера по умолчанию своя сеть. https://docs.docker.com/engine/userguide/networking/
Мой Вам совет: нужно четко понять, какие задачи контейнеры призваны решать, каким образом их решают, и, самое главное, почему они решают эти проблемы именно так. То есть понять и проникнуться проблематикой и идеологией. Когда приходит понимание этого, на все остальное ответы приходят сами собой, потому что стает понятно, как "забивать гвозди молотком".
Ясно. С registry все просто на мой взгляд. Это тупо как репозиторий исходников. Если проект/контейнер можно держать открытым и доступным всем, то лучше залить в аккаунт на Docker Hub'е (или Quay.io) по аналогии с открытыми либами/проектами на Github. Меньше мороки, плюс всегда доступно. Если это что-то, чему уже нельзя утекать в открытый доступ, то следует поднять свой собсвенный docker registry по аналогии с тем, как подымается собственный Git-сервер, и, в принципе, на той же машине (если нет каких-то экзотик в плане требований к инфраструктуре).
zoriko: С Tectonic не игрался. Не привлекает своей платностью. Если нет конкретных вопросов, то ловите меня в скайпе под тем же ником. Хотелось бы, правда, обсуждение все же сделать здесь и открытым, дабы другие люди с похожими проблемами имели пищу к размышлению. Потому все же настоятельно рекомендую разбить свою проблему на ряд этапов, и "провентилировать" каждый из них здесь.
Зашивать конкретный конфиг в образ - плохая идея. Ведь при изменении конфига Вам придется пересобирать образ. Смотрите на контейнеры как на функции, а на конфиги, порты, переменные окружения, и volumes, как на входные/выходные параметры этой функции. Хардкодить параметры в функцию - плохая практика. То же самое и с контейнерами.