new file: .dockerignore
new file: .env.example new file: Dockerfile modified: backend/.env.example modified: backend/package.json renamed: backend/src/migrations/run.ts -> backend/src/scripts/run.ts renamed: backend/src/migrations/seed.ts -> backend/src/scripts/seed.ts new file: docker-compose.external-db.yml new file: docker-compose.yml
This commit is contained in:
44
.dockerignore
Normal file
44
.dockerignore
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Dependencies
|
||||||
|
node_modules
|
||||||
|
**/node_modules
|
||||||
|
|
||||||
|
# Build outputs (will be rebuilt in container)
|
||||||
|
dist
|
||||||
|
**/dist
|
||||||
|
build
|
||||||
|
**/build
|
||||||
|
|
||||||
|
# Git
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
logs
|
||||||
|
|
||||||
|
# Environment files
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Test files
|
||||||
|
coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Project-specific (not needed in app container)
|
||||||
|
.claude
|
||||||
|
.git_backup
|
||||||
|
db_connections
|
||||||
|
final_endpoints_v2
|
||||||
|
nowContext
|
||||||
|
queries
|
||||||
29
.env.example
Normal file
29
.env.example
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# ============================================
|
||||||
|
# KIS API Builder - Configuration
|
||||||
|
# ============================================
|
||||||
|
# Copy this file to .env and adjust values
|
||||||
|
#
|
||||||
|
# For default setup (built-in DB):
|
||||||
|
# Only APP_PORT, DB_PASSWORD and JWT_SECRET are needed
|
||||||
|
#
|
||||||
|
# For external database:
|
||||||
|
# Set all DB_* variables
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
# External port (access from host machine)
|
||||||
|
APP_PORT=3000
|
||||||
|
|
||||||
|
# Database password (used by both built-in and external DB)
|
||||||
|
DB_PASSWORD=your_secure_password_here
|
||||||
|
|
||||||
|
# JWT Configuration
|
||||||
|
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
|
||||||
|
JWT_EXPIRES_IN=24h
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# External Database (only for docker-compose.external-db.yml)
|
||||||
|
# ============================================
|
||||||
|
# DB_HOST=your-postgres-host
|
||||||
|
# DB_PORT=5432
|
||||||
|
# DB_NAME=api_builder
|
||||||
|
# DB_USER=postgres
|
||||||
68
Dockerfile
Normal file
68
Dockerfile
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
# ============================================
|
||||||
|
# Stage 1: Build Frontend
|
||||||
|
# ============================================
|
||||||
|
FROM node:20-alpine AS frontend-builder
|
||||||
|
|
||||||
|
WORKDIR /app/frontend
|
||||||
|
|
||||||
|
# Copy frontend package files
|
||||||
|
COPY frontend/package*.json ./
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# Copy frontend source
|
||||||
|
COPY frontend/ ./
|
||||||
|
|
||||||
|
# Build frontend
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Stage 2: Build Backend
|
||||||
|
# ============================================
|
||||||
|
FROM node:20-alpine AS backend-builder
|
||||||
|
|
||||||
|
WORKDIR /app/backend
|
||||||
|
|
||||||
|
# Copy backend package files
|
||||||
|
COPY backend/package*.json ./
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# Copy backend source
|
||||||
|
COPY backend/ ./
|
||||||
|
|
||||||
|
# Build TypeScript
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Stage 3: Production
|
||||||
|
# ============================================
|
||||||
|
FROM node:20-alpine AS production
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy backend package files and install production deps
|
||||||
|
COPY backend/package*.json ./
|
||||||
|
RUN npm ci --only=production && npm cache clean --force
|
||||||
|
|
||||||
|
# Copy built backend
|
||||||
|
COPY --from=backend-builder /app/backend/dist ./dist
|
||||||
|
|
||||||
|
# Copy built frontend to the location expected by backend
|
||||||
|
COPY --from=frontend-builder /app/frontend/dist ./frontend/dist
|
||||||
|
|
||||||
|
# Set environment
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
ENV PORT=3000
|
||||||
|
|
||||||
|
# Expose port
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
|
||||||
|
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
|
||||||
|
|
||||||
|
# Start the application
|
||||||
|
CMD ["node", "dist/server.js"]
|
||||||
@@ -15,31 +15,4 @@ JWT_EXPIRES_IN=24h
|
|||||||
|
|
||||||
# API Rate Limiting
|
# API Rate Limiting
|
||||||
RATE_LIMIT_WINDOW_MS=900000
|
RATE_LIMIT_WINDOW_MS=900000
|
||||||
RATE_LIMIT_MAX_REQUESTS=100
|
RATE_LIMIT_MAX_REQUESTS=100
|
||||||
|
|
||||||
# Target Databases Configuration (JSON format)
|
|
||||||
# This is where your API endpoints will execute queries
|
|
||||||
TARGET_DATABASES='[
|
|
||||||
{
|
|
||||||
"id": "main_postgres",
|
|
||||||
"name": "Main PostgreSQL",
|
|
||||||
"type": "postgresql",
|
|
||||||
"host": "localhost",
|
|
||||||
"port": 5432,
|
|
||||||
"database": "your_database",
|
|
||||||
"user": "your_user",
|
|
||||||
"password": "your_password",
|
|
||||||
"ssl": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "analytics_db",
|
|
||||||
"name": "Analytics Database",
|
|
||||||
"type": "postgresql",
|
|
||||||
"host": "localhost",
|
|
||||||
"port": 5432,
|
|
||||||
"database": "analytics",
|
|
||||||
"user": "analytics_user",
|
|
||||||
"password": "analytics_password",
|
|
||||||
"ssl": false
|
|
||||||
}
|
|
||||||
]'
|
|
||||||
@@ -7,8 +7,8 @@
|
|||||||
"dev": "nodemon",
|
"dev": "nodemon",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"start": "node dist/server.js",
|
"start": "node dist/server.js",
|
||||||
"migrate": "ts-node src/migrations/run.ts",
|
"migrate": "ts-node src/scripts/run.ts",
|
||||||
"seed": "ts-node src/migrations/seed.ts"
|
"seed": "ts-node src/scripts/seed.ts"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"api",
|
"api",
|
||||||
|
|||||||
@@ -6,14 +6,18 @@ async function runMigrations() {
|
|||||||
console.log('Running migrations...');
|
console.log('Running migrations...');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const migrationFile = fs.readFileSync(
|
const migrationsDir = path.join(__dirname, '../migrations');
|
||||||
path.join(__dirname, '001_initial_schema.sql'),
|
const files = fs.readdirSync(migrationsDir)
|
||||||
'utf-8'
|
.filter(f => f.endsWith('.sql'))
|
||||||
);
|
.sort();
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
console.log(` Running ${file}...`);
|
||||||
|
const sql = fs.readFileSync(path.join(migrationsDir, file), 'utf-8');
|
||||||
|
await mainPool.query(sql);
|
||||||
|
}
|
||||||
|
|
||||||
await mainPool.query(migrationFile);
|
|
||||||
console.log('✅ Migrations completed successfully');
|
console.log('✅ Migrations completed successfully');
|
||||||
|
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Migration failed:', error);
|
console.error('❌ Migration failed:', error);
|
||||||
29
docker-compose.external-db.yml
Normal file
29
docker-compose.external-db.yml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# ============================================
|
||||||
|
# KIS API Builder - External Database
|
||||||
|
# ============================================
|
||||||
|
# Use this when you have your own PostgreSQL
|
||||||
|
#
|
||||||
|
# 1. Copy .env.example to .env
|
||||||
|
# 2. Set DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD
|
||||||
|
# 3. Run: docker compose -f docker-compose.external-db.yml up -d
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: kis-api-builder-app
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "${APP_PORT:-3000}:3000"
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
PORT: 3000
|
||||||
|
DB_HOST: ${DB_HOST:?DB_HOST is required}
|
||||||
|
DB_PORT: ${DB_PORT:-5432}
|
||||||
|
DB_NAME: ${DB_NAME:-api_builder}
|
||||||
|
DB_USER: ${DB_USER:-postgres}
|
||||||
|
DB_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD is required}
|
||||||
|
JWT_SECRET: ${JWT_SECRET:-change-this-secret-in-production}
|
||||||
|
JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-24h}
|
||||||
63
docker-compose.yml
Normal file
63
docker-compose.yml
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# ============================================
|
||||||
|
# KIS API Builder - Docker Compose
|
||||||
|
# ============================================
|
||||||
|
# Default setup with built-in PostgreSQL
|
||||||
|
# Just run: docker compose up -d
|
||||||
|
#
|
||||||
|
# For external database, use:
|
||||||
|
# docker compose -f docker-compose.external-db.yml up -d
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
services:
|
||||||
|
# PostgreSQL Database (built-in)
|
||||||
|
db:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
container_name: kis-api-builder-db
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: api_builder
|
||||||
|
POSTGRES_USER: postgres
|
||||||
|
POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
|
||||||
|
volumes:
|
||||||
|
- postgres_data:/var/lib/postgresql/data
|
||||||
|
- ./backend/src/migrations:/docker-entrypoint-initdb.d:ro
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U postgres -d api_builder"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 10s
|
||||||
|
networks:
|
||||||
|
- kis-network
|
||||||
|
|
||||||
|
# Application (Backend + Frontend)
|
||||||
|
app:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: kis-api-builder-app
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "${APP_PORT:-3000}:3000"
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
PORT: 3000
|
||||||
|
DB_HOST: db
|
||||||
|
DB_PORT: 5432
|
||||||
|
DB_NAME: api_builder
|
||||||
|
DB_USER: postgres
|
||||||
|
DB_PASSWORD: ${DB_PASSWORD:-postgres}
|
||||||
|
JWT_SECRET: ${JWT_SECRET:-change-this-secret-in-production}
|
||||||
|
JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-24h}
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- kis-network
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
kis-network:
|
||||||
|
driver: bridge
|
||||||
Reference in New Issue
Block a user