Files
FullStackTemplate/docker-compose.yml
Christian Schindler 4a6b4a0ae8 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
2025-12-01 08:37:35 +01:00

151 lines
4.0 KiB
YAML

# Docker Compose für Full Stack Application
# SICHERHEITS-OPTIMIERT für Gitea Actions & Production
version: "3.8"
services:
app:
# 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}
# 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
networks:
- app-network
# Optional: Nur aktivieren wenn PostgreSQL verwendet wird
# depends_on:
# postgres:
# condition: service_healthy
ports:
- "${APP_PORT:-8080}:8080" # Port 8080 für non-root
# Volumes für persistente Daten
volumes:
- app-data:/data
healthcheck:
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:
# 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