diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d4a0141 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,105 @@ +services: + # PostgreSQL Database + postgres: + image: postgres:16-alpine + container_name: secure-portal-db + restart: unless-stopped + environment: + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: ${POSTGRES_DB} + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] + interval: 10s + timeout: 5s + retries: 5 + + # Redis Cache + redis: + image: redis:7-alpine + container_name: secure-portal-redis + restart: unless-stopped + command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD} + volumes: + - redis_data:/data + healthcheck: + test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"] + interval: 10s + timeout: 3s + retries: 5 + + # Backend API + backend: + image: git.unixweb.net/unixweb/secure-portal-backend:latest + container_name: secure-portal-backend + restart: unless-stopped + ports: + - "3000:3000" + environment: + NODE_ENV: production + PORT: 3000 + HOST: 0.0.0.0 + DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?schema=public + REDIS_HOST: redis + REDIS_PORT: 6379 + REDIS_PASSWORD: ${REDIS_PASSWORD} + JWT_ACCESS_SECRET: ${JWT_ACCESS_SECRET} + JWT_REFRESH_SECRET: ${JWT_REFRESH_SECRET} + PASSWORD_RESET_URL: ${PASSWORD_RESET_URL} + MAIL_PROVIDER: ${MAIL_PROVIDER:-brevo} + MAIL_FROM_EMAIL: ${MAIL_FROM_EMAIL} + MAIL_FROM_NAME: ${MAIL_FROM_NAME:-Secure Portal} + BREVO_API_KEY: ${BREVO_API_KEY} + ENCRYPTION_KEY: ${ENCRYPTION_KEY} + CORS_ORIGIN: ${CORS_ORIGIN} + FRONTEND_URL: ${FRONTEND_URL} + SMTP_HOST: ${SMTP_HOST} + SMTP_PORT: ${SMTP_PORT:-587} + SMTP_USER: ${SMTP_USER} + SMTP_PASSWORD: ${SMTP_PASSWORD} + SMTP_SECURE: ${SMTP_SECURE:-false} + LICENSE_SERVER_URL: ${LICENSE_SERVER_URL} + LICENSE_KEY: ${LICENSE_KEY} + ENABLE_REGISTER: ${ENABLE_REGISTER:-false} + CLAMAV_HOST: clamav + CLAMAV_PORT: 3310 + CLAMAV_ENABLED: ${CLAMAV_ENABLED:-true} + volumes: + - uploads_data:/var/uploads + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + + # Frontend (Nginx) + frontend: + image: git.unixweb.net/unixweb/secure-portal-frontend:latest + container_name: secure-portal-frontend + restart: unless-stopped + ports: + - "80:80" + depends_on: + - backend + + # ClamAV Virus Scanner + clamav: + image: clamav/clamav:latest + container_name: secure-portal-clamav + restart: unless-stopped + volumes: + - clamav_data:/var/lib/clamav + healthcheck: + test: ["CMD", "/usr/local/bin/clamdcheck.sh"] + interval: 60s + timeout: 10s + retries: 3 + start_period: 120s + +volumes: + postgres_data: + redis_data: + uploads_data: + clamav_data: diff --git a/env.example b/env.example new file mode 100644 index 0000000..3895391 --- /dev/null +++ b/env.example @@ -0,0 +1,42 @@ +# Database +POSTGRES_USER=portal_user +POSTGRES_PASSWORD=your_secure_password +POSTGRES_DB=secure_portal + +# Redis +REDIS_PASSWORD=your_redis_password + +# JWT Secrets (generate with: openssl rand -base64 32) +JWT_ACCESS_SECRET=your_access_secret +JWT_REFRESH_SECRET=your_refresh_secret + +# Encryption (32 characters) +ENCRYPTION_KEY=your_32_character_encryption_key + +# URLs +PASSWORD_RESET_URL=https://yourdomain.com/password-reset +CORS_ORIGIN=https://yourdomain.com +FRONTEND_URL=https://yourdomain.com + +# Mail Provider (brevo, sendgrid, smtp) +MAIL_PROVIDER=brevo +MAIL_FROM_EMAIL=noreply@yourdomain.com +MAIL_FROM_NAME=Secure Portal + +# Brevo (if MAIL_PROVIDER=brevo) +BREVO_API_KEY=your_brevo_api_key + +# SMTP (if MAIL_PROVIDER=smtp) +SMTP_HOST=smtp.example.com +SMTP_PORT=587 +SMTP_USER=your_smtp_user +SMTP_PASSWORD=your_smtp_password +SMTP_SECURE=false + +# License +LICENSE_SERVER_URL=https://license.example.com +LICENSE_KEY=your_license_key + +# Features +ENABLE_REGISTER=false +CLAMAV_ENABLED=true