Self-hosted image hosting and photo album service.
1.1K
A self-hosted image hosting and photo album service with a resource-aware upload pipeline, fixed image variants, watermarking, private sharing, and compatibility for existing V1 images.
Early-release notice: V2 is still an early release. The upload protocol, browser processing pipeline, schema, compatibility behavior, and operational defaults may change frequently. Review every changelog, back up MySQL and the image volume, and pin an exact release tag or OCI index digest in production.
Documentation | V2.0.0 release notes | Docker Hub | GHCR
summeRain uses a modular Go monolith and a React single-page application. The
Go service exposes the /api/v1/* API, serves images under /i/*, and hosts
the compiled frontend from the same origin. MySQL is the authoritative store
for application and job state. Redis provides bounded caching, rate limiting,
view buffering, and device replay protection. imgproxy provides bounded V1
dynamic transformations and the optional V2 watermark stage.
Browser / Android / Windows
|
v
Go + Gin (:8080)
|-- /api/v1/* --> middleware --> handler --> service --> repository
|-- /i/*
| |-- V2 --> authorization --> fixed local assets
| `-- V1 --> stored asset or bounded imgproxy transform
|-- publish worker --> optional imgproxy watermark --> local publish asset
`-- /* --> backend/web (React SPA)
|
+------------+------------+
| | |
v v v
MySQL 8.4 Redis 8 local image volume
V2 moves the expensive decode, resize, format conversion, and compression work to the browser. The backend accepts fixed-recipe, manifest-declared WebP parts, validates them while streaming to staging storage, and promotes fixed variants without re-reading the upload solely for validation.
| Asset | Geometry | Quality | Lifecycle and use |
|---|---|---|---|
master | Original oriented dimensions | 80 | Persisted full-resolution WebP; owner/admin access |
gallery | 400x400 cover crop | 60 | Persisted My Images and dashboard preview |
admin | 120x160 cover crop | 60 | Persisted Image Management preview, displayed at 60x80 |
publish_source | Longest edge at most 2048 px | 80 | Temporary input for server-side publishing |
publish | Derived from publish_source | 80 | Persisted sharing asset with the optional watermark |
publish_source and session staging data are removed after publishing. The
server applies watermarks only to the final publish asset. V2 does not create
arbitrary sizes on first access, which avoids the unbounded thumbnail work that
made V1 vulnerable to hot-resource bursts.
wasm-vips; a bounded Canvas/Pica path is
used when the required browser isolation and memory capabilities are absent.master, gallery, and admin assets, plus a
revision-scoped publish asset.__Host-session_token plus a browser-readable,
server-backed __Host-csrf_token submitted through the CSRF request header./health, /ready, and /metrics operational endpoints.linux/amd64 and linux/arm64 images built only by GitHub
Actions and published to Docker Hub and GHCR.| Layer | Stack |
|---|---|
| Frontend | React 19, React Router 8, Vite 8, TypeScript 6, Tailwind CSS 4, shadcn/ui |
| Frontend data | TanStack Query 5, Zustand 5, React Hook Form 7, Zod 4 |
| Backend | Go, Gin, GORM, MySQL 8.4, Redis 8 |
| Image processing | wasm-vips, Pica, Web APIs, imgproxy 4 |
| Storage | Local V2 filesystem; Cloudflare R2 and compatible path-style S3 endpoints for V1 lineage |
| Testing | Go testing, Vitest, Testing Library, MSW |
Exact CI, service, and browser-processing versions are recorded in
requirements.lock. Go and npm dependency graphs are
locked by backend/go.sum and frontend/package-lock.json.
^20.19.0 || >=22.12.0. CI and container builds currently use
Node.js 24.18.0 LTS../scripts/dev-wsl.sh deps-up
This starts pinned MySQL, Redis, and imgproxy containers. It does not build the summeRain application image locally.
| Service | Default address |
|---|---|
| MySQL | 127.0.0.1:13306 |
| Redis | 127.0.0.1:16379 |
| imgproxy | 127.0.0.1:18081 |
The ports can be changed with SUMMERAIN_DEV_MYSQL_PORT,
SUMMERAIN_DEV_REDIS_PORT, and SUMMERAIN_DEV_IMGPROXY_PORT.
./scripts/dev-wsl.sh backend
The API listens on http://127.0.0.1:18080 by default. The first start applies
pending database migrations. Use SUMMERAIN_DEV_BACKEND_PORT to change the
port.
cd frontend
npm ci
cd ..
./scripts/dev-wsl.sh frontend
The development server uses https://127.0.0.1:5173 by default and proxies
/api/ and /i/ to the local backend. Accept the generated development
certificate on first use. HTTPS and same-origin proxying are required by the
__Host- session cookie.
Development enables COOP/COEP by default for the 50 MP wasm-vips path. Every third-party script, font, and image must therefore provide compatible CORS or Cross-Origin-Resource-Policy headers.
cd backend
go build ./...
go vet ./...
go test ./...
cd frontend
npm run lint
npm run build
npx vitest run
Application images are built by GitHub Actions. Production hosts should pull an
exact published tag or OCI index digest and must use --no-build.
cp backend/.env.example backend/.env
chmod 0600 backend/.env
# Edit backend/.env and set an exact DOCKER_IMAGE, database password,
# cookie secret, and imgproxy key/salt.
docker compose --env-file backend/.env \
-f backend/docker-compose.deploy.yml pull
docker compose --env-file backend/.env \
-f backend/docker-compose.deploy.yml up -d --no-build
Example stable image:
jaykserks/summerain:2.0.0
Published registries:
jaykserks/summerainghcr.io/kserksi/summerainUse the OCI multi-platform index digest when pinning by digest across
architectures. Do not reuse an architecture-specific child-manifest digest on
both amd64 and arm64 hosts.
See Deployment and Usage for the complete environment, nginx/CDN, health-check, upgrade, and rollback reference.
main publish edge and sha-<12-character-commit>.VERSION such as 2.0.0 publishes v2.0.0, 2.0.0, 2.0, 2,
latest, and the commit tag.2.1.0-rc.1 publishes exact version tags and the commit
tag without updating stable aliases.The full release contract is documented in Release and Tag Management.
The default Compose profile is designed for a 3-core, 4 GiB host shared with other services.
| Service | CPU limit | Memory limit |
|---|---|---|
| Backend | 0.75 CPU | 640 MiB |
| MySQL | 0.75 CPU | 1024 MiB |
| Redis | 0.15 CPU | 192 MiB |
| imgproxy | 0.70 CPU | 512 MiB |
The backend defaults to eight global and four per-user concurrent part uploads. MySQL and Redis pools are bounded. New V2 sessions are rejected at the default 80% disk soft limit, and new parts/publish outputs are rejected at the 90% hard limit. Reduce imgproxy and watermark workers from two to one when the host is under sustained contention.
These limits are a conservative starting point, not a universal capacity guarantee. Disk latency, database latency, watermark complexity, and colocated workloads affect throughput.
summeRain/
|-- backend/
| |-- cmd/server/ application entry point
| |-- internal/ handlers, services, repositories, workers
| |-- migrations/ versioned SQL migrations
| `-- web/ generated frontend build output
|-- frontend/
| |-- src/features/ domain-oriented application features
| |-- src/components/ shared UI and layout
| |-- src/lib/ API, CSRF, errors, and utilities
| |-- src/store/ user and theme state
| `-- src/i18n/ English, Chinese, and Japanese resources
|-- docs/ API, operations, releases, and architecture
|-- translations/ Simplified Chinese and Japanese documentation mirrors
|-- scripts/ development and repository verification
|-- .gitbook.yaml GitBook Git Sync configuration
`-- SUMMARY.md GitBook navigation
Backend requests follow this boundary:
request -> middleware -> handler -> service -> repository -> MySQL / Redis
`-> filesystem / R2 / imgproxy
The canonical online documentation is published at
summerain-1.gitbook.io/summerain.
All tracked project documentation is included in the GitBook navigation source
in SUMMARY.md. The primary references are:
English is the authoritative documentation language. Reviewable Simplified
Chinese and Japanese translations mirror the same page paths under
translations/zh-CN and translations/ja-JP. GitBook publishes them as
language variants of the same documentation site.
The repository is the source of truth for GitBook Git Sync. Manage README and navigation changes in Git rather than creating duplicate README pages in the GitBook editor.
master is a
full-resolution quality-80 WebP.Read CONTRIBUTING.md before opening a pull request and follow CODE_OF_CONDUCT.md in project spaces. Report security issues through the private process in SECURITY.md, not through a public issue. GitHub provides a private security advisory form for this repository.
Copyright 2026 The summeRain Authors
Licensed under the Apache License 2.0.
Content type
Image
Digest
sha256:b82269ce1…
Size
16.8 MB
Last updated
about 8 hours ago
docker pull jaykserks/summerain:dev-sha-79ca69577370