Skip to content
Closed
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
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
.next
.git
*.md
!README.md
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ yarn-error.log*
# env files
.env*
!.env.example
!.env.docker

# vercel
.vercel
Expand Down
55 changes: 55 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# ── Stage 1: Install dependencies ─────────────────────────────────
FROM oven/bun:1 AS deps

WORKDIR /app

COPY package.json bun.lock bunfig.toml ./
COPY apps/web/package.json apps/web/

RUN bun install --frozen-lockfile

# ── Stage 2: Build the Next.js app ───────────────────────────────
FROM oven/bun:1 AS builder

WORKDIR /app

COPY --from=deps /app/node_modules ./node_modules
COPY . .

# Generate Prisma client and build
WORKDIR /app/apps/web
RUN bunx prisma generate
RUN bun run build

WORKDIR /app

# ── Stage 3: Production runner ───────────────────────────────────
FROM oven/bun:1-slim AS runner

WORKDIR /app

ENV NODE_ENV=production
ENV HOSTNAME="0.0.0.0"
ENV PORT=3000

# Copy standalone Next.js output (includes server + minimal node_modules)
COPY --from=builder /app/apps/web/.next/standalone ./
COPY --from=builder /app/apps/web/.next/static ./apps/web/.next/static
COPY --from=builder /app/apps/web/public ./apps/web/public

# Copy Prisma schema + migrations for runtime migrate
COPY --from=builder /app/apps/web/prisma ./apps/web/prisma

# Copy generated Prisma client
COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma
COPY --from=builder /app/node_modules/@prisma ./node_modules/@prisma
COPY --from=builder /app/node_modules/prisma ./node_modules/prisma

# Copy entrypoint script
COPY docker-entrypoint.sh /app/docker-entrypoint.sh
RUN chmod +x /app/docker-entrypoint.sh

EXPOSE 3000

ENTRYPOINT ["/app/docker-entrypoint.sh"]
CMD ["bun", "apps/web/server.js"]
39 changes: 39 additions & 0 deletions apps/web/.env.docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# ──────────────────────────────────────────────
# Docker Compose environment template
# ──────────────────────────────────────────────
# Copy this file to apps/web/.env before running docker compose up:
# cp apps/web/.env.docker apps/web/.env
# Then fill in the placeholder values below.

# ──────────────────────────────────────────────
# Database (pre-configured for Docker networking)
# ──────────────────────────────────────────────
DATABASE_URL=postgresql://postgres:postgres@postgres:5432/better_hub

# ──────────────────────────────────────────────
# Redis (pre-configured for Docker networking)
# ──────────────────────────────────────────────
UPSTASH_REDIS_REST_URL=http://redis-rest:80
UPSTASH_REDIS_REST_TOKEN=local_token

# ──────────────────────────────────────────────
# Authentication (required — fill these in)
# ──────────────────────────────────────────────
# Create a GitHub OAuth App: https://github.com/settings/developers
# Set the callback URL to http://localhost:3000/api/auth/callback/github
GITHUB_CLIENT_ID=your_github_oauth_client_id
GITHUB_CLIENT_SECRET=your_github_oauth_client_secret

# Random 32-char string for session encryption
# Generate with: openssl rand -hex 16
BETTER_AUTH_SECRET=change_me_to_a_random_secret

# Base URL of the app
BETTER_AUTH_URL=http://localhost:3000
NEXT_PUBLIC_APP_URL=http://localhost:3000

# ──────────────────────────────────────────────
# AI — Ghost assistant (optional)
# ──────────────────────────────────────────────
# OPEN_ROUTER_API_KEY=your_open_router_api_key
# ANTHROPIC_API_KEY=your_anthropic_api_key
1 change: 1 addition & 0 deletions apps/web/next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const KNOWN_ROUTES = [
];

const nextConfig: NextConfig = {
output: "standalone",
devIndicators: false,
serverExternalPackages: ["@prisma/client"],
experimental: {
Expand Down
20 changes: 20 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
services:
app:
build:
context: .
dockerfile: Dockerfile
container_name: better-hub-app
restart: unless-stopped
ports:
- "3000:3000"
env_file: ./apps/web/.env
depends_on:
postgres:
condition: service_healthy
redis-rest:
condition: service_started

postgres:
image: postgres:16-alpine
container_name: better-hub-postgres
Expand All @@ -10,6 +25,11 @@ services:
POSTGRES_DB: better_hub
ports:
- "127.0.0.1:54320:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
volumes:
- postgres_data:/var/lib/postgresql/data

Expand Down
11 changes: 11 additions & 0 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh
set -e

# Run Prisma migrations on startup
echo "Running database migrations..."
cd /app/apps/web
bunx prisma migrate deploy
cd /app

echo "Starting application..."
exec "$@"