Single-page site with gallery by album and event, contact form over SMTP, Docker dev/prod setup, and on-server image derivatives. Gallery photos stay local (app/images/ is gitignored). Co-authored-by: Cursor <cursoragent@cursor.com>
3.1 KiB
Technical Kiwi Limited — Website
A small business site built with Go, templ (server-side HTML templates), and HTMX for gallery interactions.
Requirements
- Docker and Docker Compose
Quick start
cp .env.example .env # optional SMTP settings
make dev # live reload → http://localhost:7331
Make targets
| Target | Description |
|---|---|
make dev |
Dev with Air + templ browser live reload (default) |
make build |
Build production website image |
make up |
Run production website service |
make down |
Stop compose services |
make generate |
Run templ generate in dev container |
make tidy |
Run go mod tidy in dev container |
make logs |
Follow dev container logs |
Features
- Single-page layout: hero, services, gallery, contact
- Gallery loads via HTMX (
hx-get="/gallery") - Year filters without full page reload
- Lightbox modal with previous/next navigation
- Contact form with SMTP relay (HTMX submit, no page reload)
- Serves photos from
app/images/
Contact form (SMTP)
Set relay details in .env:
| Variable | Description |
|---|---|
SMTP_HOST |
Relay hostname (required) |
SMTP_PORT |
Port (default 587) |
SMTP_USER / SMTP_PASSWORD |
Auth if your relay requires it |
SMTP_FROM |
Envelope/header From address (required) |
SMTP_TO |
Where contact messages are delivered (required) |
SMTP_TLS |
auto, tls (465), or plain (25/local relay) |
If SMTP is not configured, the page shows a mailto fallback instead of the form.
Dev container
make dev mounts ./app and your host Go caches (~/go/pkg/mod, ~/.cache/go-build by default). Override with GOMODCACHE / GOCACHE in .env.
Use http://localhost:7331 in the browser — the templ proxy injects live reload on .templ, .go, and .css changes. Port 8080 hits the app directly without auto-reload.
Only run dev or website at a time if you map both to the same host ports.
Production website joins the external caddy Docker network for reverse proxy labels.
Project layout
app/
cmd/server/ HTTP server entrypoint
internal/gallery/ Scan and sort images from disk
internal/contact/ Form validation
internal/mail/ SMTP relay
internal/handlers/ Routes and HTMX partials
templates/ templ components (.templ → generated Go)
static/ CSS
images/ Gallery photos (served at /images/)
Dockerfile Production image
Dockerfile.dev Dev image (Go + templ + Air)
docker-compose.yaml
.env.example
Gallery images
On startup the server builds JPEG thumbnails in app/images/thumbs/ (max 480px edge) for the grid and hero. The lightbox still loads full-resolution originals. Thumbnails are gitignored and regenerated when source photos change.
Deploy notes
First request after deploy may take a moment while thumbnails are generated if they are not baked into the image yet.