blumeops/CLAUDE.md
Erich Blume adf6f4fbe9 Add PostgreSQL and Miniflux services to tailnet (#16)
## Summary
- Add PostgreSQL 18 as a new service at `pg.tail8d86e.ts.net:5432`
- Add Miniflux RSS/Atom feed reader at `feed.tail8d86e.ts.net`
- Both services managed via homebrew/brew services
- Pulumi ACL tags added (tag:pg, tag:feed)
- Alloy log collection configured for both services
- Zettelkasten documentation updated

## Manual Setup Required

Before running ansible, the following steps are needed on indri:

### 1. Apply Pulumi tags
```bash
mise run tailnet-up
```
Then apply tags to indri in Tailscale admin console.

### 2. Create 1Password entries
- miniflux PostgreSQL user password
- miniflux admin password (for first run)

### 3. Set PostgreSQL user password (after ansible installs postgres)
```bash
ssh indri '/opt/homebrew/opt/postgresql@18/bin/psql -c "ALTER USER miniflux PASSWORD '\''your-password'\'';"'
```

### 4. Create password files on indri
```bash
ssh indri 'echo "your-db-password" > ~/.miniflux-db-password && chmod 600 ~/.miniflux-db-password'
ssh indri 'echo "your-admin-password" > ~/.miniflux-admin-password && chmod 600 ~/.miniflux-admin-password'
```

### 5. Create ~/.pgpass for borgmatic
```bash
ssh indri 'echo "localhost:5432:miniflux:miniflux:YOUR_PASSWORD" > ~/.pgpass && chmod 600 ~/.pgpass'
```

### 6. Run ansible with first-run admin creation
```bash
mise run provision-indri -- -e miniflux_create_admin=1
```

### 7. Update borgmatic config
Add to `~/.config/borgmatic/config.yaml` on indri:
```yaml
postgresql_databases:
    - name: miniflux
      hostname: localhost
      port: 5432
      username: miniflux
```

### 8. Cleanup after first run
```bash
ssh indri 'rm ~/.miniflux-admin-password'
```

## Test plan
- [ ] Run `mise run tailnet-up` and verify Pulumi changes
- [ ] Apply tags to indri in Tailscale admin
- [ ] Run `mise run provision-indri -- --check --diff` for dry run
- [ ] Run `mise run provision-indri -- -e miniflux_create_admin=1`
- [ ] Approve services in Tailscale admin
- [ ] Verify PostgreSQL: `ssh indri '/opt/homebrew/opt/postgresql@18/bin/pg_isready'`
- [ ] Verify Miniflux: `curl https://feed.tail8d86e.ts.net/healthcheck`
- [ ] Run `mise run indri-services-check`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: https://forge.tail8d86e.ts.net/eblume/blumeops/pulls/16
2026-01-16 12:30:20 -08:00

3.9 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

blumeops is Erich Blume's GitOps repository for personal infrastructure management, orchestrated via tailnet tail8d86e.ts.net.

Critical: This repository is published publicly at https://github.com/eblume/blumeops, so never include any secrets!

Documentation

Project documentation lives in the zettelkasten at ~/code/personal/zk. Read all blumeops documentation with:

mise run zk-docs -- --style=header --color=never --decorations=always

This displays all cards tagged blumeops, with the main project card first and filenames shown for each card.

You are encouraged to explore the zk, follow links, and propose updates to it as the project evolves. Always keep the zettelkasten documentation up to date with any changes you make.

Note: The zettelkasten is synced via Obsidian Sync, not git. You don't need to commit or push zk changes.

Rules for all sessions

  1. Always start by reading the zk docs with the command above.
  2. Expand and correct the cards of the zettelkasten.
  3. Use Brewfile and mise.toml to install tools.
  4. Use brew services or Launch Agents to control services on macos hosts.
  5. Test all changes before applying them - ie with ansible, use a --check --diff run.

Task Discovery

To discover pending blumeops tasks, run:

mise run blumeops-tasks

This fetches tasks from the "Blumeops" project in Todoist (via 1Password for API credentials) and displays them sorted by priority: p1 (urgent), p2 (high), p4 (normal/default), p3 (backlog). The typical workflow is to pick a task from this list at the start of a session, then dive in with planning.

Remote Hosts

This repo is typically edited from a workstation (e.g., gilbert), but services run on remote hosts in the tailnet. Use SSH to explore or check state on remote machines:

# Explore config paths on indri
ssh indri 'ls -la /opt/homebrew/etc/grafana/'

# Check service status
ssh indri 'brew services list'

Key hosts:

  • indri - Mac Mini M1 running services (prometheus, grafana, kiwix, forgejo, borgmatic)
  • sifaka - Synology NAS (backup target)

Git Workflow

Use feature branches for all changes. Do not commit directly to main. Commit often while working to preserve progress.

IMPORTANT: Always create feature branches from main to avoid including unrelated commits:

# Always start from main
git checkout main
git pull

# Create a feature branch
git checkout -b feature/description-of-change

# Make changes, then commit
git add -A
git commit -m "Description of change"

# Push and create PR using tea CLI
git push -u origin feature/description-of-change
tea pr create --title "Description of change" --description "$(cat <<'EOF'
## Summary
- First change
- Second change

## Test plan
- [x] Tested thing one
- [ ] Need to test thing two

🤖 Generated with [Claude Code](https://claude.com/claude-code)
EOF
)"

Note: tea uses --description (not --body like gh). Other useful flags:

  • --base <branch> - target branch (default: repo's default branch)
  • --assignees <user> - assign reviewers
  • --labels <label> - add labels

PRs are reviewed and merged via the Forgejo web UI at https://forge.tail8d86e.ts.net.

After creating a PR, run open <pr-url> to open it in the browser (Claude Code's UI will prompt for permission).

Ansible

# Install collection dependencies
ansible-galaxy collection install -r ansible/requirements.yml

# Dry-run before committing changes
mise run provision-indri -- --check --diff

# Apply changes
mise run provision-indri

Service Health Checks

After making changes to services, run the service health check to verify everything is working:

mise run indri-services-check

This checks that all indri services (prometheus, grafana, kiwix, transmission, forgejo) are running and responding to health checks.