From b2d6be90c23248f668afe6afc2a541b1a2688154 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Fri, 15 May 2026 01:26:23 +0200 Subject: [PATCH] =?UTF-8?q?chore:=20update=20README,=20Dockerfile,=20compo?= =?UTF-8?q?se.yml=20=E2=80=94=20add=20frontend/worker=20services,=20SSR=20?= =?UTF-8?q?env=20var,=20feature=20list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 37 +++++++++++++++++++--- compose.yml | 41 +++++++++++++++++++++++++ thoughts-frontend/Dockerfile | 3 ++ thoughts-frontend/README.md | 59 +++++++++++++++++++++--------------- 4 files changed, 111 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 9854c00..061413a 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,11 @@ A self-hosted microblogging server with full ActivityPub federation. Write short - Short-form posts (thoughts) with replies, boosts, and likes - Full ActivityPub federation — follow/unfollow remote actors, accept/reject followers, federated content broadcast as `Note` objects, paginated outbox, NodeInfo discovery, WebFinger, shared inbox, actor profile sync +- **Remote actor discovery** — search by `@user@instance` handle, view full remote profiles (bio, banner, profile fields, posts, followers, following tabs), follow from within the UI +- **Worker-backed remote caches** — remote posts and follower/following lists are fetched by the NATS worker and cached locally; profiles populate on first visit and refresh in the background +- Content negotiation at `GET /users/{username}` — serves ActivityPub actor JSON or REST profile based on `Accept` header - Federation moderation — per-instance domain blocking, per-user actor blocking with `Block` activity delivery, delivery filter excludes blocked actors and blocked-domain inboxes -- Async event fan-out via NATS — notifications and AP delivery run in a separate worker process +- Async event fan-out via NATS JetStream — notifications and AP delivery run in a separate worker process; pull consumer with 1-hour TTL caching - JWT authentication (Bearer token) - OpenAPI documentation at `/docs` (Swagger UI) and `/scalar` (Scalar) - Full-text search over thoughts and users via PostgreSQL trigram indexes @@ -87,18 +90,33 @@ All REST endpoints are under the root path. Authentication uses `Authorization: Interactive API documentation is available at runtime: -- **Swagger UI** — `http://localhost:3000/docs` -- **Scalar** — `http://localhost:3000/scalar` +- **Swagger UI** — `http://localhost:8000/docs` +- **Scalar** — `http://localhost:8000/scalar` + +## Frontend + +The Next.js frontend lives in `thoughts-frontend/`. It requires two environment variables: + +```env +NEXT_PUBLIC_API_URL=http://localhost:8000 # client-side requests +NEXT_PUBLIC_SERVER_SIDE_API_URL=http://localhost:8000 # SSR requests +``` + +```bash +cd thoughts-frontend +bun install +bun run dev # http://localhost:3000 +``` ## Docker -The image contains both `thoughts` (API server) and `thoughts-worker` (event processor). Run them as separate containers: +The backend image contains both `thoughts` (API server) and `thoughts-worker` (event processor). Run them as separate containers: ```bash docker build -t thoughts . # API server -docker run -p 3000:3000 \ +docker run -p 8000:8000 \ -e DATABASE_URL=postgres://postgres:password@db:5432/thoughts \ -e JWT_SECRET=change-me \ -e BASE_URL=https://yourdomain.example.com \ @@ -112,8 +130,17 @@ docker run \ -e NATS_URL=nats://nats:4222 \ --entrypoint ./thoughts-worker \ thoughts + +# Frontend +docker build -t thoughts-frontend \ + --build-arg NEXT_PUBLIC_API_URL=https://api.yourdomain.example.com \ + --build-arg NEXT_PUBLIC_SERVER_SIDE_API_URL=http://thoughts:8000 \ + thoughts-frontend/ +docker run -p 3000:3000 thoughts-frontend ``` +See `compose.yml` for a full local development stack. + ## License MIT License. See [LICENSE](LICENSE). diff --git a/compose.yml b/compose.yml index 6a2b94e..06cf13a 100644 --- a/compose.yml +++ b/compose.yml @@ -22,5 +22,46 @@ services: - "8222:8222" # monitoring endpoint command: ["--jetstream", "--http_port", "8222"] + api: + build: . + ports: + - "8000:8000" + environment: + DATABASE_URL: postgres://postgres:postgres@postgres:5432/thoughts + JWT_SECRET: change-me-in-production + BASE_URL: http://localhost:8000 + NATS_URL: nats://nats:4222 + RUST_LOG: info + depends_on: + postgres: + condition: service_healthy + nats: + condition: service_started + + worker: + build: . + entrypoint: ["./thoughts-worker"] + environment: + DATABASE_URL: postgres://postgres:postgres@postgres:5432/thoughts + BASE_URL: http://localhost:8000 + NATS_URL: nats://nats:4222 + RUST_LOG: info + depends_on: + postgres: + condition: service_healthy + nats: + condition: service_started + + frontend: + build: + context: ./thoughts-frontend + args: + NEXT_PUBLIC_API_URL: http://localhost:8000 + NEXT_PUBLIC_SERVER_SIDE_API_URL: http://api:8000 + ports: + - "3000:3000" + depends_on: + - api + volumes: postgres_data: diff --git a/thoughts-frontend/Dockerfile b/thoughts-frontend/Dockerfile index 6873141..15a2879 100644 --- a/thoughts-frontend/Dockerfile +++ b/thoughts-frontend/Dockerfile @@ -4,6 +4,9 @@ WORKDIR /app ARG NEXT_PUBLIC_API_URL ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL +ARG NEXT_PUBLIC_SERVER_SIDE_API_URL +ENV NEXT_PUBLIC_SERVER_SIDE_API_URL=$NEXT_PUBLIC_SERVER_SIDE_API_URL + # Install dependencies with Bun for speed COPY --chown=node:node package.json bun.lock ./ RUN npm install -g bun diff --git a/thoughts-frontend/README.md b/thoughts-frontend/README.md index e215bc4..7adebbe 100644 --- a/thoughts-frontend/README.md +++ b/thoughts-frontend/README.md @@ -1,36 +1,47 @@ -This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). +# Thoughts — Frontend -## Getting Started +Next.js 15 (App Router) frontend for the [Thoughts](../) self-hosted microblogging server. -First, run the development server: +## Features + +- Post thoughts, reply, boost, and like +- Home feed, public feed, per-user timelines +- Browse and follow remote Fediverse actors by `@user@instance` handle +- Full remote actor profiles — bio, banner, profile fields, posts tab, followers/following tabs +- Full-text search for local users and thoughts; remote actor lookup via WebFinger +- Notifications, API key management, profile editing +- Dark/light theme + +## Setup ```bash -npm run dev -# or -yarn dev -# or -pnpm dev -# or -bun dev +bun install ``` -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. +Copy `.env.local.example` to `.env.local` (or set the variables directly): -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. +```env +NEXT_PUBLIC_API_URL=http://localhost:8000 +NEXT_PUBLIC_SERVER_SIDE_API_URL=http://localhost:8000 +``` -This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. +`NEXT_PUBLIC_API_URL` is used by client-side fetches (runs in the browser). +`NEXT_PUBLIC_SERVER_SIDE_API_URL` is used by server-side fetches (runs in Next.js SSR — can point to an internal service URL in Docker). -## Learn More +## Run -To learn more about Next.js, take a look at the following resources: +```bash +bun run dev # development — http://localhost:3000 +bun run build # production build +bun run start # serve production build +``` -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. +## Docker -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! - -## Deploy on Vercel - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - -Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. +```bash +docker build \ + --build-arg NEXT_PUBLIC_API_URL=https://api.yourdomain.example.com \ + --build-arg NEXT_PUBLIC_SERVER_SIDE_API_URL=http://thoughts:8000 \ + -t thoughts-frontend . +docker run -p 3000:3000 thoughts-frontend +```