Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to PostgreSQL and Railway #101

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 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
18 changes: 0 additions & 18 deletions .github/workflows/fly-deploy.yml

This file was deleted.

26 changes: 26 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Tests
on:
pull_request:
push:
branches:
- main

jobs:
test:
name: Run Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Start PostgreSQL and run tests
run: |
# Build and run the test service with Docker Compose
docker-compose up --build --exit-code-from test test
env:
# Set environment variables for the test
NODE_ENV: test
DATABASE_URL: postgresql://postgres:postgres@postgres_test:5432/test
121 changes: 52 additions & 69 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,86 +1,69 @@
# Build stage
FROM node:20 AS builder
# Base stage with common dependencies
FROM oven/bun:1.0.27-alpine as base

# Enable Corepack for package manager versioning
ENV BUN_HOME="/bun"
ENV PATH="$BUN_HOME:$PATH"
RUN corepack enable

# Builder stage for pruning the monorepo
FROM base AS pruner
WORKDIR /app

# Install build dependencies
RUN apt-get update && \
apt-get install -y --no-install-recommends \
python3 \
make \
g++ \
&& rm -rf /var/lib/apt/lists/* && \
apt-get clean

# Copy package files for dependency installation
COPY package.json ./
COPY frontend/package.json ./frontend/
COPY backend/package.json ./backend/
COPY backend/drizzle.config.ts ./backend/
# Install turbo globally
RUN bun install -g turbo@latest
COPY . .

# Disable telemetry and prune the monorepo to include only what's needed
RUN turbo telemetry disable
# Prune the monorepo to include only backend and frontend
RUN turbo prune --scope=@curatedotfun/backend --scope=@curatedotfun/frontend --docker

# Builder stage for installing dependencies and building
FROM base AS builder
WORKDIR /app

# Copy pruned package.json files and lockfile
COPY --from=pruner /app/out/json/ .
COPY --from=pruner /app/out/bun.lockb ./bun.lockb
COPY --from=pruner /app/turbo.json ./turbo.json

# Install dependencies
RUN cd frontend && npm install
RUN cd backend && npm install
RUN bun install --frozen-lockfile

# Copy source code after dependency installation
COPY frontend ./frontend
COPY backend ./backend
COPY curate.config.json ./
# Copy source code from pruned monorepo
COPY --from=pruner /app/out/full/ .

# Build backend (rspack will copy frontend dist to backend/dist/public)
# Build the application
ENV NODE_ENV="production"
# Build frontend first since backend depends on it
RUN cd frontend && npm run build
# Then build backend which will copy frontend dist
RUN cd backend && npm run build
RUN bun run build

# Production stage
FROM node:20-slim AS production
FROM oven/bun:1.0.27-alpine AS production
WORKDIR /app

# Install LiteFS and runtime dependencies
RUN apt-get update -y && \
apt-get install -y --no-install-recommends \
ca-certificates \
curl \
fuse3 \
sqlite3 \
python3 \
make \
g++ \
awscli \
&& rm -rf /var/lib/apt/lists/* && \
apt-get clean

# Copy LiteFS binary
COPY --from=flyio/litefs:0.5 /usr/local/bin/litefs /usr/local/bin/litefs

# Create directories for mounts with correct permissions
RUN mkdir -p /litefs /var/lib/litefs && \
chown -R node:node /litefs /var/lib/litefs

# Create volume mount points
ENV DATABASE_URL="file:/litefs/db"

# Copy application files
COPY --from=builder --chown=node:node /app/backend/dist ./backend/dist
COPY --from=builder --chown=node:node /app/backend/package.json ./backend/package.json
COPY --from=builder --chown=node:node /app/backend/drizzle.config.ts ./backend/drizzle.config.ts
COPY --from=builder --chown=node:node /app/backend/src ./backend/src
COPY --chown=node:node curate.config.json ./
COPY --chown=node:node package.json ./

# Install production dependencies
RUN cd backend && npm install && npm rebuild better-sqlite3

# Copy LiteFS configuration
COPY --chown=node:node litefs.yml /etc/litefs.yml
# Create a non-root user for security
RUN addgroup -S app && adduser -S app -G app

# Copy only the necessary files from the builder stage
COPY --from=builder --chown=app:app /app/backend/dist ./backend/dist
COPY --from=builder --chown=app:app /app/backend/package.json ./backend/package.json
COPY --from=builder --chown=app:app /app/backend/drizzle.config.ts ./backend/drizzle.config.ts
COPY --from=builder --chown=app:app /app/package.json ./
COPY --from=builder --chown=app:app /app/bun.lockb ./
COPY --chown=app:app curate.config.json ./

# Install only production dependencies
RUN cd backend && bun install --production

# Use the non-root user
USER app

# Expose the port
EXPOSE 3000

# Set secure environment defaults
ENV NODE_ENV=production \
NPM_CONFIG_LOGLEVEL=warn
ENV NODE_ENV=production

# Start LiteFS (runs app with distributed file system for SQLite)
ENTRYPOINT ["litefs", "mount"]
# Start the application
CMD ["bun", "run", "--cwd", "backend", "start"]
10 changes: 3 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,7 @@ graph TD
%% Content Sources
subgraph Sources["Content Sources"]
Twitter["Twitter Source Plugin"]
Telegram["Telegram Source Plugin"]
LinkedIn["LinkedIn Source Plugin (Planned)"]
style Twitter color:black
style Telegram color:black
style LinkedIn color:black
end

%% Submission Processing
Expand Down Expand Up @@ -105,11 +101,11 @@ graph TD

%% Distributor Plugins
subgraph Distributors["Distributor Plugins"]
TelegramDist["Telegram"]
Telegram["Telegram"]
RSS["RSS"]
Notion["Notion"]
Supabase["Supabase"]
style TelegramDist color:black
style Telegram color:black
style RSS color:black
style Notion color:black
style Supabase color:black
Expand All @@ -130,7 +126,7 @@ graph TD
classDef process fill:#bfb,stroke:#333,stroke-width:1px

class SubmissionService,ProcessorService,DistributionService service
class Twitter,Telegram,LinkedIn,TelegramDist,RSS,Notion,Supabase plugin
class Twitter,Telegram,RSS,Notion,Supabase plugin
class Moderation,GlobalTransform,DistTransform process
```

Expand Down
1 change: 0 additions & 1 deletion backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@ NODE_ENV=development

# Telegram Distributor Configuration
TELEGRAM_BOT_TOKEN=your_bot_token
TELEGRAM_CHANNEL_ID=your_channel_id
13 changes: 13 additions & 0 deletions backend/.env.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Test environment configuration
NODE_ENV=test

# Database configuration for PostgreSQL
DATABASE_URL=postgresql://postgres:postgres@localhost:54321/test
DATABASE_WRITE_URL=postgresql://postgres:postgres@localhost:54321/test
DATABASE_READ_URL=postgresql://postgres:postgres@localhost:54321/test

# Log level
LOG_LEVEL=error

# Test-specific settings
TEST_MODE=true
Loading
Loading