docs(project): add README with reverse-proxy and quick-start guide
Root README covering the stack, quick start, and dev commands, plus a Reverse proxy (nginx) section: client_max_body_size for large uploads, forwarded headers feeding the rate limiter, and buffering-off for streaming large media. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
# Tanabata File Manager
|
||||
|
||||
A multi-user, tag-based web file manager for images and video. Go + Gin backend
|
||||
(Clean Architecture, pgx, goose migrations), SvelteKit SPA frontend, PostgreSQL,
|
||||
JWT auth — shipped as a single Docker image that serves both the API and the
|
||||
built SPA on one port.
|
||||
|
||||
## Documentation
|
||||
|
||||
- [`openapi.yaml`](openapi.yaml) — full REST API specification
|
||||
- [`docs/DEPLOY.md`](docs/DEPLOY.md) — production deploy (Gitea Actions → host)
|
||||
- [`docs/GO_PROJECT_STRUCTURE.md`](docs/GO_PROJECT_STRUCTURE.md) — backend architecture
|
||||
- [`docs/FRONTEND_STRUCTURE.md`](docs/FRONTEND_STRUCTURE.md) — frontend architecture
|
||||
- [`.env.example`](.env.example) — every configuration variable, documented
|
||||
|
||||
## Quick start
|
||||
|
||||
```bash
|
||||
cp .env.example .env # then edit the secrets (JWT_SECRET, ADMIN_PASSWORD, …)
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
By default this runs the app plus a bundled PostgreSQL container
|
||||
(`COMPOSE_PROFILES=with-db`). To point at a Postgres already on the host, set
|
||||
`COMPOSE_PROFILES=` empty and aim `DATABASE_URL` at `host.docker.internal`. See
|
||||
[`.env.example`](.env.example) for the full matrix.
|
||||
|
||||
The app is published on **127.0.0.1** only and expects a reverse proxy in front
|
||||
(see below). The default port is **42776** — the sum of the Unicode code points
|
||||
of 七夕.
|
||||
|
||||
## Reverse proxy (nginx)
|
||||
|
||||
The container publishes its port on loopback (`127.0.0.1:${APP_PORT}:42776` in
|
||||
[`docker-compose.yml`](docker-compose.yml)), so a reverse proxy on the host
|
||||
terminates TLS and forwards to it. Three settings matter for this app:
|
||||
|
||||
1. **`client_max_body_size`** — uploads go up to `MAX_UPLOAD_BYTES` (500 MiB by
|
||||
default). nginx caps request bodies at **1 MiB** out of the box, so without
|
||||
this every large upload fails with `413`.
|
||||
2. **Forwarded headers** — the app trusts `X-Forwarded-For` only from the hops in
|
||||
`TRUSTED_PROXIES` (default: loopback + Docker bridge ranges) and keys its
|
||||
login/refresh rate limiter on the resulting client IP. If the proxy doesn't
|
||||
send the header, every request looks like it comes from the proxy and shares
|
||||
one rate-limit bucket.
|
||||
3. **Streaming for big media** — turning request/response buffering off lets
|
||||
large uploads stream straight to the app and lets video range-seeks work
|
||||
without nginx spooling whole files to disk first.
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name tanabata.example.com;
|
||||
|
||||
# ssl_certificate / ssl_certificate_key ... (e.g. from certbot)
|
||||
|
||||
# Match MAX_UPLOAD_BYTES (500 MiB default); nginx defaults to 1m → 413.
|
||||
client_max_body_size 512m;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:42776; # APP_PORT
|
||||
proxy_http_version 1.1;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# Stream large uploads/downloads instead of buffering to disk; keeps
|
||||
# video range-seek responsive. Scope these to file/preview locations
|
||||
# instead if you'd rather keep buffering for small JSON responses.
|
||||
proxy_request_buffering off;
|
||||
proxy_buffering off;
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you run the app **without** a proxy and want it reachable on the LAN, drop the
|
||||
`127.0.0.1:` prefix from the `ports` line in
|
||||
[`docker-compose.yml`](docker-compose.yml) and adjust `TRUSTED_PROXIES`
|
||||
accordingly.
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
# Backend
|
||||
cd backend
|
||||
go run ./cmd/server # dev server
|
||||
go test ./... # all tests
|
||||
|
||||
# Frontend
|
||||
cd frontend
|
||||
npm run dev # Vite dev server
|
||||
npm run build # production build
|
||||
npm run generate:types # regenerate API types from openapi.yaml
|
||||
```
|
||||
Reference in New Issue
Block a user