feat: Enhance security and validation in backend
- Added helmet for security headers and configured content security policy - Implemented CORS with a whitelist for allowed origins - Introduced express-validator for input validation in API endpoints - Set request size limits to prevent DoS attacks - Added global error handling and 404 response - Updated TypeScript configuration to use node16 module resolution - Improved Docker Compose configuration for security and resource limits - Created a comprehensive .env.example for environment configuration - Implemented automated security scans in CI/CD with Trivy - Added cleanup script for debugging ports - Established a detailed security policy document
This commit is contained in:
@@ -1,47 +1,150 @@
|
||||
# Docker Compose für Full Stack Application
|
||||
# SICHERHEITS-OPTIMIERT für Gitea Actions & Production
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
app:
|
||||
image: ${APP_IMAGE:-fullstack-app:latest}
|
||||
# Automatischer Build aus dem aktuellen Verzeichnis
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
NODE_ENV: ${NODE_ENV:-production}
|
||||
BUILD_VERSION: ${BUILD_VERSION:-latest}
|
||||
|
||||
# Optional: Image-Name für Registry-Push (für CI/CD)
|
||||
# image: ${REGISTRY:-localhost}/${IMAGE_NAME:-fullstack-app}:${TAG:-latest}
|
||||
|
||||
container_name: ${APP_CONTAINER_NAME:-fullstack-app}
|
||||
restart: unless-stopped
|
||||
|
||||
# Non-root User (UID/GID 1000)
|
||||
user: "1000:1000"
|
||||
|
||||
environment:
|
||||
- NODE_ENV=${NODE_ENV:-production}
|
||||
- DATABASE_URL=${DATABASE_URL:-postgresql://postgres:postgres@postgres:5432/appdb}
|
||||
- JWT_SECRET=${JWT_SECRET:-your-jwt-secret-change-this}
|
||||
networks:
|
||||
- app-network
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "${APP_PORT:-3000}:3000"
|
||||
# Optional: Nur wenn PostgreSQL verwendet wird
|
||||
- DATABASE_URL=${DATABASE_URL:-}
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
|
||||
# Security Options
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
cap_drop:
|
||||
- ALL
|
||||
cap_add:
|
||||
- NET_BIND_SERVICE # Erlaubt Binding an Ports < 1024 (falls nötig)
|
||||
|
||||
# Resource Limits (verhindern DoS)
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2.0'
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: ${POSTGRES_CONTAINER_NAME:-postgres-db}
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: ${POSTGRES_DB:-appdb}
|
||||
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- app-network
|
||||
|
||||
# Optional: Nur aktivieren wenn PostgreSQL verwendet wird
|
||||
# depends_on:
|
||||
# postgres:
|
||||
# condition: service_healthy
|
||||
|
||||
ports:
|
||||
- "${POSTGRES_PORT:-5432}:5432"
|
||||
- "${APP_PORT:-8080}:8080" # Port 8080 für non-root
|
||||
|
||||
# Volumes für persistente Daten
|
||||
volumes:
|
||||
- app-data:/data
|
||||
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8080/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
|
||||
# =============================================================================
|
||||
# PostgreSQL Service (OPTIONAL)
|
||||
# =============================================================================
|
||||
# Nur aktivieren wenn PostgreSQL benötigt wird.
|
||||
# Für SQLite oder andere Datenbanken kann dieser Service entfernt werden.
|
||||
#
|
||||
# Um PostgreSQL zu aktivieren:
|
||||
# 1. Entferne die Kommentare (#) vor dem gesamten postgres-Service
|
||||
# 2. Aktiviere "depends_on" im app-Service (siehe oben)
|
||||
# 3. Setze DATABASE_URL in .env
|
||||
# =============================================================================
|
||||
|
||||
# postgres:
|
||||
# image: postgres:15-alpine
|
||||
# container_name: ${POSTGRES_CONTAINER_NAME:-postgres-db}
|
||||
# restart: unless-stopped
|
||||
#
|
||||
# # Non-root User (postgres verwendet UID 70 standardmäßig)
|
||||
# user: "70:70"
|
||||
#
|
||||
# environment:
|
||||
# POSTGRES_DB: ${POSTGRES_DB:-appdb}
|
||||
# POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
||||
# POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} # MUSS in .env gesetzt werden!
|
||||
# POSTGRES_INITDB_ARGS: "--auth-host=scram-sha-256" # Sichere Auth
|
||||
# POSTGRES_HOST_AUTH_METHOD: scram-sha-256
|
||||
#
|
||||
# # Security Options
|
||||
# security_opt:
|
||||
# - no-new-privileges:true
|
||||
# cap_drop:
|
||||
# - ALL
|
||||
# cap_add:
|
||||
# - CHOWN
|
||||
# - DAC_OVERRIDE
|
||||
# - FOWNER
|
||||
# - SETGID
|
||||
# - SETUID
|
||||
#
|
||||
# # Resource Limits
|
||||
# deploy:
|
||||
# resources:
|
||||
# limits:
|
||||
# cpus: '1.0'
|
||||
# memory: 1G
|
||||
# reservations:
|
||||
# cpus: '0.25'
|
||||
# memory: 256M
|
||||
#
|
||||
# volumes:
|
||||
# - postgres_data:/var/lib/postgresql/data
|
||||
#
|
||||
# networks:
|
||||
# - app-network
|
||||
#
|
||||
# # KEIN Port-Expose nach außen - nur intern erreichbar!
|
||||
# # Für lokales Debugging kann der Port freigegeben werden:
|
||||
# # ports:
|
||||
# # - "${POSTGRES_PORT:-5432}:5432"
|
||||
#
|
||||
# healthcheck:
|
||||
# test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"]
|
||||
# interval: 10s
|
||||
# timeout: 5s
|
||||
# retries: 5
|
||||
# start_period: 10s
|
||||
|
||||
networks:
|
||||
app-network:
|
||||
driver: bridge
|
||||
# Optional: Netzwerk isolieren
|
||||
internal: false # Auf 'true' setzen wenn kein Internet-Zugriff nötig
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
# Persistente Daten für die App (z.B. SQLite-Datenbank, Uploads, etc.)
|
||||
app-data:
|
||||
driver: local
|
||||
|
||||
# Optional: Nur wenn PostgreSQL verwendet wird
|
||||
# postgres_data:
|
||||
# driver: local
|
||||
|
||||
Reference in New Issue
Block a user