A highly optimized Node.js service created to securely store and serve images exactly once. Built strictly with the functional programming ecosystem Effect for robust type-safety and error-handling without relying on any any types.
Required Node.js version is v22.x and relies on Yarn for package management.
- Store an image: Accepts a POST request with
multipart/form-dataand saves it strictly to local temporary storage. - View exactly once: Fetches an image via a GET endpoint, strictly verifies existence, returns the payload to the requester, and synchronously unlinks it from disk.
- Strict Typing: Completely built relying on
@effect/platformtypes withoutanybypasses.
-
Clone the repository
-
Set up
.envfile Copy the provided.env.exampleblock to.envrepresenting your environment variables:PORT=3000 HOST=0.0.0.0 BASE_URL=http://localhost:3000 UPLOAD_DIR=/tmp/ephemeral-uploads FILE_TTL_HOURS=24
-
Install Dependencies
yarn install
To start a local hot-reload development server:
yarn devTo run a production build:
yarn build
yarn startThis repository includes a multi-staged minimal Dockerfile constructed using standard Alpine node bases.
# Build the extremely lightweight image
docker build -t ephemeral-file-server .
# Run the container locally mapping port 3000
docker run -p 3000:3000 -d ephemeral-file-serverTo upload multiple images, the form field part must be exactly named image.
curl -X POST -F "image=@/path/to/my-picture.png" http://localhost:3000/uploadResponse:
{
"url": "http://localhost:3000/image/d3b07384-d113-4c91-b3b3-1f14800e84b1"
}The endpoint retrieves the provided ID, infers its Mime/content type precisely through extension, returns the buffer stream to front-facing agents, and completely unlinks/wipes the local file storage payload dynamically to emulate ephemeral lifecycles.
curl -i http://localhost:3000/image/d3b07384-d113-4c91-b3b3-1f14800e84b1If you request the same object again:
HTTP/1.1 404 Not FoundEvery uploaded file has a single, global time-to-live controlled by
FILE_TTL_HOURS (default 24, must be a positive number). A background sweep
runs hourly (or on the TTL interval, whichever is shorter) and removes any
file older than the TTL whether or not it was ever retrieved. The read
endpoint also enforces the TTL on every request, so an expired file is never
served even if the sweep hasn't run yet. There is no per-upload override, and
the upload response never discloses an expiration time. An expired file, an
already-read file, and an unknown id all return the identical 404 Not Found.