Deployment
This guide covers deploying Eventara to production environments.
Prerequisites
Infrastructure Requirements
- Compute: 2+ vCPUs, 4GB+ RAM for moderate loads
- Storage: 20GB+ for application and database
- Network: Inbound ports 8080 (API), 5173 (Dashboard, optional)
Software Requirements
- Docker 20.10+ and Docker Compose 2.0+
- Or: Java 21+, PostgreSQL 14+, Kafka, Node.js 18+
Docker Compose Deployment
Step 1: Prepare Environment
Clone the repository:
git clone https://github.com/tusharkhatriofficial/eventara.git
cd eventaraStep 2: Configure Environment
Create .env file (optional, for custom configuration):
# Database
POSTGRES_USER=postgres
POSTGRES_PASSWORD=your_secure_password
POSTGRES_DB=eventara
# Kafka
KAFKA_BOOTSTRAP_SERVERS=kafka:9092
# Spring Boot
SPRING_PROFILES_ACTIVE=productionStep 3: Update Configuration
Edit src/main/resources/application.properties:
# Update database password
spring.datasource.password=${POSTGRES_PASSWORD:mysecretpassword}
# Adjust Kafka bootstrap servers if needed
spring.kafka.bootstrap-servers=${KAFKA_BOOTSTRAP_SERVERS:kafka:9092}
# Disable SQL logging in production
spring.jpa.show-sql=falseStep 4: Build and Start Services
docker compose up --build -dThis starts:
- PostgreSQL (port 5432)
- Zookeeper (port 2181)
- Kafka (ports 9092, 9093)
- Kafka UI (port 8090, optional)
- Spring Boot API (port 8080)
- React Dashboard (port 5173, optional for production)
Step 5: Verify Deployment
# Check service status
docker compose ps
# Check logs
docker compose logs -f springboot
# Test API
curl http://your-server:8080/api/v1/events/health
# Expected: {"status":"UP","timestamp":"..."}Step 6: Monitor Services
# View logs for all services
docker compose logs -f
# View logs for specific service
docker compose logs -f springboot
docker compose logs -f kafka
# Check resource usage
docker statsProduction Considerations
Database
Persistent Volumes
Ensure PostgreSQL data persists across restarts:
# docker-compose.yaml
services:
postgres:
volumes:
- postgres_data:/var/lib/postgresql/data # Named volume
volumes:
postgres_data:
driver: localBackup Strategy
# Backup PostgreSQL
docker exec postgres14 pg_dump -U postgres eventara > backup_$(date +%Y%m%d).sql
# Restore
docker exec -i postgres14 psql -U postgres eventara < backup_20260112.sqlPerformance Tuning
Add to docker-compose.yaml:
postgres:
environment:
POSTGRES_SHARED_BUFFERS: 256MB
POSTGRES_EFFECTIVE_CACHE_SIZE: 1GB
POSTGRES_WORK_MEM: 16MBKafka
Data Retention
Configure in docker-compose.yaml:
kafka:
environment:
KAFKA_LOG_RETENTION_HOURS: 168 # 7 days
KAFKA_LOG_RETENTION_BYTES: 10737418240 # 10GBMultiple Brokers (High Availability)
For production, use 3+ brokers:
services:
kafka1:
# ... broker 1 config
environment:
KAFKA_BROKER_ID: 1
kafka2:
# ... broker 2 config
environment:
KAFKA_BROKER_ID: 2
kafka3:
# ... broker 3 config
environment:
KAFKA_BROKER_ID: 3Update replication factor:
KAFKA_DEFAULT_REPLICATION_FACTOR: 3
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3Application
JVM Configuration
Add to Spring Boot service in docker-compose.yaml:
springboot:
environment:
JAVA_OPTS: >
-Xms512m
-Xmx2g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-Djava.security.egd=file:/dev/./urandomHealth Checks
springboot:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/api/v1/events/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40sSecurity
Update Default Passwords
Never use default passwords in production:
postgres:
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} # From secretsEnable TLS/SSL
For PostgreSQL:
postgres:
command: >
postgres
-c ssl=on
-c ssl_cert_file=/etc/ssl/certs/server.crt
-c ssl_key_file=/etc/ssl/private/server.key
volumes:
- ./certs:/etc/ssl/certs
- ./keys:/etc/ssl/privateUpdate connection string:
spring.datasource.url=jdbc:postgresql://postgres:5432/eventara?ssl=true&sslmode=requireNetwork Isolation
Use Docker networks to isolate services:
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # No external access
services:
springboot:
networks:
- frontend # Exposed
- backend # Internal only
postgres:
networks:
- backend # Internal onlyReverse Proxy
Nginx Configuration
Create nginx.conf:
upstream eventara_api {
server localhost:8080;
}
upstream eventara_dashboard {
server localhost:5173;
}
server {
listen 80;
server_name your-domain.com;
# Redirect to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /etc/ssl/certs/your-domain.crt;
ssl_certificate_key /etc/ssl/private/your-domain.key;
# API
location /api/ {
proxy_pass http://eventara_api;
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;
}
# WebSocket
location /ws {
proxy_pass http://eventara_api;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 3600s;
}
# Dashboard
location / {
proxy_pass http://eventara_dashboard;
proxy_set_header Host $host;
}
}Add to docker-compose.yaml:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./certs:/etc/ssl/certs:ro
- ./keys:/etc/ssl/private:ro
depends_on:
- springbootBuilding for Production
Backend
Build JAR
./mvnw clean package -DskipTests
# JAR location: target/ingestion-0.0.1-SNAPSHOT.jarRun JAR
java -Xms512m -Xmx2g \
-Dspring.profiles.active=production \
-jar target/ingestion-0.0.1-SNAPSHOT.jarFrontend
Build Production Assets
cd eventara-dashboard
npm run build
# Output: dist/Serve Static Files
Option 1: Nginx
server {
listen 80;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}Option 2: Serve from Spring Boot
# Copy built assets to Spring Boot static folder
cp -r eventara-dashboard/dist/* src/main/resources/static/
./mvnw clean packageEnvironment Variables
Spring Boot
| Variable | Description | Default |
|---|---|---|
| SPRING_DATASOURCE_URL | PostgreSQL connection URL | jdbc:postgresql://localhost:5432/eventara |
| SPRING_DATASOURCE_USERNAME | Database username | postgres |
| SPRING_DATASOURCE_PASSWORD | Database password | mysecretpassword |
| SPRING_KAFKA_BOOTSTRAP_SERVERS | Kafka broker addresses | localhost:9093 |
| SPRING_PROFILES_ACTIVE | Active profile | (none) |
| JAVA_OPTS | JVM options | (none) |
Dashboard
| Variable | Description | Default |
|---|---|---|
| VITE_API_URL | Backend API URL | http://localhost:8080 |
Set in .env file:
VITE_API_URL=https://api.your-domain.comMonitoring
Application Logs
# Follow logs
docker compose logs -f springboot
# Search logs
docker compose logs springboot | grep ERROR
# Export logs
docker compose logs --no-color springboot > logs.txtHealth Checks
# Application health
curl http://localhost:8080/api/v1/events/health
# Metrics snapshot
curl http://localhost:8080/api/v1/metrics | jq '.summary'
# Kafka topics
docker exec -it eventara-kafka kafka-topics --list --bootstrap-server localhost:9092Resource Monitoring
# Docker stats
docker stats
# PostgreSQL stats
docker exec postgres14 psql -U postgres -c "SELECT * FROM pg_stat_database WHERE datname='eventara';"
# Kafka consumer lag
docker exec eventara-kafka kafka-consumer-groups \
--bootstrap-server localhost:9092 \
--group eventara-consumer-group \
--describeScaling
Horizontal Scaling
Multiple API Instances
springboot:
deploy:
replicas: 3
ports:
- "8080-8082:8080"Add load balancer (Nginx):
upstream eventara_api {
least_conn;
server springboot1:8080;
server springboot2:8080;
server springboot3:8080;
}Consumer Scaling
Multiple consumers automatically share Kafka partitions:
# No code changes needed, just start more instances
docker compose up --scale springboot=3Vertical Scaling
Increase resources in docker-compose.yaml:
springboot:
deploy:
resources:
limits:
cpus: '2'
memory: 4G
reservations:
cpus: '1'
memory: 2GBackup and Recovery
Full Backup Script
#!/bin/bash
BACKUP_DIR=/backups/$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
# Backup PostgreSQL
docker exec postgres14 pg_dump -U postgres eventara | gzip > $BACKUP_DIR/db.sql.gz
# Backup application config
cp -r src/main/resources/application.properties $BACKUP_DIR/
# Backup Docker Compose
cp docker-compose.yaml $BACKUP_DIR/
echo "Backup completed: $BACKUP_DIR"Recovery
# Restore database
gunzip < backup_20260112/db.sql.gz | \
docker exec -i postgres14 psql -U postgres eventara
# Restart services
docker compose restartUpgrading
Zero-Downtime Deployment
-
Deploy new version:
docker compose pull docker compose up -d --no-deps --build springboot -
Health check:
curl http://localhost:8080/api/v1/events/health -
Roll back if needed:
docker compose up -d --no-deps springboot:previous-tag
Database Migrations
Flyway runs automatically on startup. To run manually:
./mvnw flyway:migrateTroubleshooting
See Troubleshooting Guide for common issues and solutions.