Add README with setup, Docker, and fail2ban instructions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
152
README.md
Normal file
152
README.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# Nanodrop
|
||||
|
||||
A minimal self-hosted file sharing platform. Upload a file, get a shareable link. No frills.
|
||||
|
||||
- Server-rendered HTML, no client-side framework
|
||||
- SQLite database, files stored on disk
|
||||
- JWT authentication via httpOnly cookies
|
||||
- REST API alongside the web UI
|
||||
|
||||
## Stack
|
||||
|
||||
- **Runtime:** Node.js 22
|
||||
- **Framework:** Fastify
|
||||
- **Database:** SQLite (better-sqlite3)
|
||||
- **Language:** TypeScript (ESM, run directly via tsx)
|
||||
|
||||
---
|
||||
|
||||
## Quick start (local)
|
||||
|
||||
```sh
|
||||
npm install
|
||||
JWT_SECRET=changeme npm run dev
|
||||
```
|
||||
|
||||
Create a user first:
|
||||
|
||||
```sh
|
||||
npm run register-user -- --username alice --password secret
|
||||
```
|
||||
|
||||
Then open `http://localhost:3000`.
|
||||
|
||||
---
|
||||
|
||||
## Docker
|
||||
|
||||
### Build and run
|
||||
|
||||
```sh
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Requires a `.env` file (or environment variables) with at minimum:
|
||||
|
||||
```env
|
||||
JWT_SECRET=your-secret-here
|
||||
```
|
||||
|
||||
All data (database + uploads) is stored in the `nanodrop-data` Docker volume.
|
||||
|
||||
### Register a user in Docker
|
||||
|
||||
```sh
|
||||
docker compose run --rm register-user --username alice --password secret
|
||||
```
|
||||
|
||||
### Environment variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|---|---|---|
|
||||
| `JWT_SECRET` | *(required)* | Secret key for signing JWTs |
|
||||
| `JWT_EXPIRY` | `7d` | JWT token lifetime |
|
||||
| `PORT` | `3000` | Port to listen on |
|
||||
| `HOST` | `0.0.0.0` | Host to bind |
|
||||
| `BASE_URL` | `http://localhost:3000` | Public base URL (used in share links) |
|
||||
| `DB_PATH` | `./data/nanodrop.db` | SQLite database path |
|
||||
| `UPLOAD_DIR` | `./data/uploads` | Upload storage directory |
|
||||
| `LOG_FILE` | `./data/nanodrop.log` | Auth and access log path |
|
||||
| `MAX_FILE_SIZE` | `104857600` | Max upload size in bytes (100 MB) |
|
||||
| `COOKIE_SECURE` | `false` | Set `true` when serving over HTTPS |
|
||||
| `TRUST_PROXY` | `false` | Set `true` when behind a reverse proxy |
|
||||
|
||||
### Reverse proxy (nginx example)
|
||||
|
||||
When running behind nginx, set `TRUST_PROXY=true` so Nanodrop sees the real client IP in logs.
|
||||
|
||||
```nginx
|
||||
server {
|
||||
server_name files.example.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
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;
|
||||
client_max_body_size 110M;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Fail2ban
|
||||
|
||||
Nanodrop logs failed login attempts to `LOG_FILE` (default `./data/nanodrop.log`) in this format:
|
||||
|
||||
```
|
||||
[2026-03-03T12:00:00.000Z] AUTH_FAILURE ip=203.0.113.42 user-agent="curl/8.0" username="admin"
|
||||
```
|
||||
|
||||
### 1. Create a filter
|
||||
|
||||
`/etc/fail2ban/filter.d/nanodrop.conf`:
|
||||
|
||||
```ini
|
||||
[Definition]
|
||||
failregex = ^.* AUTH_FAILURE ip=<HOST> .*$
|
||||
ignoreregex =
|
||||
```
|
||||
|
||||
### 2. Create a jail
|
||||
|
||||
`/etc/fail2ban/jail.d/nanodrop.conf`:
|
||||
|
||||
```ini
|
||||
[nanodrop]
|
||||
enabled = true
|
||||
filter = nanodrop
|
||||
logpath = /path/to/nanodrop.log
|
||||
maxretry = 5
|
||||
findtime = 60
|
||||
bantime = 600
|
||||
```
|
||||
|
||||
Adjust `logpath` to wherever your `LOG_FILE` is. With Docker, the log file lives inside the `nanodrop-data` volume — mount it to a host path or bind-mount a host directory instead of the named volume to make it accessible to fail2ban:
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml override
|
||||
volumes:
|
||||
- /var/lib/nanodrop:/app/data
|
||||
```
|
||||
|
||||
Then set `logpath = /var/lib/nanodrop/nanodrop.log`.
|
||||
|
||||
### 3. Reload fail2ban
|
||||
|
||||
```sh
|
||||
sudo fail2ban-client reload
|
||||
sudo fail2ban-client status nanodrop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Development
|
||||
|
||||
```sh
|
||||
npm run dev # start with hot reload via tsx
|
||||
npm test # run all tests (vitest)
|
||||
npm run build # type check (tsc --noEmit)
|
||||
```
|
||||
Reference in New Issue
Block a user