Skip to content
Open
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
81 changes: 81 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Dependencies
node_modules
bun.lockb

# Build outputs
dist
build
.next

# Environment files
.env
.env.local
.env.*.local

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
bun-debug.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Coverage directory used by tools like istanbul
coverage
*.lcov

# IDE files
.vscode
.idea
*.swp
*.swo

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Git
.git
.gitignore

# Docker
Dockerfile*
docker-compose*
.dockerignore

# Documentation and README
README.md
*.md
docs

# Test files
tests
__tests__
*.test.ts
*.test.js
*.spec.ts
*.spec.js

# Development tools
.eslintrc*
.prettierrc*
jest.config*
tsconfig*.json

# Prisma migrations (if you don't want them in container)
# prisma/migrations

# Temporary files
tmp
temp
153 changes: 153 additions & 0 deletions DOCKER.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# Docker Setup for COC API

This guide explains how to containerize and run the COC API using Docker.

## Prerequisites

- Docker and Docker Compose installed
- `.env` file with required environment variables

## Environment Variables

Create a `.env` file in the project root with the following variables:

```env
DATABASE_URL=your_supabase_database_url
DIRECT_URL=your_supabase_direct_url
SUPABASE_URL=your_supabase_project_url
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key
NODE_ENV=production
PORT=3000
ALLOWED_ORIGINS=https://yourdomain.com
```

## Quick Start

### Automated Development Setup (Recommended)

For the easiest development experience, use the automation scripts:

```bash
# Start Supabase + extract env vars + start Docker dev container
./scripts/start-dev.sh

# View logs
./scripts/logs.sh

# Stop everything
./scripts/stop-dev.sh
```

See `scripts/README.md` for detailed documentation.

### Manual Development Setup

```bash
# Build and run development container
docker compose up -d coc-api-dev
```

## Build Targets

The Dockerfile includes multiple stages:

- **`base`**: Alpine Node + Bun installation
- **`deps`**: Dependencies and Prisma client generation
- **`development`**: Development setup with source mounting
- **`production`**: Optimized production build

### Building Specific Targets

```bash
# Development build
docker build --target development -t coc-api:dev .

# Production build (default)
docker build --target production -t coc-api:prod .
```


## Health Check

The container includes a health check endpoint:

```bash
# Check container health
curl http://localhost:3000/api/v1/health

# Response
{
"status": "OK",
"message": "COC API is running",
"timestamp": "2024-01-01T00:00:00.000Z",
"uptime": 3600
}
```

## Docker Compose Commands

```bash
# Start production services
docker compose up -d

# Start development services
docker compose --profile dev up -d

# View logs
docker compose logs -f coc-api

# Stop services
docker compose down

# Rebuild services
docker compose up -d --build
```

## Optimization Features

- **Multi-stage builds** for smaller production images
- **Layer caching** for faster rebuilds
- **Non-root user** for security
- **Alpine Linux** for minimal image size
- **Bun** for fast JavaScript runtime
- **Health checks** for container monitoring

## Troubleshooting

### Container won't start

1. Check environment variables are set correctly
2. Verify Supabase connection details
3. Check logs: `docker-compose logs coc-api`

### Prisma issues

1. Ensure DATABASE_URL is accessible from container
2. Run `docker-compose exec coc-api bunx prisma generate`
3. Check if migrations need to be applied

### Port conflicts

1. Change port mapping in docker-compose.yml
2. Or use different ports: `docker run -p 8080:3000 coc-api`

## Production Deployment

For production deployment:

1. Use production target: `--target production`
2. Set `NODE_ENV=production`
3. Use proper secrets management
4. Configure reverse proxy (nginx/traefik)
5. Set up monitoring and logging
6. Use Docker Swarm or Kubernetes for orchestration

## File Structure

```
.
├── Dockerfile # Multi-stage Dockerfile
├── docker-compose.yml # Compose configuration
├── .dockerignore # Build context exclusions
└── DOCKER.md # This documentation
```
115 changes: 115 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Multi-stage build for production optimization
FROM node:18-alpine AS base

# Install system dependencies
RUN apk add --no-cache curl bash unzip

# Install Bun with explicit verification
RUN curl -fsSL https://bun.sh/install | bash && \
echo "Checking Bun installation..." && \
ls -la /root/.bun/ || echo "No .bun directory found" && \
find /root -name "bun" -type f 2>/dev/null || echo "No bun binary found"

# Set PATH for Bun
ENV PATH="/root/.bun/bin:$PATH"

# Verify Bun installation and create bunx symlink if needed
RUN if [ -f /root/.bun/bin/bun ]; then \
/root/.bun/bin/bun --version && \
if [ ! -f /root/.bun/bin/bunx ]; then \
ln -s /root/.bun/bin/bun /root/.bun/bin/bunx; \
fi; \
else \
echo "ERROR: Bun not installed properly" && exit 1; \
fi

# Set working directory
WORKDIR /app

# ================================
# Dependencies stage - for caching
# ================================
FROM base AS deps

# Copy package files for dependency installation
COPY package.json bun.lock* ./
COPY prisma ./prisma

# Install dependencies with Bun
RUN bun install --frozen-lockfile

# Generate Prisma client with correct binary targets
RUN bunx prisma generate

# ================================
# Development stage
# ================================
FROM base AS development

# Copy node_modules from deps stage
COPY --from=deps /app/node_modules ./node_modules
COPY --from=deps /app/src/generated ./src/generated

# Copy source code
COPY . .

# Expose port
EXPOSE 3000

# Development command (skip migrations for now)
CMD ["bun", "src/server.ts"]

# ================================
# Production build stage
# ================================
FROM base AS builder

# Copy node_modules and generated files from deps stage
COPY --from=deps /app/node_modules ./node_modules
COPY --from=deps /app/src/generated ./src/generated

# Copy source code
COPY . .

# Build the application (if needed - Bun can run TS directly)
# RUN bun build src/server.ts --outdir=dist --target=node

# ================================
# Production stage
# ================================
FROM base AS production

# Create non-root user for security
RUN addgroup -g 1001 -S nodejs && \
adduser -S bunjs -u 1001

# Copy Bun installation to accessible location
RUN cp -r /root/.bun /usr/local/bun && \
chown -R bunjs:nodejs /usr/local/bun

# Copy only production dependencies and generated files
COPY --from=deps --chown=bunjs:nodejs /app/node_modules ./node_modules
COPY --from=deps --chown=bunjs:nodejs /app/src/generated ./src/generated

# Copy source code and config files
COPY --chown=bunjs:nodejs src ./src
COPY --chown=bunjs:nodejs package.json ./
COPY --chown=bunjs:nodejs prisma ./prisma

# Switch to non-root user
USER bunjs

# Set environment variables for bunjs user
ENV NODE_ENV=production
ENV PORT=3000
ENV PATH="/usr/local/bun/bin:$PATH"

# Expose port
EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1

# Production command with migrations
CMD ["sh", "-c", "bun src/server.ts"]
Loading