2015-06-29 3 views
-1

Я нахожусь в процессе создания сервиса, который, среди прочего, позволяет пользователям запускать/останавливать веб-сервер Golang по своему усмотрению. Чтобы получить сервер Nodejs, работающий при подобных обстоятельствах, я просто выдаю nodejs /path/to/index.js &disown из командного файла, который я запускаю при запуске контейнера. Существенные битыЗапуск golang webserver внутри Dockercontainer

ADD gorun.sh /usr/local/bin/gorun.sh 
RUN chmod +x /usr/local/bin/gorun.sh 

... 
ENTRYPOINT ["/bin/bash"] 
CMD ["/usr/local/bin/gorun.sh"] 

Это работает отлично, каждый раз. В gorun.sh У меня есть линия nodejs /path/to/index.js & disown.

Теперь, когда я пытаюсь получить веб-сервер Golang, работающий в аналогичных условиях, я думал, что попробую тот же подход. Я изменил сценарий gorun.sh на чтение

#! /bin/bash 
go run /path/to/index.go & disown; 
ps aux | grep go 

Теперь вот странная вещь. Я пытался получить сервер Go начал два способов

  • Сугубо в качестве эксперимента я начал контейнер Docker с терминалом, подключенным в называется gorun из терминала. Сервер Golang сразу заработал, и все было ханкри-дори.
  • Чтобы лучше подражать тому, как все работает в реальном мире - я разместил файл startgo.txt в заранее определенном месте, которое затем получает задание CRON, которое вызывает gorun. На этот раз без радости - сервер не запускается.

Почему бы просто не позвонить go run /path/to/index.go & disown из сценария запуска контейнера Docker? Пробовал это тоже - тот же результат: сервер не запускается.

Непонятно, что здесь происходит. Почему сервер Nodejs запускается, а сервер golang отказывается от пустой точки? Почему он запускается, если я запускаю один и тот же сценарий из терминала? Я бы очень признателен за любую помощь в решении этих проблем.

+5

Не используйте 'идти run'. Создайте или установите требуемый двоичный файл. (ваш 'ps aux | grep go' не получает серверный процесс, это инструмент go go) – JimB

ответ

-3

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

Никогда не забывайте: Чтобы Golang доставлял свою магию, ОС должна быть в состоянии ее найти. Введите переменную среды $ GOPATH. Если вы похожи на меня, вы будете следовать инструкциям где-то в сети о том, как это сделать. Я следовал инструкциям в this post на Vultr. Суть того, что они предлагают

echo export GOPATH=/opt/gopkg >> ~/.bashrc 
echo export GOROOT=/opt/go >> ~/.bashrc 
echo export PATH=$PATH:$GOROOT/bin:$GOPATH/bin >> ~/.bashrc 

Отличные инструкции - спасибо Vultr.

Ключ Isssue

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

go run /path/to/index.go & 

из терминальной сессии, прикрепленного к сессии Докер это работал. Однако, когда я попытался выполнить его из сценария bash, выполненного в начале сеанса Docker, этого не произошло.

Когда вы немного об этом подумаете и посмотрите, что происходит в приведенных выше инструкциях Vultr, все это ослепительно очевидно.Переменные пути устанавливаются ТОЛЬКО КОГДА ИНТЕРАКТИВНЫЙ ТЕРМИНАЛ ОТКРЫТ! - т. Е. Когда вы пытаетесь выполнить команду go dosomething из любого старого командного файла - например, тот, который вы запускаете при запуске контейнера Docker.

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

export GOPATH="/opt/gopkg"; 
export GOROOT="/opt/go"; 
export PATH=$PATH:$GOPATH/bin:$GOROOT/bin; 
+1

Вы должны компилировать свою программу Go и запускать ее через' RUN' или 'ENTRYPOINT' в вашем файле Docker. Использование сценария оболочки для exec go run очень слабовато (как вы находите). См. Мой пример в этом репо: https://github.com/elithrar/supervisord – elithrar

+0

@elithrar - Файл Docker используется один раз для создания соответствующего изображения. Я мог бы сделать то, что вы предлагаете, если программа Go, которая должна быть запущена внутри контейнера Docker, была статичной. В моем случае программа будет меняться при работе пользователя контейнера. Восстановление образа докера или компиляция программы Go на «реальной» машине в отличие от внутри запущенного контейнера не являются параметрами в данном экземпляре – DroidOS

Смежные вопросы