# 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:

1. **`.env.shared`** - Loaded first, contains common settings
2. **`.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:

```bash
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:

```bash
# 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):
```bash
# Override model for this bot only
NANOBOT_AGENTS__DEFAULTS__MODEL=anthropic/claude-sonnet-4
```

**`.env.user2`** (example - override temperature):
```bash
# Override temperature for this bot only
NANOBOT_AGENTS__DEFAULTS__TEMPERATURE=0.9
```

**`.env.user3`** (example - leave empty to use all shared settings):
```bash
# 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`**:
```json
{
  "channels": {
    "telegram": {
      "enabled": true,
      "token": "BOT_TOKEN_FOR_USER1",
      "allowFrom": ["USER1_TELEGRAM_ID"]
    }
  }
}
```

**`~/.nanobot-user2/config.json`**:
```json
{
  "channels": {
    "telegram": {
      "enabled": true,
      "token": "BOT_TOKEN_FOR_USER2",
      "allowFrom": ["USER2_TELEGRAM_ID"]
    }
  }
}
```

### Step 5: Run with Docker Compose

```bash
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`**:
```bash
NANOBOT_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-xxx
NANOBOT_AGENTS__DEFAULTS__MODEL=anthropic/claude-opus-4-5
```

**`.env.user1`**, **`.env.user2`**, **`.env.user3`**:
```bash
# Empty - all bots use shared settings
```

### Example 2: One Bot Uses Different Model

**`.env.shared`**:
```bash
NANOBOT_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-xxx
NANOBOT_AGENTS__DEFAULTS__MODEL=anthropic/claude-opus-4-5
```

**`.env.user1`**:
```bash
# Bot 1 uses a different model
NANOBOT_AGENTS__DEFAULTS__MODEL=anthropic/claude-sonnet-4
```

**`.env.user2`**, **`.env.user3`**:
```bash
# Empty - use shared model
```

### Example 3: One Bot Uses Different API Key

**`.env.shared`**:
```bash
NANOBOT_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-shared-key
NANOBOT_AGENTS__DEFAULTS__MODEL=anthropic/claude-opus-4-5
```

**`.env.user2`**:
```bash
# 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:

```bash
# 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:

```bash
# 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.apiKey`
- `NANOBOT_AGENTS__DEFAULTS__MODEL` → `agents.defaults.model`
- `NANOBOT_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

1. Check if env files exist:
   ```bash
   ls -la .env.*
   ```

2. Check what's loaded in container:
   ```bash
   docker exec nanobot-user1 env | grep NANOBOT
   ```

3. Restart container after changes:
   ```bash
   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.shared` overriding it? (remove from `.env.shared` if you want bot-specific only)


