Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM node:20-alpine
WORKDIR /app
COPY package.json ./
RUN npm install --production
COPY server.js ./
COPY public ./public
EXPOSE 3000
CMD ["node", "server.js"]
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,46 @@
# MacAI

AI-powered search assistant using Cerebras LLM and SearXNG.

## Quick Start (Docker)

Run both the Node server and SearXNG together:

```bash
# Create a .env file with your API key
echo "CEREBRAS_API_KEY=your-key-here" > .env

# Start everything
docker compose up -d
```

Open [http://localhost:3000](http://localhost:3000) in your browser.

Inside Docker Compose the Node server reaches SearXNG via `http://searxng:8080`
(the Docker service name and internal port). This is set automatically by
`docker-compose.yml`.

## Running the Node Server on the Host

If you prefer to run the Node server directly on your machine while SearXNG
stays in Docker:

```bash
# Start only SearXNG
docker compose up -d searxng

# Install dependencies and start the server
npm install
npm start
```

When running on the host, the default `SEARXNG_URL` is `http://localhost:8888`,
which maps to the container's port 8080 via the published Docker port.

## Environment Variables

| Variable | Default | Description |
| ------------------ | ------------------------ | ------------------------------- |
| `CEREBRAS_API_KEY` | *(required)* | API key for Cerebras |
| `SEARXNG_URL` | `http://localhost:8888` | SearXNG base URL |
| `PORT` | `3000` | Port for the Express server |
23 changes: 22 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,26 @@ services:
- ./searxng/settings.yml:/etc/searxng/settings.yml:ro
- ./searxng/limiter.toml:/etc/searxng/limiter.toml:ro
environment:
- SEARXNG_BASE_URL=http://localhost:8888/
- SEARXNG_BASE_URL=http://searxng:8080/
restart: unless-stopped
networks:
- macai-net

server:
build: .
container_name: macai-server
ports:
- "3000:3000"
environment:
- SEARXNG_URL=http://searxng:8080
env_file:
- .env
depends_on:
- searxng
restart: unless-stopped
networks:
- macai-net

networks:
macai-net:
driver: bridge
32 changes: 22 additions & 10 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -324,15 +324,27 @@ app.listen(PORT, async () => {
console.log(`✓ http://localhost:${PORT}`);
if (!CEREBRAS_KEY_RESOLVED) console.warn('⚠ CEREBRAS_API_KEY not set');

// Check SearXNG connectivity on startup
try {
const ctrl = new AbortController();
const timer = setTimeout(() => ctrl.abort(), 3000);
const resp = await fetch(`${SEARXNG_URL}/healthz`, { signal: ctrl.signal });
clearTimeout(timer);
if (resp.ok) console.log(`✓ SearXNG reachable at ${SEARXNG_URL}`);
else console.warn(`⚠ SearXNG returned HTTP ${resp.status} at ${SEARXNG_URL}`);
} catch (_) {
console.warn(`⚠ SearXNG not reachable at ${SEARXNG_URL} — run: docker compose up -d`);
// Check SearXNG connectivity on startup (retry up to 5 times for Docker cold-start)
const maxRetries = 5;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const ctrl = new AbortController();
const timer = setTimeout(() => ctrl.abort(), 5000);
const resp = await fetch(`${SEARXNG_URL}/healthz`, { signal: ctrl.signal });
clearTimeout(timer);
if (resp.ok) {
console.log(`✓ SearXNG reachable at ${SEARXNG_URL}`);
break;
}
console.warn(`⚠ SearXNG returned HTTP ${resp.status} at ${SEARXNG_URL}`);
break;
} catch (_) {
if (attempt < maxRetries) {
console.warn(`⚠ SearXNG not reachable at ${SEARXNG_URL} (attempt ${attempt}/${maxRetries}), retrying in 3s…`);
await new Promise(r => setTimeout(r, 3000));
} else {
console.warn(`⚠ SearXNG not reachable at ${SEARXNG_URL} after ${maxRetries} attempts — run: docker compose up -d`);
}
}
}
});