docker + update readme

This commit is contained in:
Maze Winther 2026-02-23 09:38:38 +01:00
parent 86a3592c88
commit dbfecbba59
5 changed files with 203 additions and 82 deletions

15
.dockerignore Normal file
View File

@ -0,0 +1,15 @@
node_modules
.next
.git
.gitignore
*.md
.env*
!.env.example
.cursor
.vscode
diffs
docs
agent-transcripts
mcps
terminals
apps/web/.font-cache

104
README.md
View File

@ -38,110 +38,52 @@
### Prerequisites
Before you begin, ensure you have the following installed on your system:
- [Node.js](https://nodejs.org/en/) (v18 or later)
- [Bun](https://bun.sh/docs/installation)
(for `npm` alternative)
- [Docker](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/install/)
> **Note:** Docker is optional, but it's essential for running the local database and Redis services. If you're planning to run the frontend or want to contribute to frontend features, you can skip the Docker setup. If you have followed the steps below in [Setup](#setup), you're all set to go!
> **Note:** Docker is optional but recommended for running the local database and Redis. If you only want to work on frontend features, you can skip it.
### Setup
1. Fork the repository
2. Clone your fork locally
3. Navigate to the web app directory: `cd apps/web`
4. Copy `.env.example` to `.env.local`:
1. Fork and clone the repository
2. Copy the environment file:
```bash
# Unix/Linux/Mac
cp .env.example .env.local
# Windows Command Prompt
copy .env.example .env.local
cp apps/web/.env.example apps/web/.env.local
# Windows PowerShell
Copy-Item .env.example .env.local
Copy-Item apps/web/.env.example apps/web/.env.local
```
5. Install dependencies: `bun install`
6. Start the development server: `bun dev`
## Development Setup
### Local Development
1. Start the database and Redis services:
3. Start the database and Redis:
```bash
# From project root
docker-compose up -d
docker compose up -d db redis serverless-redis-http
```
2. Navigate to the web app directory:
4. Install dependencies and start the dev server:
```bash
cd apps/web
bun install
bun dev:web
```
3. Copy `.env.example` to `.env.local`:
```bash
# Unix/Linux/Mac
cp .env.example .env.local
# Windows Command Prompt
copy .env.example .env.local
# Windows PowerShell
Copy-Item .env.example .env.local
```
4. Configure required environment variables in `.env.local`:
**Required Variables:**
```bash
# Database (matches docker-compose.yaml)
DATABASE_URL="postgresql://opencut:opencut@localhost:5432/opencut"
# Generate a secure secret for Better Auth
BETTER_AUTH_SECRET="your-generated-secret-here"
BETTER_AUTH_URL="http://localhost:3000"
# Redis (matches docker-compose.yaml)
UPSTASH_REDIS_REST_URL="http://localhost:8079"
UPSTASH_REDIS_REST_TOKEN="example_token"
# Marble Blog
MARBLE_WORKSPACE_KEY=cm6ytuq9x0000i803v0isidst # example organization key
NEXT_PUBLIC_MARBLE_API_URL=https://api.marblecms.com
# Development
NODE_ENV="development"
```
**Generate BETTER_AUTH_SECRET:**
```bash
# Unix/Linux/Mac
openssl rand -base64 32
# Windows PowerShell (simple method)
[System.Web.Security.Membership]::GeneratePassword(32, 0)
# Cross-platform (using Node.js)
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
# Or use an online generator: https://generate-secret.vercel.app/32
```
5. Run database migrations: `bun run db:migrate` from (inside apps/web)
6. Start the development server: `bun run dev` from (inside apps/web)
The application will be available at [http://localhost:3000](http://localhost:3000).
The `.env.example` has sensible defaults that match the Docker Compose config — it should work out of the box.
### Self-Hosting with Docker
To run everything (including a production build of the app) in Docker:
```bash
docker compose up -d
```
The app will be available at [http://localhost:3100](http://localhost:3100).
## Contributing
We welcome contributions! While we're actively developing and refactoring certain areas, there are plenty of opportunities to contribute effectively.

View File

@ -13,7 +13,7 @@ DATABASE_URL="postgresql://opencut:opencut@localhost:5432/opencut"
BETTER_AUTH_SECRET=your_better_auth_secret
UPSTASH_REDIS_REST_URL=http://localhost:8079
UPSTASH_REDIS_REST_TOKEN=example_token_here
UPSTASH_REDIS_REST_TOKEN=example_token
MARBLE_WORKSPACE_KEY=your_workspace_key_here

70
apps/web/Dockerfile Normal file
View File

@ -0,0 +1,70 @@
FROM oven/bun:alpine AS base
FROM base AS builder
WORKDIR /app
ARG FREESOUND_CLIENT_ID
ARG FREESOUND_API_KEY
COPY package.json package.json
COPY bun.lock bun.lock
COPY turbo.json turbo.json
COPY apps/web/package.json apps/web/package.json
COPY packages/env/package.json packages/env/package.json
COPY packages/ui/package.json packages/ui/package.json
RUN bun install
COPY apps/web/ apps/web/
COPY packages/env/ packages/env/
COPY packages/ui/ packages/ui/
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
# Build-time env stubs to pass zod validation
ENV DATABASE_URL="postgresql://opencut:opencut@localhost:5432/opencut"
ENV BETTER_AUTH_SECRET="build-time-secret"
ENV UPSTASH_REDIS_REST_URL="http://localhost:8079"
ENV UPSTASH_REDIS_REST_TOKEN="example_token"
ENV NEXT_PUBLIC_SITE_URL="http://localhost:3000"
ENV NEXT_PUBLIC_MARBLE_API_URL="https://api.marblecms.com"
ENV MARBLE_WORKSPACE_KEY="build-placeholder"
ENV CLOUDFLARE_ACCOUNT_ID="build-placeholder"
ENV R2_ACCESS_KEY_ID="build-placeholder"
ENV R2_SECRET_ACCESS_KEY="build-placeholder"
ENV R2_BUCKET_NAME="build-placeholder"
ENV MODAL_TRANSCRIPTION_URL="http://localhost:0"
ENV FREESOUND_CLIENT_ID=$FREESOUND_CLIENT_ID
ENV FREESOUND_API_KEY=$FREESOUND_API_KEY
WORKDIR /app/apps/web
RUN bun run build
# Production image
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static
RUN chown nextjs:nodejs apps
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["bun", "apps/web/server.js"]

94
docker-compose.yml Normal file
View File

@ -0,0 +1,94 @@
services:
db:
image: postgres:17
restart: unless-stopped
environment:
POSTGRES_USER: opencut
POSTGRES_PASSWORD: opencut
POSTGRES_DB: opencut
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U opencut"]
interval: 30s
timeout: 10s
retries: 5
start_period: 10s
redis:
image: redis:7-alpine
restart: unless-stopped
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 10s
retries: 5
start_period: 10s
serverless-redis-http:
image: hiett/serverless-redis-http:latest
ports:
- "8079:80"
environment:
SRH_MODE: env
SRH_TOKEN: example_token
SRH_CONNECTION_STRING: "redis://redis:6379"
depends_on:
redis:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "wget --spider -q http://127.0.0.1:80 || exit 1"]
interval: 30s
timeout: 10s
retries: 5
start_period: 10s
web:
build:
context: .
dockerfile: ./apps/web/Dockerfile
args:
- FREESOUND_CLIENT_ID=${FREESOUND_CLIENT_ID}
- FREESOUND_API_KEY=${FREESOUND_API_KEY}
restart: unless-stopped
ports:
- "3100:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://opencut:opencut@db:5432/opencut
- BETTER_AUTH_SECRET=your-production-secret-key-here
- UPSTASH_REDIS_REST_URL=http://serverless-redis-http:80
- UPSTASH_REDIS_REST_TOKEN=example_token
- NEXT_PUBLIC_SITE_URL=http://localhost:3100
- NEXT_PUBLIC_MARBLE_API_URL=https://api.marblecms.com
- MARBLE_WORKSPACE_KEY=${MARBLE_WORKSPACE_KEY:-placeholder}
- FREESOUND_CLIENT_ID=${FREESOUND_CLIENT_ID}
- FREESOUND_API_KEY=${FREESOUND_API_KEY}
# Transcription (Optional - leave blank to disable auto-captions)
- CLOUDFLARE_ACCOUNT_ID=${CLOUDFLARE_ACCOUNT_ID:-placeholder}
- R2_ACCESS_KEY_ID=${R2_ACCESS_KEY_ID:-placeholder}
- R2_SECRET_ACCESS_KEY=${R2_SECRET_ACCESS_KEY:-placeholder}
- R2_BUCKET_NAME=${R2_BUCKET_NAME:-opencut-transcription}
- MODAL_TRANSCRIPTION_URL=${MODAL_TRANSCRIPTION_URL:-http://localhost:0}
depends_on:
db:
condition: service_healthy
serverless-redis-http:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000/api/health || exit 1"]
interval: 30s
timeout: 10s
retries: 5
start_period: 30s
volumes:
postgres_data:
networks:
default:
name: opencut-network