Files
swarm-master/ansible/AGENTS.md
William Valentin aceeb7b542 Initial commit — OpenClaw VM infrastructure
- ansible/: VM provisioning playbooks and roles
  - provision-vm.yml: create KVM VM from Ubuntu cloud image
  - install.yml: install OpenClaw on guest (upstream)
  - customize.yml: swappiness, virtiofs fstab, linger
  - roles/vm/: libvirt domain XML, cloud-init templates
  - inventory.yml + host_vars/zap.yml: zap instance config
- backup-openclaw-vm.sh: daily rsync + MinIO upload
- restore-openclaw-vm.sh: full redeploy from scratch
- README.md: full operational documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:18:31 -07:00

190 lines
5.6 KiB
Markdown

# Agent Guidelines
## Project Overview
Ansible playbook for automated, hardened OpenClaw installation on Debian/Ubuntu systems.
## Key Principles
1. **Security First**: Firewall must be configured before Docker installation
2. **One Command Install**: `curl | bash` should work out of the box
3. **Localhost Only**: All container ports bind to 127.0.0.1
4. **Defense in Depth**: UFW + DOCKER-USER + localhost binding + non-root container
## Critical Components
### Task Order
Docker must be installed **before** firewall configuration.
Task order in `roles/openclaw/tasks/main.yml`:
```yaml
- tailscale.yml # VPN setup
- user.yml # Create system user
- docker.yml # Install Docker (creates /etc/docker)
- firewall.yml # Configure UFW + daemon.json (needs /etc/docker to exist)
- nodejs.yml # Node.js + pnpm
- openclaw.yml # Container setup
```
Reason: `firewall.yml` writes `/etc/docker/daemon.json` and restarts Docker service.
### DOCKER-USER Chain
Located in `/etc/ufw/after.rules`. Uses dynamic interface detection (not hardcoded `eth0`).
**Never** use `iptables: false` in Docker daemon config - this would break container networking.
### Port Binding
Always use `127.0.0.1:HOST_PORT:CONTAINER_PORT` in docker-compose.yml, never `HOST_PORT:CONTAINER_PORT`.
## Code Style
### Ansible
- Use loops instead of repeated tasks
- No `become_user` (playbook already runs as root)
- Use `community.docker.docker_compose_v2` (not deprecated `docker_compose`)
- Always specify collections in `requirements.yml`
### Docker
- Multi-stage builds if needed
- USER directive for non-root
- Proper healthchecks (test the app, not just Node)
- Use `docker compose` (V2) not `docker-compose` (V1)
- No `version:` in compose files
### Templates
- Use variables for all paths/ports
- Add comments explaining security decisions
- Keep jinja2 logic simple
## Testing Checklist
Before committing changes:
```bash
# 1. Syntax check
ansible-playbook playbook.yml --syntax-check
# 2. Dry run
ansible-playbook playbook.yml --check
# 3. Full install (on test VM)
curl -fsSL https://raw.githubusercontent.com/.../install.sh | bash
# 4. Verify security
sudo ufw status verbose
sudo iptables -L DOCKER-USER -n
sudo ss -tlnp # Only SSH + localhost should listen
# 5. External port scan
nmap -p- TEST_SERVER_IP # Only port 22 should be open
# 6. Test isolation
sudo docker run -p 80:80 nginx
curl http://TEST_SERVER_IP:80 # Should fail
curl http://localhost:80 # Should work
```
## Common Mistakes to Avoid
1. ❌ Installing Docker before configuring firewall
2. ❌ Using `0.0.0.0` port binding
3. ❌ Hardcoding network interface names (use dynamic detection)
4. ❌ Setting `iptables: false` in Docker daemon
5. ❌ Running container as root
6. ❌ Using deprecated `docker-compose` (V1)
7. ❌ Forgetting to add collections to requirements.yml
## Documentation
### User-Facing
- **README.md**: Installation, quick start, basic management
- **docs/**: Technical details, architecture, troubleshooting
### Developer-Facing
- **AGENTS.md**: This file - guidelines for AI agents/contributors
- Code comments: Explain *why*, not *what*
Keep docs concise. No progress logs, no refactoring summaries.
## File Locations
### Host System
```
/opt/openclaw/ # Installation files
/home/openclaw/.openclaw/ # Config and data
/etc/systemd/system/openclaw.service
/etc/docker/daemon.json
/etc/ufw/after.rules
```
### Repository
```
roles/openclaw/
├── tasks/ # Ansible tasks (order matters!)
├── templates/ # Jinja2 configs
├── defaults/ # Variables
└── handlers/ # Service restart handlers
docs/ # Technical documentation (frontmatter format)
requirements.yml # Ansible Galaxy collections
```
## Security Notes
### Why UFW + DOCKER-USER?
Docker bypasses UFW by default. DOCKER-USER chain is evaluated first, allowing us to block before Docker sees the traffic.
### Why Fail2ban?
SSH is exposed to the internet. Fail2ban automatically bans IPs after 5 failed attempts for 1 hour.
### Why Unattended-Upgrades?
Security patches should be applied promptly. Automatic security-only updates reduce vulnerability windows.
### Why Scoped Sudo?
The openclaw user only needs to manage its own service and Tailscale. Full root access would be dangerous if the app is compromised.
### Why Localhost Binding?
Defense in depth. If DOCKER-USER fails, localhost binding prevents external access.
### Why Non-Root Container?
Least privilege. Limits damage if container is compromised.
### Why Systemd?
Clean lifecycle, auto-start, logging integration.
### Known Limitations
- **macOS**: Incomplete support (no launchd, basic firewall). Test thoroughly.
- **IPv6**: Disabled in Docker. Review if your network uses IPv6.
- **curl | bash**: Inherent risks. For production, clone and audit first.
## Making Changes
### Adding a New Task
1. Add to appropriate file in `roles/openclaw/tasks/`
2. Update main.yml if new task file
3. Test with `--check` first
4. Verify idempotency (can run multiple times safely)
### Changing Firewall Rules
1. Test on disposable VM first
2. Always keep SSH accessible
3. Update `docs/security.md` with changes
4. Verify with external port scan
### Updating Docker Config
1. Changes to `daemon.json.j2` trigger Docker restart (via handler)
2. Test container networking after restart
3. Verify DOCKER-USER chain still works
## Version Management
- Use semantic versioning for releases
- Tag releases in git
- Update CHANGELOG.md with user-facing changes
- No version numbers in code (use git tags)
## Support Channels
- OpenClaw issues: https://github.com/openclaw/openclaw
- This installer: https://github.com/openclaw/openclaw-ansible