---
name: deploy-hermes-docker-profile
description: Deploy a Hermes agent inside a Docker container with a custom profile (e.g., 'mom'), configure API keys and Telegram bot, and run the gateway.
version: 1.0
author: Hermes Agent
license: MIT
---
# Deploy Hermes Agent in Docker with a Custom Profile

This skill outlines the steps to run Hermes Agent in a Docker container, create/initialize a profile (e.g., `mom`), configure required API keys (OpenRouter, Telegram Bot Token), and start the messaging gateway so the agent can communicate via Telegram.

## Prerequisites

- Docker installed and running on the host.
- A GitHub Personal Access Token (PAT) with `repo` scope if you plan to pull/push code (optional for just running the agent).
- OpenRouter API key (or another LLM provider key) – obtain from https://openrouter.ai/keys.
- Telegram Bot Token – obtain from @BotFather.
- Basic familiarity with the command line.

## Steps

### 1. Pull (or ensure) the Hermes Agent Docker image

The official image is `nousresearch/hermes-agent:latest`. If you have a custom image (e.g., built from a fork) or a locally built image named `hermes-agent`, use that instead.

```bash
docker pull nousresearch/hermes-agent:latest
```

### 2. Create a host directory for persistent data

Choose a directory on the host that will be mounted into the container to persist profiles, skills, config, and `.env` files.

```bash
HERMES_DATA=/opt/hermes-data   # adjust as needed
mkdir -p "$HERMES_DATA"
```

### 3. Run the container interactively to create the profile

Start a container with the data directory mounted. We’ll run it interactively so we can create the profile and then exit.

```bash
docker run -it \
  --name hermes-setup \
  -v "$HERMES_DATA":/root/.hermes \
  nousresearch/hermes-agent:latest \
  bash
```

You are now inside the container as root.

#### 3.1 Create the desired profile (if it doesn’t exist)

```bash
hermes profile create mom   # replace 'mom' with your profile name
```

This creates `/root/.hermes/profiles/mom/config.yaml` and a wrapper script at `/root/.local/bin/mom`.

#### 3.2 Exit the container (but keep it running if you prefer)

Press `Ctrl+D` or type `exit`. The container will stop because we didn’t use `-d`.  
If you want to keep it running for later steps, you could instead detach with `Ctrl+P Ctrl+Q`, but for simplicity we’ll restart it in the next step.

### 4. Configure the profile (API keys, Telegram bot, model)

Restart the container (or start a new one) with the same volume and run the profile‑specific setup wizard.

```bash
docker run -it \
  --name hermes-mom-setup \
  -v "$HERMES_DATA":/root/.hermes \
  nousresearch/hermes-agent:latest \
  mom setup
```

The wizard will prompt for:
- **Inference Provider** – choose `OpenRouter` (or another).
- **OpenRouter API Key** – paste your key.
- **Model** – e.g., `nvidia/nemotron-3-super-120b-a12b` or a free model like `meta-llama/llama-3-8b-instruct`.
- **Temperature** – `0.3` (or leave default).
- **System Prompt** – keep the existing one (it should already be copied from your source).
- **Tools** – leave default (includes google_sheets, translate, reminder, web_search, etc.).
- **Allowed Users** – if you want the bot to respond only to you, keep your Telegram ID; otherwise clear.
- **Telegram Bot Token** – paste the token from @BotFather.

After completing the wizard, the configuration is saved under `/root/.hermes/profiles/mom/` and the file `/root/.hermes/.env` (containing `OPENROUTER_API_KEY` and `TELEGRAM_BOT_TOKEN`).

### 5. Add the wrapper directory to PATH (important!)

The wrapper scripts (`mom`, `hermes`, etc.) are installed into `/root/.local/bin` inside the container, which is **not** in the default PATH. To use them easily, either:

- Use the full path: `/root/.local/bin/mom ...`
- Or add the directory to PATH for subsequent commands.

If you plan to run commands manually inside the container, you can export PATH:

```bash
export PATH="/root/.local/bin:$PATH"
```

Add this to your shell’s rc file (`~/.bashrc` or `~/.zshrc`) if you’ll be using the container frequently.

### 6. Start the Telegram gateway

Now start the agent’s gateway so it can listen for updates from Telegram.

```bash
docker run -d \
  --name hermes-mom \
  -v "$HERMES_DATA":/root/.hermes \
  -e PATH="/root/.local/bin:$PATH" \   # ensure PATH is set inside container
  nousresearch/hermes-agent:latest \
  mom gateway start
```

Explanation:
- `-d` runs the container in detached mode (background).
- The same volume mount ensures the profile and config persist.
- Setting `PATH` ensures the `mom` wrapper is found.
- The command `mom gateway start` launches the gateway process inside the container.

### 7. Verify the bot is working

- Find your bot in Telegram (username you gave @BotFather).
- Send a message, e.g., `Привет! Кто ты?`.
- The bot should reply using the system prompt and tools of the `mom` profile.

### 8. (Optional) View logs

To see what the gateway is doing:

```bash
docker logs -f hermes-mom
```

### 9. Stopping / Removing the container

When you need to stop:

```bash
docker stop hermes-mom
docker rm hermes-mom
```

If you want to keep the data for later reuse, simply leave the volume (`$HERMES_DATA`) intact; you can start a new container with the same mount and configuration.

## Troubleshooting

| Symptom | Likely Cause | Fix |
|---------|--------------|-----|
| `Command 'mom' not found` | PATH does not include `/root/.local/bin` | Add `export PATH="/root/.local/bin:$PATH"` before running commands, or use full path. |
| `Error: Profile 'mom' does not exist` | Profile not created or volume not mounted correctly | Ensure the volume mount points to the directory containing `.hermes`. Re‑run `hermes profile create mom` inside the container. |
| Agent does not respond in Telegram | Missing or incorrect `TELEGRAM_BOT_TOKEN` or `OPENROUTER_API_KEY` | Re‑run `mom setup` and verify the keys are correct. Check container logs for authentication errors. |
| `git push` fails when trying to update code from inside container | No GitHub credentials configured | Either mount your SSH keys or configure a Personal Access Token via `git config --global credential.helper store` and `git ls-remote ...` as described in the `github-pat-push` skill. |
| Container exits immediately after start | The command given (`mom gateway start`) may be failing due to missing config | Check logs with `docker logs <container>`; re‑run setup if needed. |

## 10. Backup (automatic, daily)

All important Hermes data lives in `/opt/hermes-data`. Back it up daily:

```bash
cat > /opt/backup-hermes.sh << 'EOF'
#!/bin/bash
set -e
DATE=$(date +%Y-%m-%d_%H%M)
BACKUP_DIR="/opt/backups"
mkdir -p "$BACKUP_DIR"
tar czf "$BACKUP_DIR/hermes-$DATE.tar.gz" -C /opt/hermes-data .
ls -t "$BACKUP_DIR"/hermes-*.tar.gz | tail -n +8 | xargs -r rm
echo "[$DATE] Backup done"
EOF
chmod +x /opt/backup-hermes.sh
(crontab -l 2>/dev/null; echo "0 3 * * * /opt/backup-hermes.sh >> /var/log/hermes-backup.log 2>&1") | crontab -
```

**Off-site backup** (Cloudflare R2 / Backblaze B2 free tier):
```bash
# Install rclone, configure remote, then append to backup script:
rclone copy "$BACKUP_DIR/hermes-$DATE.tar.gz" r2:hermes-backups/
```

## 11. Health monitoring (cron)

Auto-restart crashed containers + optional Telegram alert:
```bash
*/5 * * * * docker ps | grep -q hermes || (docker start hermes && curl -s "https://api.telegram.org/bot<TOKEN>/sendMessage?chat_id=<ID>&text=Hermes restarted" > /dev/null)
```

## 12. Server hardening (before exposing to internet)

```bash
# Firewall
ufw allow 22    # SSH
ufw allow 443   # HTTPS
ufw enable

# SSH: disable password auth
sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart sshd

# Create non-root user
adduser hermes && usermod -aG docker hermes
# Then run docker commands as that user
```

## Bare VPS vs Umbrel

| | **Bare VPS** | **Umbrel** |
|---|---|---|
| 💰 Cost | ~6€/mo VPS | VPS + Umbrel overhead |
| 🔄 Backup | One folder (`/opt/hermes-data`) | Complex, Umbrel-managed |
| 🛠 Control | Full | Limited to web UI |
| 🐳 Docker | Direct access | Through app store |
| ⚡ Speed | Max | Extra layers |

**Recommendation**: Bare VPS + Docker. Simpler, more control, easier to back up and debug.

## Notes

- All important Hermes data (profiles, skills, `.env`, memory) lives in the mounted volume. Back up that single directory and you're safe.
- If you prefer a fully immutable image with baked‑in configuration, you could create a custom Dockerfile that copies a pre‑configured `.hermes` directory and sets the appropriate `ENV` variables. However, the volume approach is more flexible for changing keys or profiles without rebuilding the image.
- The skill can be adapted for other profiles (e.g., `valentin`) by replacing `mom` with the desired profile name throughout.
- To push code changes (e.g., updating the Sailor.bar site) from inside the container, you can use the `github-pat-push` skill or configure git credentials as described in its troubleshooting section.

---