22
33[ 中文] ( ./README.md ) | [ English] ( ./README_en.md )
44
5+ ![ Node] ( https://img.shields.io/badge/Node.js-43853D.svg?logo=node.js&logoColor=white )
6+ ![ Docker] ( https://img.shields.io/badge/Docker-ready-2496ED?logo=docker&logoColor=white )
7+ ![ License] ( https://img.shields.io/badge/License-MIT-yellow )
8+ ![ Tests] ( https://img.shields.io/badge/Tests-passing-brightgreen )
9+
510A self-hosted random image API with an admin panel. Built on Node.js + Express, no database required. Images are stored on the local filesystem. Suitable for personal image hosting and wallpaper sites.
611
712## Features
@@ -25,46 +30,104 @@ The app is mounted under the `/image` subpath:
2530
2631## Deployment
2732
28- ### Docker (Recommended)
29-
30- ** docker compose (Recommended)**
33+ ### Docker Hub Image (Recommended)
34+
35+ Image: ` docker.io/charyeahowo/nyaovo-random-image-api:latest `
36+
37+ Auto-built and pushed via GitHub Actions on every push to ` main ` .
38+
39+ <details >
40+ <summary ><b >docker compose (click to expand)</b ></summary >
41+
42+ Create ` docker-compose.yml ` , copy the content below, and change ` ADMIN_PASSWORD ` and ` SESSION_SECRET ` :
43+
44+ ``` yaml
45+ services :
46+ nyaovo-random-image-api :
47+ image : charyeahowo/nyaovo-random-image-api:latest
48+ container_name : nyaovo-random-image-api
49+ ports :
50+ - " 3400:3000"
51+ volumes :
52+ - ./images:/app/public/images
53+ environment :
54+ PORT : 3000
55+ PUBLIC_BASE_URL : http://localhost:3400
56+ IMAGE_ROOT : public/images
57+ CACHE_TTL_SECONDS : 60
58+ RATE_LIMIT_WINDOW_MS : 60000
59+ RATE_LIMIT_MAX : 120
60+ ADMIN_USERNAME : admin
61+ ADMIN_PASSWORD : changeme # ← must change
62+ SESSION_SECRET : please-change-this # ← must change
63+ ADMIN_PATH : /image/admin
64+ MAX_FILE_SIZE_MB : 10
65+ MAX_UPLOAD_FILES : 20
66+ CORS_ORIGIN : " *"
67+ restart : unless-stopped
68+ ` ` `
3169
3270` ` ` bash
33- git clone https://github.com/user/nyaovo-random-image-api.git
34- cd nyaovo-random-image-api
35-
36- # Edit environment variables
37- cp .env.example .env
38- # At minimum, change ADMIN_PASSWORD and SESSION_SECRET
39-
40- docker compose up -d --build
71+ docker compose up -d
4172```
4273
74+ > The container auto-fixes ` ./images ` directory permissions on startup. No manual chown needed.
75+
4376Access at ` http://localhost:3400/image ` , admin at ` http://localhost:3400/image/admin ` .
4477
45- ** docker run **
78+ </ details >
4679
47- ``` bash
48- docker build -t nyaovo-random-image-api .
80+ < details >
81+ < summary >< b > docker run (click to expand)</ b ></ summary >
4982
83+ ``` bash
5084docker run -d \
5185 --name nyaovo \
5286 -p 3400:3000 \
5387 -v ./images:/app/public/images \
5488 -e ADMIN_PASSWORD=your-password \
5589 -e SESSION_SECRET=your-secret \
5690 -e PUBLIC_BASE_URL=http://localhost:3400 \
57- nyaovo-random-image-api
91+ --restart unless-stopped \
92+ charyeahowo/nyaovo-random-image-api:latest
5893```
5994
6095> The ` images ` volume must be writable. Do not use ` :ro ` .
6196
62- ** 1Panel**
97+ </details >
98+
99+ <details >
100+ <summary ><b >Local build (click to expand)</b ></summary >
101+
102+ ``` bash
103+ git clone https://github.com/charyeahowo/nyaovo-random-image-api.git
104+ cd nyaovo-random-image-api
105+
106+ cp .env.example .env
107+ # Edit .env, at minimum change ADMIN_PASSWORD and SESSION_SECRET
108+
109+ docker compose up -d --build
110+ ```
111+
112+ To use local build instead of remote image, replace the ` image ` line in ` docker-compose.yml ` with:
113+
114+ ``` yaml
115+ build :
116+ context : .
117+ dockerfile : Dockerfile
118+ ` ` `
119+
120+ </details>
121+
122+ <details>
123+ <summary><b>1Panel (click to expand)</b></summary>
63124
641251. Create a Docker Compose stack, upload project or clone via Git
65- 2 . Use the included ` docker-compose.yml ` , edit environment variables
126+ 2. Use the included ` docker-compose.yml`, create `.env` file with your variables
661273. After starting, configure a reverse proxy in OpenResty / Nginx to bind your domain
67128
129+ </details>
130+
68131# ## Local
69132
70133` ` ` bash
@@ -120,18 +183,24 @@ Default credentials: `admin` / `changeme`.
120183
121184# ## `GET /image/api/random`
122185
123- Returns a random image.
186+ Returns a random image. Supports flexible parameter combinations for different use cases.
124187
125- Parameters:
126- - ` gallery ` — Gallery name
127- - ` device ` — ` pc ` / ` mobile ` / ` all `
128- - ` type ` — ` image ` (default) / ` json ` / ` redirect `
188+ | Parameter | Values | Default | Description |
189+ |-----------|--------|---------|-------------|
190+ | `gallery` | Gallery name | All | Target gallery |
191+ | `device` | `pc` / `mobile` / `all` | `all` | Device type |
192+ | `type` | `image` / `json` / `redirect` | `image` | Response format |
129193
130- ```
131- /image/api/random?gallery=anime&device=pc&type=json
132- ```
194+ **Response format details:**
195+
196+ | type | Response | Content-Type |
197+ |------|----------|-------------|
198+ | `image` | Raw image binary | `image/*` |
199+ | `json` | Image metadata JSON | `application/json` |
200+ | `redirect` | 302 redirect to image URL | - |
201+
202+ **JSON response example:**
133203
134- JSON response:
135204` ` ` json
136205{
137206 "url": "https://example.com/image/images/anime/pc/001.webp",
@@ -146,17 +215,23 @@ JSON response:
146215}
147216` ` `
148217
149- ### Other Endpoints
150-
151- | Endpoint | Description |
152- | ----------| -------------|
153- | ` GET /image/api/:gallery ` | Gallery shortcut |
154- | ` GET /image/api/galleries ` | Gallery statistics |
155- | ` GET /image/api/list ` | Paginated image list |
156- | ` GET /image/api/stats ` | Global statistics |
157- | ` GET /image/health ` | Health check |
158-
159- ## Image Management
218+ # ## API Examples
219+
220+ | Endpoint | Use Case |
221+ |----------|----------|
222+ | `GET /image/api/random` | Random image from any gallery, ideal for site-wide random backgrounds |
223+ | `GET /image/api/random?gallery=anime` | Random image from a specific gallery, ideal for category-based wallpaper rotation |
224+ | `GET /image/api/random?gallery=anime&device=pc` | Gallery + landscape, ideal for desktop backgrounds |
225+ | `GET /image/api/random?gallery=anime&device=mobile` | Gallery + portrait, ideal for mobile backgrounds |
226+ | `GET /image/api/random?type=json` | Image metadata for custom frontend rendering |
227+ | `GET /image/api/random?type=redirect` | 302 redirect, ideal for `<img src>` direct embedding |
228+ | `GET /image/api/:gallery` | Gallery shortcut, equivalent to `?gallery=xxx` |
229+ | `GET /image/api/galleries` | All gallery statistics, ideal for admin dashboards |
230+ | `GET /image/api/list?limit=100` | Paginated image list, ideal for backend management |
231+ | `GET /image/api/stats` | Global statistics, ideal for monitoring dashboards |
232+ | `GET /image/health` | Health check, ideal for Docker/K8s probes |
233+
234+ # ## Image Management
160235
161236- Supported formats : jpg, jpeg, png, webp, gif, avif
162237- Real file format is detected on upload; wrong extensions are corrected
0 commit comments