1.8 KiB
The Meme Protocol
Small self-hosted meme gallery matching the stitch_the_meme_protocol desktop mockup direction.
Run locally
npm start
The server listens on http://localhost:8080 by default.
Configuration
PORT: HTTP port, default8080HOST: bind address, default0.0.0.0DATA_DIR: disk storage root, default./dataSEED_DEMO_MEMES: set tofalseto disable generated demo memes on first bootADMIN_TOKEN: secret review URL token. If omitted, one is generated at boot and printed in server logs.OPENAI_API_KEY: enables AI upload moderation. Without it, uploads are queued for admin review.OPENAI_MODERATION_MODEL: moderation vision model, defaultgpt-4o-miniTRUST_PROXY: set totruewhen running behind a trusted reverse proxy so upload limits useX-Forwarded-For
Uploads accept only square PNG and JPEG images. The server rejects files over 5 MB, images over 6000x6000, and images over 20 million pixels. Accepted uploads are decoded, metadata-stripped, resized down to 1600x1600 if needed, and stored as WebP.
Upload caps are 5 per hour per IP, 10 per day per IP, and 100 globally per day. AI-approved uploads publish immediately; ambiguous uploads are queued for the secret admin review page; likely illegal uploads are rejected immediately.
Files are stored under sharded date/hash paths:
data/
index/memes.jsonl
memes/YYYY/MM/DD/aa/bb/<sha256>.<ext>
meta/YYYY/MM/DD/aa/bb/<sha256>.json
Docker
docker build -t meme-protocol .
docker run --rm -p 8080:8080 -v meme-protocol-data:/data meme-protocol
For production, copy .env.example to .env, set real secrets, then run:
docker compose up -d --build
The included compose file binds the app to 127.0.0.1:18080 on the host so a reverse proxy can publish it without exposing the Node container directly.