A standalone Node.js storage backend for handling file uploads, local disk storage, and public file serving. Designed to be used as a remote storage service alongside a main backend (e.g. deployed on Render), while utilizing persistent disk storage on platforms like Hostinger.
This project provides a dedicated storage server that:
- Accepts file uploads via HTTP
- Stores files on local disk (persistent storage)
- Optimizes images (compression + WebP conversion)
- Serves files publicly
- Deletes files on request
- Secures all write operations using an API Key
It is intended to be used as a separate service from the main application backend.
Frontend
↓
Core Backend (Render)
↓ HTTP (API Key secured)
Remote Storage Server (Hostinger)
↓
Local Disk (uploads/)
- Authentication & authorization
- Business logic
- Database access (MongoDB)
- File metadata persistence (URL, publicId)
- File upload & deletion
- Local disk storage
- Image optimization
- Public file access
- NO database access
- NO business logic
storage-backend/
├── src/
│ └── providers/
│ ├── BaseUploadProvider.js
│ └── LocalProvider.js
├── uploads/ # Stored files
├── .env.example
├── package.json
└── storage-server.js # Express entry point
Create a .env file based on .env.example:
PORT=5001
STORAGE_SERVER_API_KEY=your_secure_api_key
LOCAL_UPLOAD_PATH=uploadsnpm installnpm startThe server will start on:
http://localhost:5001
All write operations (upload & delete) are protected using an API Key.
X-API-KEY: your_secure_api_key
Requests without a valid API key will be rejected.
POST /upload
X-API-KEY: your_secure_api_key
file(required): The file to uploadfolder(optional): Target subfolder (default:general)
{
"success": true,
"data": {
"url": "https://storage.example.com/uploads/general/file.webp",
"publicId": "general/file.webp",
"resourceType": "image",
"format": "webp"
}
}DELETE /delete/:publicId
X-API-KEY: your_secure_api_key
DELETE /delete/general/file.webp
Uploaded files are publicly accessible via:
/uploads/<folder>/<filename>
Example:
https://storage.example.com/uploads/general/image.webp
GET /health
Expected response:
{ "status": "OK" }- Upload a file using Postman or curl
- Verify file appears in
uploads/ - Open file URL in browser
- Delete file and verify removal
- Upload this project to your Hostinger server
- Set environment variables
- Install dependencies
- Run:
node storage-server.jsOr using a process manager like pm2 (recommended).
This server is designed to work with a main backend using an HTTP-based storage provider
(e.g. HttpStorageProvider).
The Core Backend:
- Sends files to this server
- Receives URLs & publicIds
- Stores metadata in its own database
- This service should NOT access any database
- This service should NOT contain business logic
- This service is stateless except for stored files
- Designed for small to medium scale projects