726 lines
17 KiB
Markdown
726 lines
17 KiB
Markdown
# DreamChat Deployment Guide
|
|
|
|
## Overview
|
|
|
|
This document covers the deployment configuration including Docker Compose setup, DevContainer configuration, and production deployment procedures.
|
|
|
|
## DevContainer Setup
|
|
|
|
### .devcontainer/devcontainer.json
|
|
|
|
```json
|
|
{
|
|
"name": "DreamChat Development",
|
|
"dockerComposeFile": "docker-compose.yml",
|
|
"service": "app",
|
|
"workspaceFolder": "/workspace",
|
|
"features": {
|
|
"ghcr.io/devcontainers/features/node:1": {
|
|
"version": "20"
|
|
},
|
|
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
|
|
},
|
|
"customizations": {
|
|
"vscode": {
|
|
"extensions": [
|
|
"dbaeumer.vscode-eslint",
|
|
"esbenp.prettier-vscode",
|
|
"bradlc.vscode-tailwindcss",
|
|
"ms-vscode.vscode-typescript-next",
|
|
"nestjs.vscode-nestjs",
|
|
"prisma.prisma"
|
|
],
|
|
"settings": {
|
|
"editor.formatOnSave": true,
|
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
"typescript.preferences.importModuleSpecifier": "relative"
|
|
}
|
|
}
|
|
},
|
|
"forwardPorts": [3000, 5173, 5432, 8080],
|
|
"portsAttributes": {
|
|
"3000": {
|
|
"label": "Backend API",
|
|
"onAutoForward": "notify"
|
|
},
|
|
"5173": {
|
|
"label": "Frontend Dev Server",
|
|
"onAutoForward": "notify"
|
|
},
|
|
"5432": {
|
|
"label": "PostgreSQL",
|
|
"onAutoForward": "silent"
|
|
},
|
|
"8080": {
|
|
"label": "Keycloak",
|
|
"onAutoForward": "notify"
|
|
}
|
|
},
|
|
"postCreateCommand": "bash .devcontainer/post-create.sh",
|
|
"remoteUser": "node",
|
|
"mounts": [
|
|
"source=${localWorkspaceFolderBasename}-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume",
|
|
"source=${localWorkspaceFolderBasename}-pnpm-store,target=/home/node/.local/share/pnpm/store,type=volume"
|
|
]
|
|
}
|
|
```
|
|
|
|
### .devcontainer/docker-compose.yml
|
|
|
|
```yaml
|
|
version: '3.8'
|
|
|
|
services:
|
|
app:
|
|
build:
|
|
context: ..
|
|
dockerfile: .devcontainer/Dockerfile
|
|
volumes:
|
|
- ..:/workspace:cached
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
command: sleep infinity
|
|
environment:
|
|
- DATABASE_URL=postgresql://postgres:postgres@db:5432/dreamchat
|
|
- REDIS_URL=redis://redis:6379
|
|
- KEYCLOAK_URL=http://keycloak:8080
|
|
depends_on:
|
|
- db
|
|
- redis
|
|
- keycloak
|
|
networks:
|
|
- dreamchat-network
|
|
|
|
db:
|
|
image: ankane/pgvector:latest
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_USER: postgres
|
|
POSTGRES_PASSWORD: postgres
|
|
POSTGRES_DB: dreamchat
|
|
volumes:
|
|
- postgres-data:/var/lib/postgresql/data
|
|
ports:
|
|
- "5432:5432"
|
|
networks:
|
|
- dreamchat-network
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
restart: unless-stopped
|
|
ports:
|
|
- "6379:6379"
|
|
networks:
|
|
- dreamchat-network
|
|
|
|
keycloak:
|
|
image: quay.io/keycloak/keycloak:23.0
|
|
restart: unless-stopped
|
|
command: start-dev
|
|
environment:
|
|
KEYCLOAK_ADMIN: admin
|
|
KEYCLOAK_ADMIN_PASSWORD: admin
|
|
KC_DB: postgres
|
|
KC_DB_URL: jdbc:postgresql://db:5432/keycloak
|
|
KC_DB_USERNAME: postgres
|
|
KC_DB_PASSWORD: postgres
|
|
ports:
|
|
- "8080:8080"
|
|
depends_on:
|
|
- db
|
|
networks:
|
|
- dreamchat-network
|
|
|
|
volumes:
|
|
postgres-data:
|
|
|
|
networks:
|
|
dreamchat-network:
|
|
driver: bridge
|
|
```
|
|
|
|
### .devcontainer/Dockerfile
|
|
|
|
```dockerfile
|
|
FROM mcr.microsoft.com/devcontainers/typescript-node:20
|
|
|
|
# Install additional tools
|
|
RUN apt-get update && apt-get install -y \
|
|
postgresql-client \
|
|
redis-tools \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Install pnpm
|
|
RUN npm install -g pnpm@8
|
|
|
|
# Set working directory
|
|
WORKDIR /workspace
|
|
|
|
# Install global packages
|
|
RUN npm install -g @nestjs/cli@latest
|
|
|
|
# Create non-root user
|
|
USER node
|
|
```
|
|
|
|
### .devcontainer/post-create.sh
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
set -e
|
|
|
|
echo "🚀 Setting up DreamChat monorepo development environment..."
|
|
|
|
# Install pnpm globally
|
|
npm install -g pnpm@8
|
|
|
|
# Install all dependencies (uses pnpm workspaces)
|
|
echo "📦 Installing dependencies..."
|
|
cd /workspace
|
|
pnpm install
|
|
|
|
# Build shared packages first
|
|
echo "📦 Building shared packages..."
|
|
pnpm --filter @dreamchat/shared build
|
|
|
|
# Generate Prisma client
|
|
pnpm db:generate
|
|
|
|
# Copy environment files if they don't exist
|
|
if [ ! -f /workspace/apps/backend/.env ]; then
|
|
echo "⚙️ Creating backend .env file..."
|
|
cat > /workspace/apps/backend/.env << EOF
|
|
NODE_ENV=development
|
|
PORT=3000
|
|
DATABASE_URL=postgresql://postgres:postgres@db:5432/dreamchat
|
|
JWT_SECRET=dev-jwt-secret-change-in-production
|
|
JWT_EXPIRES_IN=1h
|
|
JWT_REFRESH_EXPIRES_IN=7d
|
|
LLM_PROVIDER=openrouter
|
|
LLM_API_KEY=your-openrouter-api-key
|
|
LLM_MODEL=openai/gpt-4o
|
|
KEYCLOAK_URL=http://localhost:8080
|
|
KEYCLOAK_REALM=dreamchat
|
|
KEYCLOAK_CLIENT_ID=dreamchat-backend
|
|
EOF
|
|
fi
|
|
|
|
if [ ! -f /workspace/apps/frontend/.env ]; then
|
|
echo "⚙️ Creating frontend .env file..."
|
|
cat > /workspace/apps/frontend/.env << EOF
|
|
VITE_API_URL=http://localhost:3000/api
|
|
VITE_WS_URL=ws://localhost:3000
|
|
VITE_KEYCLOAK_URL=http://localhost:8080
|
|
VITE_KEYCLOAK_REALM=dreamchat
|
|
VITE_KEYCLOAK_CLIENT_ID=dreamchat-frontend
|
|
EOF
|
|
fi
|
|
|
|
echo "✅ Development environment setup complete!"
|
|
echo ""
|
|
echo "Next steps:"
|
|
echo "1. Start all apps: pnpm dev"
|
|
echo "2. Or start individually:"
|
|
echo " - Backend: pnpm --filter @dreamchat/backend dev"
|
|
echo " - Frontend: pnpm --filter @dreamchat/frontend dev"
|
|
echo "3. Access Keycloak admin at http://localhost:8080 (admin/admin)"
|
|
```
|
|
|
|
## Docker Compose Production
|
|
|
|
### docker-compose.yml (Root)
|
|
|
|
```yaml
|
|
version: '3.8'
|
|
|
|
services:
|
|
# Backend API
|
|
backend:
|
|
build:
|
|
context: .
|
|
dockerfile: apps/backend/Dockerfile
|
|
restart: unless-stopped
|
|
environment:
|
|
- NODE_ENV=production
|
|
- PORT=3000
|
|
- DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@db:5432/dreamchat
|
|
- JWT_SECRET=${JWT_SECRET}
|
|
- JWT_EXPIRES_IN=${JWT_EXPIRES_IN:-1h}
|
|
- JWT_REFRESH_EXPIRES_IN=${JWT_REFRESH_EXPIRES_IN:-7d}
|
|
- LLM_PROVIDER=${LLM_PROVIDER}
|
|
- LLM_API_KEY=${LLM_API_KEY}
|
|
- LLM_MODEL=${LLM_MODEL}
|
|
- EMBEDDING_PROVIDER=${EMBEDDING_PROVIDER:-local}
|
|
- EMBEDDING_MODEL=${EMBEDDING_MODEL:-Xenova/all-MiniLM-L6-v2}
|
|
- EMBEDDING_DIMENSION=${EMBEDDING_DIMENSION:-384}
|
|
- EMBEDDING_DEVICE=${EMBEDDING_DEVICE:-cpu}
|
|
- HUGGINGFACE_API_KEY=${HUGGINGFACE_API_KEY}
|
|
- KEYCLOAK_URL=${KEYCLOAK_URL}
|
|
- KEYCLOAK_REALM=${KEYCLOAK_REALM}
|
|
- KEYCLOAK_CLIENT_ID=${KEYCLOAK_CLIENT_ID}
|
|
- KEYCLOAK_CLIENT_SECRET=${KEYCLOAK_CLIENT_SECRET}
|
|
ports:
|
|
- "3000:3000"
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
volumes:
|
|
- backend-logs:/app/logs
|
|
- model-cache:/app/models
|
|
networks:
|
|
- dreamchat-network
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
|
|
# Frontend
|
|
frontend:
|
|
build:
|
|
context: .
|
|
dockerfile: apps/frontend/Dockerfile
|
|
restart: unless-stopped
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
environment:
|
|
- VITE_API_URL=/api
|
|
- VITE_WS_URL=/ws
|
|
depends_on:
|
|
- backend
|
|
networks:
|
|
- dreamchat-network
|
|
|
|
# Database
|
|
db:
|
|
image: ankane/pgvector:latest
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_USER: postgres
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
POSTGRES_DB: dreamchat
|
|
volumes:
|
|
- postgres-data:/var/lib/postgresql/data
|
|
- ./init-scripts:/docker-entrypoint-initdb.d
|
|
networks:
|
|
- dreamchat-network
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
# Redis (optional, for session storage and caching)
|
|
redis:
|
|
image: redis:7-alpine
|
|
restart: unless-stopped
|
|
volumes:
|
|
- redis-data:/data
|
|
networks:
|
|
- dreamchat-network
|
|
|
|
# Nginx Reverse Proxy (optional)
|
|
nginx:
|
|
image: nginx:alpine
|
|
restart: unless-stopped
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
volumes:
|
|
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
|
- ./nginx/ssl:/etc/nginx/ssl:ro
|
|
- model-cache:/model-cache:ro
|
|
depends_on:
|
|
- backend
|
|
- frontend
|
|
networks:
|
|
- dreamchat-network
|
|
|
|
volumes:
|
|
postgres-data:
|
|
redis-data:
|
|
backend-logs:
|
|
model-cache: # Persist downloaded embedding models
|
|
|
|
networks:
|
|
dreamchat-network:
|
|
driver: bridge
|
|
```
|
|
|
|
### Embedding Model Cache (Optional)
|
|
|
|
To avoid re-downloading models on every restart, models are cached in a Docker volume:
|
|
|
|
```yaml
|
|
# Add to docker-compose volumes
|
|
volumes:
|
|
model-cache:
|
|
```
|
|
|
|
Models are downloaded on first use and cached at `/app/models` in the backend container.
|
|
|
|
Common models and their sizes:
|
|
- `Xenova/all-MiniLM-L6-v2`: ~80MB (384 dimensions)
|
|
- `Xenova/all-mpnet-base-v2`: ~420MB (768 dimensions)
|
|
- `BAAI/bge-small-en`: ~130MB (384 dimensions)
|
|
|
|
### .env.example
|
|
|
|
```bash
|
|
# Database
|
|
POSTGRES_PASSWORD=your_secure_password_here
|
|
|
|
# JWT
|
|
JWT_SECRET=your_jwt_secret_key_min_32_chars
|
|
JWT_EXPIRES_IN=1h
|
|
JWT_REFRESH_EXPIRES_IN=7d
|
|
|
|
# LLM Configuration
|
|
LLM_PROVIDER=openrouter
|
|
LLM_API_KEY=sk-or-v1-...
|
|
LLM_MODEL=openai/gpt-4o
|
|
|
|
# Embedding Configuration (Local HuggingFace by default)
|
|
EMBEDDING_PROVIDER=local
|
|
EMBEDDING_MODEL=Xenova/all-MiniLM-L6-v2
|
|
EMBEDDING_DIMENSION=384
|
|
EMBEDDING_DEVICE=cpu
|
|
|
|
# HuggingFace API (optional - if not using local embeddings)
|
|
# HUGGINGFACE_API_KEY=hf_...
|
|
|
|
# Keycloak (optional - for external auth)
|
|
KEYCLOAK_URL=http://keycloak:8080
|
|
KEYCLOAK_REALM=dreamchat
|
|
KEYCLOAK_CLIENT_ID=dreamchat-backend
|
|
KEYCLOAK_CLIENT_SECRET=your_keycloak_secret
|
|
```
|
|
|
|
## Backend Dockerfile
|
|
|
|
```dockerfile
|
|
# apps/backend/Dockerfile
|
|
FROM node:20-alpine AS base
|
|
RUN npm install -g pnpm@8
|
|
|
|
FROM base AS dependencies
|
|
WORKDIR /app
|
|
|
|
# Copy workspace configuration
|
|
COPY pnpm-workspace.yaml package.json ./
|
|
COPY apps/backend/package.json ./apps/backend/
|
|
COPY packages/shared/package.json ./packages/shared/
|
|
|
|
# Install dependencies
|
|
RUN pnpm install --frozen-lockfile
|
|
|
|
FROM base AS build
|
|
WORKDIR /app
|
|
COPY --from=dependencies /app/node_modules ./node_modules
|
|
COPY --from=dependencies /app/apps/backend/node_modules ./apps/backend/node_modules
|
|
COPY --from=dependencies /app/packages/shared/node_modules ./packages/shared/node_modules
|
|
|
|
# Copy source code
|
|
COPY packages/shared ./packages/shared
|
|
COPY apps/backend ./apps/backend
|
|
|
|
# Build shared packages first
|
|
RUN pnpm --filter @dreamchat/shared build
|
|
|
|
# Build backend
|
|
RUN pnpm --filter @dreamchat/backend build
|
|
|
|
FROM base AS production
|
|
WORKDIR /app
|
|
|
|
# Copy only production dependencies
|
|
COPY --from=dependencies /app/node_modules ./node_modules
|
|
COPY --from=dependencies /app/apps/backend/node_modules ./apps/backend/node_modules
|
|
COPY --from=build /app/apps/backend/dist ./dist
|
|
COPY --from=build /app/packages/shared/dist ./node_modules/@dreamchat/shared/dist
|
|
|
|
# Create logs directory
|
|
RUN mkdir -p /app/logs
|
|
|
|
# Non-root user
|
|
RUN addgroup -g 1001 -S nodejs
|
|
RUN adduser -S nodejs -u 1001
|
|
USER nodejs
|
|
|
|
EXPOSE 3000
|
|
|
|
CMD ["node", "dist/main.js"]
|
|
```
|
|
|
|
## Frontend Dockerfile
|
|
|
|
```dockerfile
|
|
# apps/frontend/Dockerfile
|
|
FROM node:20-alpine AS base
|
|
RUN npm install -g pnpm@8
|
|
|
|
FROM base AS dependencies
|
|
WORKDIR /app
|
|
|
|
# Copy workspace configuration
|
|
COPY pnpm-workspace.yaml package.json ./
|
|
COPY apps/frontend/package.json ./apps/frontend/
|
|
COPY packages/shared/package.json ./packages/shared/
|
|
|
|
# Install dependencies
|
|
RUN pnpm install --frozen-lockfile
|
|
|
|
FROM base AS build
|
|
WORKDIR /app
|
|
COPY --from=dependencies /app/node_modules ./node_modules
|
|
COPY --from=dependencies /app/apps/frontend/node_modules ./apps/frontend/node_modules
|
|
COPY --from=dependencies /app/packages/shared/node_modules ./packages/shared/node_modules
|
|
|
|
# Copy source code
|
|
COPY packages/shared ./packages/shared
|
|
COPY apps/frontend ./apps/frontend
|
|
|
|
# Build shared packages first
|
|
RUN pnpm --filter @dreamchat/shared build
|
|
|
|
# Build frontend
|
|
RUN pnpm --filter @dreamchat/frontend build
|
|
|
|
# Production with Nginx
|
|
FROM nginx:alpine
|
|
|
|
# Copy built assets
|
|
COPY --from=build /app/apps/frontend/dist /usr/share/nginx/html
|
|
|
|
# Copy nginx config
|
|
COPY apps/frontend/nginx.conf /etc/nginx/conf.d/default.conf
|
|
|
|
EXPOSE 80
|
|
|
|
CMD ["nginx", "-g", "daemon off;"]
|
|
```
|
|
|
|
### frontend/nginx.conf
|
|
|
|
```nginx
|
|
server {
|
|
listen 80;
|
|
server_name localhost;
|
|
root /usr/share/nginx/html;
|
|
index index.html;
|
|
|
|
# Gzip compression
|
|
gzip on;
|
|
gzip_vary on;
|
|
gzip_min_length 1024;
|
|
gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml;
|
|
|
|
# API proxy
|
|
location /api {
|
|
proxy_pass http://backend:3000/api;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection 'upgrade';
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_cache_bypass $http_upgrade;
|
|
}
|
|
|
|
# WebSocket proxy
|
|
location /ws {
|
|
proxy_pass http://backend:3000;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
}
|
|
|
|
# Static files
|
|
location / {
|
|
try_files $uri $uri/ /index.html;
|
|
add_header Cache-Control "public, max-age=31536000, immutable";
|
|
}
|
|
|
|
# Health check
|
|
location /health {
|
|
access_log off;
|
|
return 200 "healthy\n";
|
|
add_header Content-Type text/plain;
|
|
}
|
|
}
|
|
```
|
|
|
|
## Keycloak Configuration
|
|
|
|
### Initial Setup
|
|
|
|
1. Access Keycloak admin console: `http://localhost:8080/admin`
|
|
2. Login with admin credentials
|
|
3. Create new realm: `dreamchat`
|
|
4. Create client: `dreamchat-backend`
|
|
- Client authentication: ON
|
|
- Authorization: ON
|
|
- Valid redirect URIs: `http://localhost:3000/*`
|
|
- Web origins: `http://localhost:3000`
|
|
|
|
5. Create client: `dreamchat-frontend`
|
|
- Client authentication: OFF
|
|
- Valid redirect URIs: `http://localhost:5173/*`
|
|
- Web origins: `http://localhost:5173`
|
|
|
|
### realm-export.json (Optional)
|
|
|
|
```json
|
|
{
|
|
"realm": "dreamchat",
|
|
"enabled": true,
|
|
"clients": [
|
|
{
|
|
"clientId": "dreamchat-backend",
|
|
"enabled": true,
|
|
"clientAuthenticatorType": "client-secret",
|
|
"secret": "**********",
|
|
"redirectUris": ["http://localhost:3000/*"],
|
|
"webOrigins": ["http://localhost:3000"],
|
|
"protocol": "openid-connect"
|
|
},
|
|
{
|
|
"clientId": "dreamchat-frontend",
|
|
"enabled": true,
|
|
"publicClient": true,
|
|
"redirectUris": ["http://localhost:5173/*"],
|
|
"webOrigins": ["http://localhost:5173"],
|
|
"protocol": "openid-connect"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
## Deployment Procedures
|
|
|
|
### Local Development
|
|
|
|
```bash
|
|
# Using DevContainer
|
|
1. Open project in VS Code
|
|
2. Click "Reopen in Container"
|
|
3. Wait for setup to complete
|
|
4. Start services:
|
|
- Terminal 1: pnpm --filter @dreamchat/backend dev
|
|
- Terminal 2: pnpm --filter @dreamchat/frontend dev
|
|
- Or run all: pnpm dev
|
|
```
|
|
|
|
### Production Deployment
|
|
|
|
```bash
|
|
# 1. Clone repository
|
|
git clone https://github.com/yourusername/dreamchat.git
|
|
cd dreamchat
|
|
|
|
# 2. Create environment file
|
|
cp .env.example .env
|
|
# Edit .env with production values
|
|
|
|
# 3. Build and start
|
|
docker-compose up -d --build
|
|
|
|
# 4. Run database migrations
|
|
docker-compose exec backend pnpm db:migrate
|
|
|
|
# 5. Check health
|
|
curl http://localhost:3000/health
|
|
|
|
# 6. View logs
|
|
docker-compose logs -f backend
|
|
```
|
|
|
|
### Backup and Restore
|
|
|
|
```bash
|
|
# Backup database
|
|
docker-compose exec db pg_dump -U postgres -Fc dreamchat > backup_$(date +%Y%m%d).dump
|
|
|
|
# Restore database
|
|
docker-compose exec -T db pg_restore -U postgres -d dreamchat < backup_20240223.dump
|
|
|
|
# Backup volumes
|
|
docker run --rm -v dreamchat_postgres-data:/data -v $(pwd):/backup alpine tar czf /backup/postgres-backup.tar.gz -C /data .
|
|
```
|
|
|
|
### Updates
|
|
|
|
```bash
|
|
# Pull latest changes
|
|
git pull origin main
|
|
|
|
# Rebuild and restart
|
|
docker-compose down
|
|
docker-compose up -d --build
|
|
|
|
# Run migrations
|
|
docker-compose exec backend npx prisma migrate deploy
|
|
```
|
|
|
|
## Monitoring and Logging
|
|
|
|
### Health Checks
|
|
|
|
```bash
|
|
# Backend health
|
|
curl http://localhost:3000/health
|
|
|
|
# Database health
|
|
docker-compose exec db pg_isready -U postgres
|
|
|
|
# Full stack
|
|
docker-compose ps
|
|
```
|
|
|
|
### Log Management
|
|
|
|
```bash
|
|
# View all logs
|
|
docker-compose logs
|
|
|
|
# View specific service
|
|
docker-compose logs -f backend
|
|
|
|
# View last 100 lines
|
|
docker-compose logs --tail=100 backend
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
1. **Change default passwords** in production
|
|
2. **Use HTTPS** with valid SSL certificates
|
|
3. **Enable firewall** rules for required ports only
|
|
4. **Regular updates** of base images and dependencies
|
|
5. **Secrets management** - use Docker secrets or external vault
|
|
6. **Network isolation** - separate networks for different services
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
1. **Database connection failed**
|
|
- Check DATABASE_URL environment variable
|
|
- Ensure db service is healthy: `docker-compose ps`
|
|
|
|
2. **WebSocket not connecting**
|
|
- Verify VITE_WS_URL matches your domain
|
|
- Check Nginx proxy configuration
|
|
|
|
3. **Keycloak authentication issues**
|
|
- Verify client configuration in Keycloak admin
|
|
- Check redirect URIs match exactly
|
|
|
|
4. **File upload fails**
|
|
- Check file size limits in Nginx config
|
|
- Verify disk space in backend container
|