Express-based multi-user web hosting service with admin-managed accounts, domain quotas, and FTP access.
- Admin-only user provisioning and JWT authentication
- Domain assignment with per-domain quota management
- File upload API for domain content
- HTTP hosting for registered domains via
/site/:domain/... - FTP access for users at
ftp://<host>:2121
- Install dependencies:
npm install- Start the service:
npm startOr use Docker Compose:
docker compose up --build- Environment variables (optional):
PORT- HTTP port (default:3000)JWT_SECRET- JWT signing secretADMIN_API_KEY- admin API key for protected endpointsFTP_HOST- FTP bind host (default:0.0.0.0)FTP_PORT- FTP port (default:2121)MONGO_URI- MongoDB URI (default:mongodb://127.0.0.1:27017/hosting)DEFAULT_DOMAIN_QUOTA_MB- default quota per domain in MB (default:100)
POST /api/auth/login- body:
{ "email": "user@example.com", "password": "secret" }
- body:
GET /api/users/me- requires
Authorization: Bearer <token>
- requires
GET /api/domains- requires auth
DELETE /api/domains/:domain- requires auth
- delete an owned domain and its hosted files
POST /api/domains/:domain/upload- requires auth
- multipart form field
file
GET /api/domains/:domain/files- requires auth
DELETE /api/users/me- requires auth
- delete your own account and related domains
GET /api/admin/users- requires admin auth
- list all users
POST /api/admin/users- requires admin auth
- body:
{ "email": "admin@example.com", "password": "secret", "displayName": "Admin", "isAdmin": true }
DELETE /api/admin/users/:id- requires admin auth
- delete a user and all owned domains
GET /api/admin/domains- requires admin auth
- list all domains
POST /api/admin/domains- requires admin API key
- body:
{ "userId": "<userId>", "name": "newdomain.com", "quotaMb": 100 }
PATCH /api/admin/domains/:id- requires admin API key
- body:
{ "quotaMb": 200 } - update a domain quota in megabytes
DELETE /api/admin/domains/:id- requires admin API key
- delete a domain by id
- send
x-api-key: <ADMIN_API_KEY>header or use?apiKey=<ADMIN_API_KEY> - set
ADMIN_API_KEYin your environment to protect admin endpoints
- HTTP assets are served from
/site/:domain/... - If your host header matches a registered domain, content is served directly from that domain root.
Use your account email and password to authenticate. The FTP root is scoped to your user, with directories created for each registered domain.