Add Hermes agent, self-host fonts, new blog post

- Add Hermes (Nous Research LLM agent) with Telegram gateway,
  Ansible provisioning, and Makefile targets
- Self-host JetBrains Mono and Spectral fonts (remove Google Fonts)
- Add "An Experiment in Self-Hosting" blog post
- Update CLAUDE.md with high-level server overview

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Louis Simoneau
2026-04-10 16:06:48 +10:00
parent ab050fddd7
commit 3a9e3a7916
19 changed files with 226 additions and 5 deletions

View File

@@ -24,6 +24,8 @@ monotrope.au {
path *.html / /posts/ /posts/*
}
header @html Cache-Control "public, max-age=0, must-revalidate"
}
# Redirect www to apex

View File

@@ -14,6 +14,9 @@
goatcounter_version: "2.7.0"
goatcounter_admin_email: "{{ lookup('env', 'GOATCOUNTER_ADMIN_EMAIL') }}"
goatcounter_admin_password: "{{ lookup('env', 'GOATCOUNTER_ADMIN_PASSWORD') }}"
hermes_openrouter_api_key: "{{ lookup('env', 'HERMES_OPENROUTER_API_KEY') }}"
hermes_telegram_bot_token: "{{ lookup('env', 'HERMES_TELEGRAM_BOT_TOKEN') }}"
hermes_telegram_allowed_users: "{{ lookup('env', 'HERMES_TELEGRAM_ALLOWED_USERS') }}"
tasks:
@@ -311,6 +314,55 @@
chdir: /opt/gitea
tags: gitea
# ── Hermes Agent ────────────────────────────────────────────────────────
- name: Create Hermes directory
file:
path: /opt/hermes
state: directory
owner: root
group: root
mode: '0750'
tags: hermes
- name: Copy Hermes docker-compose.yml
copy:
src: ../hermes/docker-compose.yml
dest: /opt/hermes/docker-compose.yml
owner: root
group: root
mode: '0640'
tags: hermes
- name: Copy Hermes config.yaml
copy:
src: ../hermes/config.yaml
dest: /opt/hermes/config.yaml
owner: root
group: root
mode: '0640'
notify: Restart Hermes
tags: hermes
- name: Write Hermes .env
copy:
dest: /opt/hermes/.env
owner: root
group: root
mode: '0600'
content: |
OPENROUTER_API_KEY={{ hermes_openrouter_api_key }}
TELEGRAM_BOT_TOKEN={{ hermes_telegram_bot_token }}
TELEGRAM_ALLOWED_USERS={{ hermes_telegram_allowed_users }}
no_log: true
tags: hermes
- name: Pull and start Hermes
command: docker compose up -d --pull always
args:
chdir: /opt/hermes
tags: hermes
# ── GoatCounter ─────────────────────────────────────────────────────────
- name: Create goatcounter system user
@@ -461,3 +513,8 @@
systemd:
name: fail2ban
state: restarted
- name: Restart Hermes
command: docker compose restart
args:
chdir: /opt/hermes

10
infra/hermes/config.yaml Normal file
View File

@@ -0,0 +1,10 @@
model:
provider: openrouter
default: openrouter/auto
memory:
memory_enabled: true
user_profile_enabled: true
agent:
max_turns: 70

View File

@@ -0,0 +1,23 @@
services:
hermes:
image: nousresearch/hermes-agent:latest
container_name: hermes
restart: unless-stopped
command: gateway run
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
volumes:
- hermes_data:/opt/data
- ./config.yaml:/opt/data/config.yaml:ro
environment:
OPENROUTER_API_KEY: "${OPENROUTER_API_KEY}"
TELEGRAM_BOT_TOKEN: "${TELEGRAM_BOT_TOKEN}"
TELEGRAM_ALLOWED_USERS: "${TELEGRAM_ALLOWED_USERS}"
env_file:
- .env
volumes:
hermes_data: