如何在supervisord中设置环境变量?KMS解密命令配置异常问题
Hey there, I see the issue you're running into—your AWS KMS decrypt command works fine on its own and your environment variables are correctly passed to the container, but it breaks when put into supervisord's config. Let's break down why this happens and how to fix it.
The Root Cause
By default, supervisord doesn't execute your command using a shell. That means shell-specific features like $() command substitution, pipes (|), process substitution (<()), and even variable expansion syntax won't get parsed correctly. When you run the command manually, your shell handles all these bits, but supervisord just tries to run the command directly as an executable with arguments, which fails because those syntax elements aren't valid arguments for the export command.
Solution 1: Wrap the Command in a Shell
You can explicitly tell supervisord to run your command via a shell (like bash) using bash -c. You'll need to handle quoting properly to make sure supervisord passes the full command to the shell correctly.
Here's how to adjust your config:
[program:decrypt] command=bash -c "export KEYTOKEN=\$(aws kms decrypt --ciphertext-blob fileb://<(echo %(ENV_TOKENENC)s | base64 -d) --output text --query Plaintext --region %(ENV_REGION)s | base64 -d )"
- The
bash -ctells supervisord to launch bash and pass the quoted string as the command to execute. - We escape the
$in$()with a backslash (\$()) to prevent supervisord from trying to parse it as a variable before passing it to bash. - We keep using
%(ENV_TOKENENC)sand%(ENV_REGION)sso supervisord injects the environment variables correctly before passing the command to bash.
Alternatively, you can use single quotes and skip escaping $(), but then you'll need to use direct shell variable references instead of supervisord's %(ENV_...)s syntax:
[program:decrypt] command=bash -c 'export KEYTOKEN=$(aws kms decrypt --ciphertext-blob fileb://<(echo $ENV_TOKENENC | base64 -d) --output text --query Plaintext --region $ENV_REGION | base64 -d )'
This works because single quotes prevent supervisord from expanding the variables, letting bash handle them directly (since you've already confirmed the variables are present in the container's environment).
Solution 2: Use a Separate Shell Script
For more complex commands, it's often cleaner to move the logic into a dedicated shell script. This avoids quoting headaches and makes the config easier to read.
- Create a script (e.g.,
/opt/scripts/decrypt.sh) with your command:
#!/bin/bash export KEYTOKEN=$(aws kms decrypt --ciphertext-blob fileb://<(echo $ENV_TOKENENC | base64 -d) --output text --query Plaintext --region $ENV_REGION | base64 -d ) # If you need to run additional commands after setting KEYTOKEN, add them here
- Make the script executable:
chmod +x /opt/scripts/decrypt.sh
- Update your supervisord config to run the script:
[program:decrypt] command=/opt/scripts/decrypt.sh
This method is more maintainable, especially if you ever need to modify the decrypt logic later.
Verify the Fix
After updating the config, restart supervisord in your container to apply the changes. You can check the supervisord logs to confirm the command runs successfully, or verify that KEYTOKEN is set in the context of the process managed by supervisord.
内容的提问来源于stack exchange,提问作者Rob

