How to Run Supervisor Programs as Another User with Environment Variables Expansion


2 views

When running programs through Supervisor with a different user context while needing environment variable expansion, several technical hurdles emerge. The configuration you provided shows a common scenario where environment variables defined at the supervisord level don't properly propagate to program commands.

The "can't connect to unix server" error typically occurs when:

  • Supervisor tries to switch users but lacks proper permissions
  • Environment variables aren't properly expanded in the command
  • The socket file permissions become restrictive after user switching

Here's a corrected approach that maintains security while achieving your goal:

[program:hank-message-forwarder]
user = a-user-name
directory = /home/a-user-name
environment = 
    HOME="/home/a-user-name",
    APP="staging.example.com",
    SYMFONY_ENVIRONMENT="staging"
command = bash -c '${HOME}/apps/${APP}/current/bin/hank forward-messages tcp://*:5500 tcp://*:5600'
stdout_logfile = /var/log/pink-tie/%(program_name)s-out.log
stderr_logfile = /var/log/pink-tie/%(program_name)s-err.log

The solution implements several critical fixes:

1. Uses bash -c to enable proper environment variable expansion
2. Sets the working directory to avoid path resolution issues
3. Moves environment variables to the program section for proper scoping
4. Maintains explicit user specification at the program level

To verify your environment variables are properly set:

[program:env-test]
command = /usr/bin/printenv
user = a-user-name
environment = 
    TEST_VAR="this_should_show_up",
    PATH="/usr/local/bin:/usr/bin:/bin"
redirect_stderr = true
stdout_logfile = /tmp/env-test.log

For complex setups where you need parent environment inheritance:

[program:complex-app]
user = deploy-user
environment = 
    PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
    NODE_ENV="production",
    %(ENV_OVERRIDES)s
command = bash -c 'source ${HOME}/.bashrc && exec ${HOME}/app/start.sh'

When configuring Supervisor to run processes under a different user account while maintaining environment variables, several common pitfalls emerge. The configuration you've shared shows a typical scenario where environment variables aren't properly expanded when Supervisor switches users.

The main problems in your setup appear to be:

1. Environment variables defined in [supervisord] section not propagating to child processes
2. Permission issues when switching users
3. Socket file accessibility problems

Here's a corrected version of your configuration that properly handles user switching and environment variables:

[program:hank-message-forwarder]
user = a-user-name
directory = /home/a-user-name
environment = 
    HOME='/home/a-user-name',
    APP='staging.example.com',
    SYMFONY_ENVIRONMENT='staging'
command = /bin/bash -c '${HOME}/apps/${APP}/current/bin/hank forward-messages tcp://*:5500 tcp://*:5600'
stdout_logfile = /var/log/pink-tie/%(program_name)s-out.log
stderr_logfile = /var/log/pink-tie/%(program_name)s-err.log

The critical changes that make this work:

  • Moved environment variables to the program section instead of global
  • Added explicit bash shell invocation to handle variable expansion
  • Set the working directory to avoid path issues

For the Unix socket permission issues, add this to your main config:

[unix_http_server]
file=/var/run/supervisor.sock
chmod=0770
chown=a-user-name:supervisor

After making these changes:

  1. Restart Supervisor: sudo service supervisor restart
  2. Check status: sudo supervisorctl status
  3. Verify environment: sudo supervisorctl tail hank-message-forwarder

For more complex scenarios, you might need to use sudo in the command:

command = sudo -u a-user-name -i /home/a-user-name/apps/staging.example.com/current/bin/hank forward-messages tcp://*:5500 tcp://*:5600

Remember to configure sudoers file appropriately for passwordless execution.