mirror of
https://github.com/cole-maxwell1/todo-hetzner.git
synced 2026-10-27 19:02:49 -05:00
Implement the server-rendered Go todo application with PostgreSQL persistence, Tailwind styling, health checks, and test coverage. Provision production and staging infrastructure with OpenTofu, including private networking, static IPs, Object Storage backups, and load balancing. Configure Rocky Linux hosts with Ansible, rootless Podman, PostgreSQL, WAL-G backup automation, staging restores, and generated inventory.
4.7 KiB
4.7 KiB
AGENTS.md / OpenCode Execution Plan
1. Executive Summary & Objective
Build a complete, production-ready, highly maintainable infrastructure and web application stack:
- Infrastructure: OpenTofu configs deploying Rocky Linux 10 on Hetzner Cloud, isolated via private networking, configured with S3-compatible Hetzner Object Storage.
- App: Lightweight Go To-Do web app using native
html/template, xorm,and TailwindCSS, running via rootless Podman / systemd containers. - Database & Backups: PostgreSQL running on host/container, using
WAL-Gfor continuous archiving and hourly base backups to Hetzner Object Storage. - Staging Environment: Automated daily database sync (6:00 AM and 12:00 PM
America/Chicago) restoring production S3 state onto a separate Staging instance. - Scale Path: Pre-wired for future multi-instance app scaling behind a Hetzner Cloud Load Balancer.
2. Project Directory Structure
Generate the codebase using this strict layout:
.
├── infra/
│ ├── modules/
│ │ ├── compute/ # OpenTofu module for Rocky Linux instances
│ │ └── storage/ # OpenTofu module for Hetzner S3 bucket
│ ├── environments/
│ │ ├── prod/ # Production HCL configs
│ │ └── staging/ # Staging HCL configs
│ └── main.tf
├── ansible/
│ ├── playbooks/
│ │ ├── setup-node.yml # System setup, Podman, PostgreSQL, WAL-G installation
│ │ └── deploy-app.yml # Pull container & reload systemd unit
│ ├── roles/
│ └── templates/
│ ├── wal-g.env.j2 # Hetzner S3 credentials for WAL-G
│ ├── db-sync.service.j2
│ └── db-sync.timer.j2 # Systemd timer set for America/Chicago
├── app/
│ ├── cmd/
│ │ └── server/
│ │ └── main.go
│ ├── internal/
│ │ ├── db/ # Postgres connections & queries
│ │ ├── handler/ # HTTP handlers using html/template
│ │ └── model/ # Todo struct definitions
│ ├── web/
│ │ ├── templates/ # Go HTML templates
│ │ │ ├── layouts/
│ │ │ └── pages/
│ │ └── static/ # Compiled Tailwind CSS output
│ ├── Dockerfile # Multi-stage build for Go app + Tailwind CLI
│ ├── tailwind.config.js
│ ├── go.mod
│ └── Makefile
└── README.md
3. Component & Technical Specifications
A. Infrastructure (OpenTofu)
Use the official hetznercloud/hcloud provider.
Provision an hcloud_network (private subnet 10.0.1.0/24) and attach both Production and Staging instances.
Configure hcloud_primary_ip for static public IPv4/IPv6 assignment.
Include structural outputs for an hcloud_load_balancer to easily attach future app instances.
B. Application (Golang + TailwindCSS)
Standard library net/http router (or lightweight chi).
UI: Native html/template rendering Todo List operations (Create, Read, Toggle Complete, Delete).
Styling: Standalone TailwindCSS CLI integrated into a multi-stage Dockerfile (build CSS step -> Go build step -> minimal Scratch/Distroless image).
Database Driver: jackc/pgx/v5 targeting local PostgreSQL.
Service Management: App runs containerized via Podman and configured as a systemd user service (app-todo.service).
C. Database & Continuous Backups (Production)
Install PostgreSQL on the Rocky Linux instance.
Configure WAL streaming and continuous archiving using WAL-G.
Systemd service executes wal-g backup-push hourly, pushing binary base backups and WAL logs to Hetzner Object Storage (S3 API).
D. Automated Staging Restore Pipeline
Create a systemd timer on the Staging server configured explicitly for America/Chicago timezone:
db-sync.timer:
Ini, TOML
[Unit]
Description=Run DB Restore from S3 Hourly/Daily Snapshot
[Timer]
OnCalendar=*-*-* 06,12:00:00 America/Chicago
Persistent=true
[Install]
WantedBy=timers.target
db-sync.service Execution Steps:
systemctl stop app-todo
Execute wal-g backup-fetch LATEST onto PostgreSQL staging instance
Apply any necessary staging sanitization scripts
systemctl start app-todo
4. Execution Rules for OpenCode
Idiomatic Code: Write standard, strictly formatted Go code (gofmt).
Full Implementation: Do not use placeholder code (// TODO: implement later) inside Go handlers or Ansible templates. Generate complete, runnable files.
No External Framework Bloat: Keep dependencies minimal (xorm for database, standard library for templates/routing).
Shell Script Verification: Provide a Makefile in the root directory automation tasks: make build-app, make infra-plan, make deploy-ansible.