When configuring programs in Supervisord, a common requirement is to append custom directories to the existing $PATH
environment variable. However, direct variable expansion like PATH="/new/path:$PATH"
doesn't work as expected because Supervisord doesn't evaluate environment variables in the configuration file.
The issue stems from how Supervisord processes environment variables in its configuration:
; This won't work as expected
environment=PATH="/custom/path:$PATH"
The $PATH
reference remains literal rather than being expanded to the current system PATH.
Method 1: Using the Full PATH Value
Explicitly include the entire PATH value in your configuration:
environment=PATH="/home/site/environments/master/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Method 2: Dynamic PATH Construction
For more flexibility, use a wrapper script that sets the PATH before executing your program:
command=/bin/bash -c 'export PATH="/custom/path:$PATH"; exec /path/to/your/program'
Method 3: Environment Variable Substitution
Supervisord supports environment variable substitution from its own environment:
environment=PATH="/custom/path:%(ENV_PATH)s"
Note this requires the parent process to have PATH set when starting supervisord.
- Always verify the final PATH using
supervisorctl tail programname stderr
- Consider using absolute paths for all executables when possible
- For complex environments, use wrapper scripts for better control
Here's a full program configuration example:
[program:myapp]
command=/opt/myapp/wrapper.sh
environment=PATH="/opt/myapp/bin:%(ENV_PATH)s"
With wrapper.sh containing:
#!/bin/bash
export PATH="/opt/myapp/bin:$PATH"
exec /opt/myapp/bin/main --some-flag
When configuring programs in Supervisord, you might need to modify the PATH
environment variable. A common requirement is to append a directory to the existing PATH rather than completely overwriting it. The naive approach doesn't work:
environment=PATH="/custom/path:$PATH" # Doesn't work!
Supervisord doesn't perform shell-style variable expansion in the configuration file, so $PATH
remains literal.
The most reliable approach is to explicitly specify the complete PATH:
environment=PATH="/custom/path:/usr/local/bin:/usr/bin:/bin"
However, this becomes problematic when you need the configuration to work across different systems where the default PATH might vary.
For more flexibility, you can use a wrapper script that modifies the PATH before executing your program. Create a shell script (e.g., wrapper.sh
):
#!/bin/bash
export PATH="/custom/path:$PATH"
exec /path/to/your/program "$@"
Then configure Supervisord to use this wrapper:
[program:myapp]
command=/path/to/wrapper.sh
Another approach is to use the env
command in your program configuration:
[program:myapp]
command=env PATH="/custom/path:$PATH" /path/to/your/program
This works because the shell that Supervisord uses to execute the command will expand $PATH
.
For complex environment setups, consider using an environment file:
[program:myapp]
environment=ENV_FILE="/path/to/environment"
command=/path/to/your/program
Then in your program, you can source this file to set up the environment, including PATH modifications.
To verify your PATH is set correctly, you can temporarily modify your program to log the environment:
[program:debug]
command=env
This will show you the actual environment variables being passed to your program.