Architecture
This page shows, in one overview diagram, how go-image-server layers edge caches, the Go service, libvips, and file storage.
System Overview
graph TB
Client[Client] --> Browser[Browser Cache]
Browser --> Worker[Cloudflare Worker]
Browser --> Nginx[Nginx proxy_cache]
Worker --> Nginx
Nginx --> Gin[Gin routes]
Gin --> Get[GetFromPath]
Gin --> Post[PostToPath]
Gin --> Del[DeleteFromPath]
Get --> Vips[libvips govips]
Get --> Cache[(storage/image/cache)]
Get --> Upload[(storage/image/upload)]
Post --> Upload
Del --> Trash[(upload/.trash/YYYY-MM-DD)]
Layers
| Layer | Location | Responsibility |
|---|---|---|
| Edge | worker/index.js |
Caches images for 7 days keyed by the full URL including query |
| Reverse proxy | config/nginx/nodes.conf |
/c/img/ caching, upload / delete forwarding, security headers |
| Routing | app/internal/routes/ |
SetGET / SetPOST / SetDELETE register endpoints; Set404 handles unknown paths |
| Handlers | app/internal/handlers/ |
Read and transform, upload, move to trash |
| Config | app/internal/configs/config.go |
Environment variables and storage paths |
| Utilities | app/internal/utils/ |
Query alias lookup, error responses |
Cross-Cutting Principles
| Principle | Implementation |
|---|---|
| 30-second cap per request | All three handlers wrap a goroutine in context.WithTimeout and return 408 timed out on expiry |
| Parameters are the cache key | Local cache filenames concatenate size, quality, blur, brightness, and format parameters |
| Delete means move | Deletion always os.Renames into the date-bucketed .trash |
| Streamed output | Images go out with chunked transfer and a buffer sized by file size |
Further Reading
- Full module-level diagrams (per-handler flows, data-flow sequence): doc/architecture.md
- Four-layer cache details: Caching Layers
- Transform flow: Image Pipeline