如何设置supervisor运行shell脚本

16

设置一个Dockerfile来安装node先决条件,然后设置supervisor以便运行最终的npm install命令。在VirtualBox下在CoreOS中运行Docker。

我有一个Dockerfile可以正确地设置所有内容:

FROM ubuntu
MAINTAINER <<Me>>

# Install docker basics
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get upgrade -y

# Install dependencies and nodejs
RUN apt-get update
RUN apt-get install -y python-software-properties python g++ make
RUN add-apt-repository ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get install -y nodejs

# Install git
RUN apt-get install -y git

# Install supervisor
RUN apt-get install -y supervisor
RUN mkdir -p /var/log/supervisor

# Add supervisor config file
ADD ./etc/supervisord.conf /etc/supervisor/conf.d/supervisord.conf

# Bundle app source
ADD . /src

# create supervisord user
RUN /usr/sbin/useradd --create-home --home-dir /usr/local/nonroot --shell /bin/bash nonroot
RUN chown -R nonroot: /src

# set install script to executable
RUN /bin/chmod +x /src/etc/install.sh

#set up .env file
RUN echo "NODE_ENV=development\nPORT=5000\nRIAK_SERVERS={SERVER}" > /src/.env

#expose the correct port
EXPOSE 5000

# start supervisord when container launches
CMD ["/usr/bin/supervisord"]

然后,我希望设置supervisord以启动几个可能的进程之一,包括一个我确认可以正确运行的安装脚本install.sh,该脚本位于应用程序的/etc目录中:

#!/bin/bash
cd /src; npm install
export PATH=$PATH:node_modules/.bin

然而,我对supervisor的语法非常陌生,无法正确运行shell脚本。以下是我在supervisord.conf文件中的内容:

[supervisord]
nodaemon=true

[program:install]
command=install.sh
directory=/src/etc/
user=nonroot

当我运行Dockerfile时,一切正常,但是当我启动镜像时,出现以下错误:
2014-03-15 07:39:56,854 CRIT Supervisor running as root (no user in config file)
2014-03-15 07:39:56,856 WARN Included extra file "/etc/supervisor/conf.d/supervisord.conf" during parsing
2014-03-15 07:39:56,913 INFO RPC interface 'supervisor' initialized
2014-03-15 07:39:56,913 WARN cElementTree not installed, using slower XML parser for XML-RPC
2014-03-15 07:39:56,914 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2014-03-15 07:39:56,915 INFO supervisord started with pid 1
2014-03-15 07:39:57,918 INFO spawnerr: can't find command 'install.sh'
2014-03-15 07:39:58,920 INFO spawnerr: can't find command 'install.sh'

显然,我没有正确地设置supervisor来运行这个shell脚本 -- 我是不是在语法的某个部分搞砸了?
4个回答

23

我找到的最好方法是进行如下设置:

[program:my-program-name]
command = /path/to/my/command.sh
startsecs = 0
autorestart = false
startretries = 1

5
我查看了supervisor的源代码,发现如果command不包含正斜杠/,它将在PATH环境变量中查找该文件。这模拟了通过shell执行的行为。
以下方法应该解决您最初的问题:
  1. 指定脚本的完整路径(就像您在自己的答案中所做的那样)
  2. command前加上./,即./install.sh(理论上,但未经测试)
  3. command前加上shell可执行文件,即/bin/bash install.sh
我不明白为什么user=对您无效(您是否在修复执行后尝试过?),但是您在自己的答案中遇到的问题可能是由于su的错误使用方式引起的,它与sudo不同。 su将创建自己的交互式shell,因此会挂起等待标准输入。要使用su运行命令,请使用-c标志,例如:su -c "some-program" nonroot。如果需要,还可以使用-s标志指定显式shell。

5

我想我解决了这个问题:在命令中需要完整的路径,而且我将.conf文件中的user=nonroot改为在install.sh脚本中添加su nonroot


1
编辑:不行,看起来它卡在“INFO success: install entered RUNNING state”但没有退出脚本。 - fox

0

我也遇到了这个问题。对我来说,根本原因是没有设置shebang行导致的。即使脚本在bash中可以正常运行,但要让supervisord能够使用exec() 来运行它,必须以例如#!/bin/bash 开头。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接