Home » Nodejs » how to set supervisor to run a shell script

how to set supervisor to run a shell script

Posted by: admin November 29, 2017 Leave a comment

Questions:

Setting up a Dockerfile to install node prereqs and then set up supervisor in order to run the final npm install command. Running Docker in CoreOS under VirtualBox.

I have a Dockerfile that sets everything up correctly:

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"]

And then I want to set up supervisord to launch one of a few possible processes, including an installation shell script that I’ve confirmed to work correctly, install.sh, which is located in the application’s /etc directory:

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

However, I’m very new to supervisor syntax, and I can’t get it to launch the shell script correctly. This is what I have in my supervisord.conf file:

[supervisord]
nodaemon=true

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

When I run the Dockerfile, everything runs correctly, but when I launch the image, I get the following:

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'

Clearly, I have not set up supervisor correctly to run this shell script — is there part of the syntax that I’m screwing up?

Answers:

The best way that I found was setting this:

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

Questions:
Answers:

think I got this sorted: needed the full path in command, and instead of having user=nonroot in the .conf file, I put su nonroot into the install.sh script.

Questions:
Answers:

I had a quick look in the source code for supervisor and noticed that if the command does not contain a forward slash /, it will look in the PATH environmental variable for that file. This imitates the behaviour of execution via shell.

The following methods should fix your initial problem:

  1. Specify the full path of the script (like you have done in your own answer)
  2. Prefix the command with ./, i.e. ./install.sh (in theory, but untested)
  3. Prefix the command with the shell executable, i.e. /bin/bash install.sh

I do not understand why user= does not work for you (have you tried it after fixing execution?), but the problem you encountered in your own answer was probably due to the incorrect usage of su which does not work like sudo. su will create its own interactive shell and will therefore hang while waiting for standard input. To run commands with su, use the -c flag, i.e. su -c "some-program" nonroot. An explicit shell can also be specified with the -s flag if necessary.