Production-oriented Go web application template built on the Modern Go Stack: Echo, Templ, HTMX, SQLC, PostgreSQL, and Mage. It is designed for teams that want strong defaults for security, maintainability, and fast iteration without a heavy frontend framework.
- Linux, macOS, or WSL2 (recommended). Native Windows PowerShell is not the primary target because Mage tasks use Unix utilities like
which. - Go 1.25+
- PostgreSQL 15+
- Node.js + npm (for Tailwind build)
- Atlas CLI
- Mage (
go install github.com/magefile/mage@latest)
git clone https://github.com/dunamismax/go-web-server.git
cd go-web-server
cp .env.example .envEdit .env with real database credentials (at minimum DATABASE_USER, DATABASE_PASSWORD, or a full DATABASE_URL).
sudo -u postgres createuser -P gowebserver
sudo -u postgres createdb -O gowebserver gowebservermage setup
mage generatemage migratemage devOpen http://localhost:8080.
Expected results:
- Home page loads with HTMX-enabled UI
GET /healthreturns JSON health data- Login and registration routes are available at
/auth/loginand/auth/register
- Fast server-rendered UX with HTMX, no SPA complexity required
- Type-safe database and template workflow (SQLC + Templ)
- Session authentication with Argon2id password hashing
- Security middleware included by default (CSRF, sanitization, headers, rate limiting)
- Single-binary deployment with embedded static assets
- Practical build and quality automation through Mage
- Web stack: Echo v4 + Templ + HTMX + Tailwind + DaisyUI
- Data layer: PostgreSQL + pgx/v5 + SQLC generated queries
- Auth model: Session-based auth using
scswith PostgreSQL-backed sessions - Security controls: CSRF protection, input sanitization, strict security headers, request IDs, structured errors
- Ops readiness: graceful shutdown, systemd service, deployment scripts, structured logging with
slog - Dev workflow: hot reload with Air, code generation, linting, vulnerability checks
| Layer | Technology | Purpose |
|---|---|---|
| Language | Go 1.25+ | Application runtime |
| HTTP | Echo v4 | Routing and middleware |
| Templates | Templ | Type-safe server-rendered UI |
| Frontend behavior | HTMX 2.x | Progressive dynamic interactions |
| CSS | Tailwind CSS + DaisyUI | Styling and components |
| Database | PostgreSQL | Relational storage |
| DB driver | pgx/v5 | High-performance PostgreSQL driver |
| Query generation | SQLC | Compile-time safe SQL access |
| Auth/session | scs + pgxstore + Argon2id | Secure session auth and password hashing |
| Config | Koanf | Defaults + .env + file + env layering |
| Migrations | Atlas | Declarative schema migration workflow |
| Build/dev tooling | Mage + Air | Automation and hot reload |
go-web-server/
├── cmd/web/ # Entry point
├── internal/
│ ├── config/ # Configuration loading (Koanf)
│ ├── handler/ # HTTP handlers and route registration
│ ├── middleware/ # CSRF, auth, sanitization, error handling
│ ├── store/ # SQLC queries, schema, and DB store
│ ├── ui/ # Embedded static assets
│ └── view/ # Templ components/pages
├── migrations/ # Atlas migrations used by mage migrate
├── docs/ # Development, API, architecture, deployment docs
├── scripts/ # systemd service and deployment scripts
├── magefile.go # Build/dev/quality command definitions
├── sqlc.yaml # SQLC configuration
├── atlas.hcl # Atlas configuration
└── .env.example # Environment template
mage dev # Run with hot reload
mage generate # Regenerate SQLC + Templ + CSS
mage quality # vet + lint + vulncheck
mage build # Build production binary (bin/server)
mage ci # generate + fmt + quality + buildmage helpmage clean # Remove build artifacts and temp outputs
mage reset # Clean + regenerate + migrate for a fresh local stateRuntime config is loaded in this order:
- Built-in defaults
.env(if present)config.yaml/config.yml(optional)- Environment variables
Important settings (.env):
APP_ENVIRONMENT=development
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_LOG_FORMAT=text
SERVER_PORT=8080
DATABASE_URL=postgres://username:password@localhost:5432/gowebserver?sslmode=disable
# or use DATABASE_USER / DATABASE_PASSWORD / DATABASE_HOST / DATABASE_PORT / DATABASE_NAME
AUTH_COOKIE_NAME=auth_token
AUTH_COOKIE_SECURE=falseFor production, set:
APP_ENVIRONMENT=productionAPP_DEBUG=falseAUTH_COOKIE_SECURE=true- restrictive
SECURITY_ALLOWED_ORIGINS
Core routes currently registered:
GET /home pageGET /demoHTMX demo endpointGET /healthhealth checkGET|POST /auth/loginloginGET|POST /auth/registerregistrationPOST /auth/logoutlogoutGET /profileauthenticated profile pageGET|POST|PUT|PATCH|DELETE /users...user CRUD endpointsGET /api/users/countAPI example endpoint
Implemented in current codebase:
- Session-based authentication (
scs) with PostgreSQL session store - Argon2id password hashing
- CSRF middleware on state-changing requests
- Input sanitization middleware
- Security headers + CORS + rate limiting
- Structured error responses and request correlation IDs
Operational note:
/profileis authenticated.- The
/usersCRUD routes are currently not wrapped by auth middleware by default. Restrict these routes before internet-facing production deployment.
mage build
sudo ./scripts/deploy.shscripts/deploy.sh installs to /opt/gowebserver, copies .env, installs scripts/gowebserver.service, and restarts the service.
mage build
sudo cp bin/server /opt/gowebserver/bin/
sudo cp scripts/gowebserver.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable gowebserver
sudo systemctl restart gowebserver
sudo systemctl status gowebserver- Documentation Index
- Development Guide
- API Reference
- Architecture
- Security Guide
- Deployment Guide
- Ubuntu Deployment Guide
- Some docs still mention legacy JWT terminology; runtime auth in this codebase is session-based.
- Feature flags for metrics/pprof exist in config, but dedicated production endpoints are not fully wired in current routes.
- Fork repository
- Create a focused branch
- Run
mage quality - Open a pull request with clear implementation notes
Licensed under the MIT License.
