Getting Started
Last updated
This page starts node-image-server with Docker Compose and walks through the first upload and fetch.
Prerequisites
| Item | Version |
|---|---|
| Docker and Docker Compose v2 | Recommended deployment |
| Node.js | 22 or higher (only for running on the host; the container uses node:22-alpine) |
Start with Docker Compose
git clone https://github.com/pardnio/node-image-server.git
cd node-image-server
docker compose up -d
| Service | Image | Role |
|---|---|---|
nginx |
nginx:stable-alpine |
Listens on 8080, loads config/nginx/nodejs.conf |
nodejs |
node:22-alpine |
Runs npm install on start, then loads app.ts with npx pm2-runtime start app.json |
The default Nginx config forwards
/upload/and/del/tonodejs:3000, whileNODE_PORTinapp/.envis8080. Align the two before uploading or deleting through Nginx; see Nginx.
Run on the Host
cd node-image-server/app
npm install
mkdir -p storage/logs storage/image
npx pm2-runtime start app.json
Requests then reach Express directly (http://localhost:8080) without Nginx.
First Upload
curl -fsS -X POST \
-F "filepath=@./photo.jpg" \
http://localhost:8080/upload/blog/2025 \
|| echo "upload failed"
A successful upload returns 201:
{
"success": 1,
"filename": "ERftP1gTS7WCTeJ8_1744080848530.jpg",
"type": "image/jpeg",
"size": 2501808,
"src": "http://localhost:8080/c/img/blog/2025/ERftP1gTS7WCTeJ8_1744080848530.jpg"
}
First Fetch
# Defaults: WebP, quality 75, long edge shrunk to 1024px when the short edge exceeds 1024px
curl -fsS -o photo.webp \
http://localhost:8080/c/img/blog/2025/ERftP1gTS7WCTeJ8_1744080848530.jpg
# 800px-wide AVIF
curl -fsS -o w800.avif \
"http://localhost:8080/c/img/blog/2025/ERftP1gTS7WCTeJ8_1744080848530.jpg?w=800&t=avif"
The first request converts the image with sharp and writes it to storage/image/cache/; later requests with the same parameters read the cache file.
Next Steps
- Full parameter list: Image Parameters
- How caching is layered: Caching Layers
- Production settings: Configuration