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:
2025-12-18 13:01:25 +03:00
parent 12736f5b79
commit 9a08396610
9 changed files with 246 additions and 36 deletions

44
.dockerignore Normal file
View 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
View 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
View 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"]

View File

@@ -16,30 +16,3 @@ 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
}
]'

View File

@@ -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",

View File

@@ -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);

View 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
View 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