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
25 changes: 25 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# docker build context ignores
node_modules
.next/cache
.next/types
.next/trace
.turbo

dist
build

.git
.gitignore
.vscode
.idea

Dockerfile*
docker-compose*

.env
.env.*
!.env.example

pnpm-debug.log*
npm-debug.log*
yarn-error.log*
22 changes: 22 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
# Copy to .env and fill in values for local/dev.

# Database (Easypanel: create a Postgres service and copy the internal connection URL)
DATABASE_URL="postgresql://user:password@postgres:5432/dbname?schema=public"

# NextAuth
NEXTAUTH_URL="https://your-domain.com"
# Generate a strong random value for production
NEXTAUTH_SECRET="changeme"

# AI Providers (at least one required by the app)
OPENROUTER_API_KEY=""
GROQ_API_KEY=""

# Optional integrations
GOOGLE_CLIENT_ID=""
GOOGLE_CLIENT_SECRET=""
UNSPLASH_ACCESS_KEY=""
TAVILY_API_KEY=""

# Node env
NODE_ENV="development"
DATABASE_URL=""
# https://next-auth.js.org/configuration/options#secret
NEXTAUTH_SECRET=""
Expand Down
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
# production
/build

# docker
Dockerfile*
docker-compose*

# misc
.DS_Store
*.pem
Expand All @@ -28,6 +32,15 @@ yarn-error.log*
# local env files
.env.local
.env
# keep example env tracked
!.env.example

# editors
.idea/
.vscode/

# prisma local db files
prisma/*.db
# vercel
.vercel

Expand Down
5 changes: 0 additions & 5 deletions .vscode/settings.json

This file was deleted.

63 changes: 63 additions & 0 deletions DEPLOY-EASYPANEL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Deploy to Easypanel

This repo is Easypanel-ready. It includes a production Dockerfile, a healthcheck route, and an example env file.

## What Easypanel needs
- Source: Connect your GitHub repo and select this project.
- Builder: Dockerfile (recommended). Root directory is the repository root.
- Port: 3000 (the app also respects the `PORT` environment variable).
- Environment Variables: Provide the ones listed below.
- Database: Create a Postgres service in Easypanel and set `DATABASE_URL`.

## Environment variables
Set these in the App -> Environment tab:

Required
- `DATABASE_URL`
- `OPENROUTER_API_KEY` (or any required provider key for your usage)
- `NEXTAUTH_URL`
- `NEXTAUTH_SECRET`

Optional
- `GROQ_API_KEY`
- `GOOGLE_CLIENT_ID`
- `GOOGLE_CLIENT_SECRET`
- `UNSPLASH_ACCESS_KEY`
- `TAVILY_API_KEY`

See `.env.example` for a quick reference.

## Healthcheck
The container exposes `/api/health`. Configure Easypanel’s healthcheck to GET `http://localhost:3000/api/health`.

## Database schema (Prisma)
For the initial deploy, run the schema sync once:
- In the app container shell: `pnpm prisma db push`

You can also set up a one-off command in Easypanel after the first deployment.

## Build and run
- Dockerfile: multi-stage build; outputs a standalone Next.js server and runs `node server.js`.
- The Dockerfile sets `SKIP_ENV_VALIDATION=1` during build to avoid strict env validation.
- Exposes port `3000` and honors `PORT`.

## Images and static assets
Next.js remote images are configured in `next.config.js` via `images.remotePatterns`. Adjust if your deployment needs additional hosts.

## Troubleshooting
- Prisma/sharp native deps: We use Debian slim to avoid Alpine musl issues.
- Ensure `NEXTAUTH_URL` matches your public domain and HTTPS is enabled in Easypanel.
- If the app boots but returns 500s, verify all required env vars and that `DATABASE_URL` is reachable from the app container.

---

## Deploy steps summary
1. Push this branch to GitHub and set it as the deployment branch (or merge to `main`).
2. In Easypanel, create a new App service:
- Source: GitHub
- Builder: Dockerfile
- Root: repository root
- Port: 3000
3. Create a Postgres service; copy its internal connection string to the App’s `DATABASE_URL`.
4. Fill in env vars and Deploy.
5. (One-time) Run `pnpm prisma db push` to create tables.
78 changes: 78 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# syntax=docker/dockerfile:1.7

# Multi-stage Dockerfile for Next.js (App Router) with pnpm and Prisma
# Safe base: Debian slim (avoids Alpine musl issues with Prisma/sharp)

ARG NODE_VERSION=20

FROM node:${NODE_VERSION}-bookworm-slim AS base
ENV NODE_ENV=production \
NEXT_TELEMETRY_DISABLED=1
WORKDIR /app

# Install system deps commonly needed by Next.js/Prisma/sharp
RUN apt-get update -y \
&& apt-get install -y --no-install-recommends \
ca-certificates \
openssl \
git \
&& rm -rf /var/lib/apt/lists/*

# Enable corepack to use pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate

# --- Dependencies ---
FROM base AS deps
# Copy only manifest files to leverage Docker layer caching
COPY package.json pnpm-lock.yaml ./
COPY prisma ./prisma
RUN --mount=type=cache,id=pnpm-store,target=/root/.local/share/pnpm/store \
pnpm install --frozen-lockfile

# --- Build ---
FROM base AS build
ENV SKIP_ENV_VALIDATION=1
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Ensure Prisma client is generated during build (postinstall handles it, but safe to re-run)
RUN pnpm prisma generate || true
RUN pnpm build
# Create empty public folder if it doesn't exist to avoid copy errors
RUN mkdir -p public

# --- Runtime Image ---
FROM node:${NODE_VERSION}-bookworm-slim AS runner
ENV NODE_ENV=production \
NEXT_TELEMETRY_DISABLED=1 \
PORT=3000
WORKDIR /app

# System deps
RUN apt-get update -y \
&& apt-get install -y --no-install-recommends \
ca-certificates \
openssl \
&& rm -rf /var/lib/apt/lists/*

# Copy standalone server output and static assets
COPY --from=build /app/.next/standalone ./
COPY --from=build /app/.next/static ./.next/static
# Copy public folder (created as empty in build if it doesn't exist)
COPY --from=build /app/public ./public

# If your app uses Prisma at runtime, keep schema available (optional)
COPY --from=build /app/prisma ./prisma

# Copy entrypoint script
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh

# Expose the port (Easypanel will map this)
EXPOSE 3000

# Healthcheck hits Next.js API route we'll add at /api/health
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
CMD node -e "require('http').request({host:'127.0.0.1', port: process.env.PORT || 3000, path:'/api/health'}, res=>{process.exit(res.statusCode===200?0:1)}).on('error',()=>process.exit(1)).end()"

# Start using entrypoint that validates env vars
ENTRYPOINT ["docker-entrypoint.sh"]
21 changes: 21 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Pollinations Integration Documentation & Testing

## Task Overview
Create comprehensive documentation for Pollinations API integration and test which models work for text and image generation.

## Steps

- [ ] Research Pollinations API documentation and capabilities
- [ ] Create comprehensive connection documentation
- [ ] Test text generation models
- [ ] Test image generation models
- [ ] Document working vs non-working models
- [ ] Create implementation examples
- [ ] Test integration in the existing project
- [ ] Final documentation review and cleanup

## Expected Deliverables
- Complete Pollinations integration guide
- Model compatibility matrix
- Working code examples
- Test results documentation
42 changes: 42 additions & 0 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/sh
set -e

echo "🚀 Starting Next.js application..."
echo "📍 Port: ${PORT:-3000}"
echo "🔗 NEXTAUTH_URL: ${NEXTAUTH_URL:-NOT SET}"

# Check required environment variables
if [ -z "$NEXTAUTH_URL" ]; then
echo "❌ ERROR: NEXTAUTH_URL environment variable is required but not set!"
echo "Please set it in Easypanel App > Environment section"
exit 1
fi

if [ -z "$NEXTAUTH_SECRET" ]; then
echo "❌ ERROR: NEXTAUTH_SECRET environment variable is required but not set!"
exit 1
fi

if [ -z "$DATABASE_URL" ]; then
echo "❌ ERROR: DATABASE_URL environment variable is required but not set!"
exit 1
fi

if [ -z "$OPENROUTER_API_KEY" ]; then
echo "⚠️ WARNING: OPENROUTER_API_KEY not set - AI features may not work"
fi

echo "✅ Environment variables validated"

# Initialize database schema
echo "📊 Initializing database schema..."
cd /app
npx prisma db push --skip-generate --accept-data-loss || echo "⚠️ DB schema sync failed or already up to date"

echo "🎯 Starting server on port ${PORT:-3000}..."

# Export HOSTNAME for Next.js standalone to bind to all interfaces
export HOSTNAME="0.0.0.0"

# Start the Next.js standalone server
exec node server.js
1 change: 1 addition & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ await import("./src/env.js");

/** @type {import("next").NextConfig} */
const config = {
output: "standalone",
images: {
remotePatterns: [
{
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
"build": "next build --turbo",
"db:push": "prisma db push",
"db:studio": "prisma studio",
"dev": "next dev --turbo",
"dev": "next dev --turbo -p 7888",
"postinstall": "prisma generate",
"lint": "biome lint .",
"lint:fix": "biome lint --write .",
"check": "biome check .",
"check:fix": "biome check --write .",
"start": "next start",
"start": "next start -p ${PORT:-3000}",
"type": "tsc --noEmit"
},
"dependencies": {
Expand Down
24 changes: 24 additions & 0 deletions pollinations-research.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Pollinations API Research

## Current Understanding
- **Image Generation**: Fully implemented and working with URL-based API
- **Text Generation**: Partial implementation in test files, needs verification
- **Repository**: https://github.com/pollinations/pollinations

## API Endpoints Found

### Text Generation
- `https://text.pollinations.ai/{prompt}`
- `https://text.pollinations.ai/openai` (OpenAI-compatible)
- Base URL: `https://text.pollinations.ai`

### Image Generation
- `https://image.pollinations.ai/prompt/{encodedPrompt}?width=1024&height=768&model={model}`
- Base URL: `https://image.pollinations.ai`

## Research Tasks
1. ✅ Identified existing test script
2. ✅ Found current implementation
3. 🔄 Need to test all endpoints
4. 🔄 Need to verify available models
5. 🔄 Need to check text generation capabilities
12 changes: 6 additions & 6 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ generator client {
}

datasource db {
provider = "postgresql"
provider = "sqlite"
// NOTE: When using mysql or sqlserver, uncomment the @db.Text annotations in model Account below
// Further reading:
// https://next-auth.js.org/adapters/prisma#create-the-prisma-schema
// https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#string
url = env("DATABASE_URL")
url = "file:./dev.db"
}

// Necessary for Next auth
Expand Down Expand Up @@ -45,9 +45,9 @@ model User {
image String?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
headline String? @db.VarChar(100)
bio String? @db.Text
interests String[]
headline String?
bio String?
interests Json?
location String?
website String?
accounts Account[]
Expand Down Expand Up @@ -103,7 +103,7 @@ model Presentation {
prompt String? // The prompt used for generating the presentation
presentationStyle String? // The style of the presentation
language String? @default("en-US") // The language of the presentation
outline String[] // Store the presentation outline
outline Json? // Store the presentation outline
searchResults Json? // Store the search results
base BaseDocument @relation(fields: [id], references: [id], onDelete: Cascade)
templateId String?
Expand Down
Loading