Document and add multi-bot Docker workflows with env layering scripts, and update agent/tool configuration handling to make MCP/email/calendar behavior more robust for day-to-day operations. Made-with: Cursor
5.8 KiB
Using Separate Env Files Per Container
This guide shows you how to use separate .env files for each bot container, making it easy to manage both shared and bot-specific settings.
How It Works
Docker Compose loads env_file entries in order. Later files override earlier ones:
.env.shared- Loaded first, contains common settings.env.user1,.env.user2,.env.user3- Loaded after, can override shared settings
This means:
- ✅ Shared settings go in
.env.shared(update once) - ✅ Bot-specific overrides go in
.env.user1,.env.user2, etc. (only if needed) - ✅ Easy to edit (plain text files, no JSON)
Quick Setup
Step 1: Create Env Files
Run the setup script:
chmod +x env-files-setup.sh
./env-files-setup.sh
This creates:
.env.shared- Shared settings for all bots.env.user1- Overrides for bot 1 (optional).env.user2- Overrides for bot 2 (optional).env.user3- Overrides for bot 3 (optional)
Step 2: Edit .env.shared
Edit .env.shared with your shared settings:
# Shared configuration for all nanobot instances
NANOBOT_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-your-actual-key
NANOBOT_AGENTS__DEFAULTS__MODEL=anthropic/claude-opus-4-5
NANOBOT_AGENTS__DEFAULTS__TEMPERATURE=0.7
NANOBOT_AGENTS__DEFAULTS__MAX_TOKENS=8192
Step 3: Edit Bot-Specific Files (Optional)
If a bot needs different settings, edit its .env.userX file:
.env.user1 (example - override model for bot 1):
# Override model for this bot only
NANOBOT_AGENTS__DEFAULTS__MODEL=anthropic/claude-sonnet-4
.env.user2 (example - override temperature):
# Override temperature for this bot only
NANOBOT_AGENTS__DEFAULTS__TEMPERATURE=0.9
.env.user3 (example - leave empty to use all shared settings):
# This bot uses all settings from .env.shared
# No overrides needed
Step 4: Create Minimal Config Files
Each bot still needs a minimal config.json with bot-specific channel settings:
~/.nanobot-user1/config.json:
{
"channels": {
"telegram": {
"enabled": true,
"token": "BOT_TOKEN_FOR_USER1",
"allowFrom": ["USER1_TELEGRAM_ID"]
}
}
}
~/.nanobot-user2/config.json:
{
"channels": {
"telegram": {
"enabled": true,
"token": "BOT_TOKEN_FOR_USER2",
"allowFrom": ["USER2_TELEGRAM_ID"]
}
}
}
Step 5: Run with Docker Compose
docker compose -f docker-compose.multi.env.yml up -d
File Structure
nanobot/
├── .env.shared ← Shared settings (API keys, model, etc.)
├── .env.user1 ← Bot 1 overrides (optional)
├── .env.user2 ← Bot 2 overrides (optional)
├── .env.user3 ← Bot 3 overrides (optional)
├── docker-compose.multi.env.yml
│
└── ~/.nanobot-user1/
└── config.json ← Bot 1 channel config (Telegram token, user ID)
└── ~/.nanobot-user2/
└── config.json ← Bot 2 channel config
└── ~/.nanobot-user3/
└── config.json ← Bot 3 channel config
Examples
Example 1: All Bots Use Same Settings
.env.shared:
NANOBOT_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-xxx
NANOBOT_AGENTS__DEFAULTS__MODEL=anthropic/claude-opus-4-5
.env.user1, .env.user2, .env.user3:
# Empty - all bots use shared settings
Example 2: One Bot Uses Different Model
.env.shared:
NANOBOT_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-xxx
NANOBOT_AGENTS__DEFAULTS__MODEL=anthropic/claude-opus-4-5
.env.user1:
# Bot 1 uses a different model
NANOBOT_AGENTS__DEFAULTS__MODEL=anthropic/claude-sonnet-4
.env.user2, .env.user3:
# Empty - use shared model
Example 3: One Bot Uses Different API Key
.env.shared:
NANOBOT_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-shared-key
NANOBOT_AGENTS__DEFAULTS__MODEL=anthropic/claude-opus-4-5
.env.user2:
# Bot 2 uses its own API key
NANOBOT_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-user2-key
Updating Settings
Update Shared Settings
Edit .env.shared and restart all containers:
# Edit shared settings
nano .env.shared
# Restart all bots
docker compose -f docker-compose.multi.env.yml restart
Update Bot-Specific Settings
Edit the specific .env.userX file and restart that bot:
# Edit bot 1's settings
nano .env.user1
# Restart only bot 1
docker restart nanobot-user1
Environment Variable Format
Nanobot uses Pydantic's BaseSettings with:
- Prefix:
NANOBOT_ - Nested delimiter:
__(double underscore)
Examples:
NANOBOT_PROVIDERS__OPENROUTER__API_KEY→providers.openrouter.apiKeyNANOBOT_AGENTS__DEFAULTS__MODEL→agents.defaults.modelNANOBOT_AGENTS__DEFAULTS__TEMPERATURE→agents.defaults.temperature
Advantages
✅ Easy to edit - Plain text files, no JSON syntax
✅ Clear separation - Shared vs bot-specific settings
✅ Flexible - Override only what you need
✅ Version control friendly - Can commit .env.shared, ignore .env.userX if they contain secrets
✅ No config.json editing - Only edit env files for most changes
Troubleshooting
Settings Not Applied
-
Check if env files exist:
ls -la .env.* -
Check what's loaded in container:
docker exec nanobot-user1 env | grep NANOBOT -
Restart container after changes:
docker restart nanobot-user1
Override Not Working
Remember: Later files override earlier ones. If .env.user1 has a setting but it's not applied, check:
- Is the variable name correct? (use
__not.) - Did you restart the container?
- Is the setting in
.env.sharedoverriding it? (remove from.env.sharedif you want bot-specific only)