Supervisord - using A variable INSIDE the supervisord.conf

alonisser picture alonisser · Dec 2, 2015 · Viewed 7.1k times · Source

Moved to using supervisod as a process control system.

I have a LONG and repeating ENVIRONMENT configuration in my supervisord.conf setting a lot of environment variables for a lot of processes. I need to define it one place and reuse it, to keep the configuration DRY and maintainable. is that possible with supervisor and how?

EDIT: Example of a non dry configuration

[program:node-app1]
command=node /home/ubuntu/server/node-app1/app.js
directory=/home/ubuntu/server/node-app1
autostart=true
autorestart=true
stderr_logfile=/home/ubuntu/supervisor/node_app1/err.log
stdout_logfile=/home/ubuntu/supervisor/node_app1/out.log
user=ubuntu
priority=998
startretries=20
ENVIRONMENT=BROKER_URL="amqp://user:[email protected]:5672",
            NODE_ENV=envName,
            MONGO_URL="mongodb://path.to.mongo:27017",
            BASE_PUBLIC_API="http:path.to.api",
            REDIS_URL="redis://path.to.redis:6379",
            BACKEND_URL="https://path.to.backend",
            CHARTS_URL="https://path.to.charts"

[program:node-app2]
command=node /home/ubuntu/server/node-app2/app.js
directory=/home/ubuntu/server/node-app2
autostart=true
autorestart=true
stderr_logfile=/home/ubuntu/supervisor/node_app2/err.log
stdout_logfile=/home/ubuntu/supervisor/node_app2/out.log
user=ubuntu
priority=20
startretries=20
ENVIRONMENT=BROKER_URL="amqp://user:[email protected]:5672",
            NODE_ENV=envName,
            MONGO_URL="mongodb://path.to.mongo:27017",
            BASE_PUBLIC_API="http:path.to.api",
            REDIS_URL="redis://path.to.redis:6379",
            BACKEND_URL="https://path.to.backend",
            CHARTS_URL="https://path.to.charts"

What could be shared: ENVIRONMENT, base directory for logs (only the end would change for each app), common variables like startsecs. etc

Answer

lossleader picture lossleader · Dec 10, 2015

Options

Via Inheritance from supervisord:

As long as you are using version 3.0a10 or above, you can set environment variables in [supervisord] environment and they will be in the environment of all processes under supervisord's management.

[supervisord]
...
environment=FAVORITE_VENTURE="RUSTY",FAVORITE_COLOR="RED"

Working with Variables supervisord inherited from a Shell

Supervisord also has a %(ENV_VARNAME)s expansion format for interpreting environment variables which would allow moving around variable names for different processes. But the configuration's environment section does not add to the environment variables available by the %(ENV_)s mechanism, so it would be necessary to call supervisord with variables already set by your shell.

As an example, if you use init scripts to start supervisord and are on a debian based system (i.e. Ubuntu) then you might start with the following in /etc/default/supervisor:

export SUPERVISOR_INCLUDES="main.conf test.conf"
export MAIN_RETRY_COUNT=2
export TEST_RETY_COUNT=1
MONGO_BASE="MONGO_URL=mongodb://path.to.mongo"
MAIN_MONGO_URL="${MONGO_BASE}:27017"
TEST_MONGO_URL="${MONGO_BASE}:27018"
export MAIN_ENV="${MAIN_MONGO_URL},OTHER_THING=\"Another thing with escaped quoting\""
export TEST_ENV=..

Then use them in configurations:

; supvervisord.conf
[includes]
files= %(here)s/subdir/other.conf %(ENV_SUPERVISOR_INCLUDES)s 

; main.conf
[group:main]
...
[program:mainbackend]
startretries=%(ENV_MAIN_RETRY_COUNT)s
environment=%(ENV_MAIN_ENV)s

If users can sudo and call supervisord directly, this method doesn't work very well since sudo both strips the users environment and doesn't run traditional shell init scripts. But you can source /etc/default/supervisor in root's .bashrc and use sudo bash -c "supervisord .." or source it before calling supervisord.