The same code that runsDocumentation Index
Fetch the complete documentation index at: https://docs.letmepost.dev/llms.txt
Use this file to discover all available pages before exploring further.
api.letmepost.dev runs locally. There is no feature gate between the OSS image and the hosted SaaS.
What you need
- Docker + Docker Compose
- Postgres 15+ (or use the bundled service)
- Redis 7+ (BullMQ workers run here)
- An S3-compatible bucket for media (R2, MinIO, AWS S3 — anything signed-url-able)
- Your own OAuth app credentials per platform (Bluesky doesn’t need one)
Compose
The repo ships adocker-compose.dev.yml that wires up Postgres, Redis, the API, the worker, and the dashboard:
bring-it-up.sh
:3000, the dashboard to :3001. Health probe: GET http://localhost:3000/healthz.
Required env
| var | what |
|---|---|
DATABASE_URL | Postgres URL |
REDIS_URL | Redis URL (BullMQ + idempotency cache) |
MEDIA_S3_BUCKET | bucket name |
MEDIA_S3_REGION | region |
MEDIA_S3_ENDPOINT | for R2 / MinIO; omit for AWS S3 |
MEDIA_S3_ACCESS_KEY_ID | bucket credentials |
MEDIA_S3_SECRET_ACCESS_KEY | |
MEDIA_PUBLIC_BASE_URL | public URL prefix; concatenated with the s3 key |
ENCRYPTION_KEY | 32-byte base64 key for token encryption at rest |
WEBHOOK_SIGNING_SECRET | HMAC secret for outbound webhook signatures |
PUBLIC_API_BASE_URL | the URL your API is reachable on (used in OAuth callbacks) |
| platform | env vars |
|---|---|
| Bluesky | none |
LINKEDIN_CLIENT_ID, LINKEDIN_CLIENT_SECRET | |
| Twitter / X | TWITTER_CLIENT_ID, TWITTER_CLIENT_SECRET |
| Facebook (and Instagram) | META_APP_ID, META_APP_SECRET |
| Threads | THREADS_APP_ID, THREADS_APP_SECRET |
PINTEREST_CLIENT_ID, PINTEREST_CLIENT_SECRET |
.env. The auth flows themselves are identical to hosted — see accounts.
Migrations
apps/api/drizzle/. For zero-downtime deploys, follow the standard “additive then destructive in a follow-up release” pattern.
Updating
DEPLOY.md.
Production notes
- Run the API and worker as separate processes in production. Compose runs both for convenience; deployments should split them so one queue backlog doesn’t starve HTTP.
- Postgres + Redis must persist. The dev compose ships ephemeral volumes — don’t ship that to prod.
- Rotate
ENCRYPTION_KEYcarefully — there is no automatic re-encryption today; rotation requires a script that decrypts with the old key and re-encrypts with the new.