Cursor rule
.cursor/rules/docker-deployment.mdcComplete Docker containerization, production deployment, and monitoring patterns for POS System
Cursor rules
Quality
77/100
Scores the file, not the repository.Length
2,890 words
111 headings · 29 code blocksRepository
118
— · pushed 339 days agoLast changed
3 days ago
First indexed 3 days ago.123456# 🐳 Docker & Production Deployment Guide78## Container Architecture910### Service Overview11The POS system uses a multi-container architecture defined in [docker-compose.yml](mdc:docker-compose.yml):12131. **postgres** - PostgreSQL database with persistent storage142. **backend** - Golang API server with database connectivity153. **frontend** - React application served via Nginx1617### Container Networking18All services communicate through the `pos-network` bridge network:19- Frontend → Backend: HTTP API calls20- Backend → Database: PostgreSQL connection21- External access via exposed ports2223## Development vs Production2425### Development Configuration26Use [docker-compose.dev.yml](mdc:docker-compose.dev.yml) for development:27```bash28docker-compose -f docker-compose.dev.yml up29```3031**Development Features:**32- Volume mounts for live code reloading33- Development-specific environment variables34- Hot reloading for both frontend (Vite) and backend (Air)35- Debug logging enabled3637### Production Configuration38Use [docker-compose.yml](mdc:docker-compose.yml) for production:39```bash40docker-compose up -d41```4243**Production Features:**44- Optimized multi-stage builds45- Minimal runtime containers (Alpine-based)46- Health checks and restart policies47- Production-ready Nginx configuration4849## Dockerfile Patterns5051### Backend Dockerfile52Multi-stage build pattern in [backend/Dockerfile](mdc:backend/Dockerfile):5354```dockerfile55# Build stage - full Go toolchain56FROM golang:1.21-alpine AS builder57WORKDIR /app58COPY go.mod go.sum ./59RUN go mod download60COPY . .61RUN CGO_ENABLED=0 GOOS=linux go build -o main .6263# Production stage - minimal runtime64FROM alpine:latest65RUN apk --no-cache add ca-certificates66WORKDIR /root/67COPY --from=builder /app/main .68EXPOSE 808069CMD ["./main"]70```7172### Frontend Dockerfile73Node.js build with Nginx serving in [frontend/Dockerfile](mdc:frontend/Dockerfile):7475```dockerfile76# Build stage77FROM node:18-alpine AS builder78WORKDIR /app79COPY package*.json ./80RUN npm ci --only=production81COPY . .82RUN npm run build8384# Production stage - Nginx85FROM nginx:alpine AS production86COPY nginx.conf /etc/nginx/nginx.conf87COPY --from=builder /app/dist /usr/share/nginx/html88EXPOSE 300089CMD ["nginx", "-g", "daemon off;"]90```9192## Environment Configuration9394### Environment Variables95Define environment variables in `.env` file or through Docker Compose:9697```env98# Database99DB_HOST=postgres100DB_PORT=5432101DB_USER=postgres102DB_PASSWORD=postgres123103DB_NAME=pos_system104105# Backend106PORT=8080107GIN_MODE=release108109# Frontend110VITE_API_URL=http://localhost:8080111```112113### Security Considerations114- Use Docker secrets for sensitive data in production115- Avoid hardcoding credentials in Dockerfiles116- Use separate environment files for different stages117- Rotate passwords and API keys regularly118119## Volume Management120121### Persistent Data Storage122Database data persists using named volumes:123```yaml124volumes:125 postgres_data:126 driver: local127128services:129 postgres:130 volumes:131 - postgres_data:/var/lib/postgresql/data132```133134### Development Volume Mounts135Mount source code for hot reloading in development:136```yaml137services:138 backend:139 volumes:140 - ./backend:/app141 frontend:142 volumes:143 - ./frontend:/app144 - /app/node_modules # Anonymous volume for node_modules145```146147## Nginx Configuration148149### Reverse Proxy Setup150Nginx configuration in [frontend/nginx.conf](mdc:frontend/nginx.conf):151152```nginx153# API proxy to backend154location /api {155 proxy_pass http://backend:8080;156 proxy_set_header Host $host;157 proxy_set_header X-Real-IP $remote_addr;158 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;159}160161# SPA routing for React162location / {163 try_files $uri $uri/ /index.html;164}165```166167### Performance Optimization168- Gzip compression for static assets169- Proper caching headers for assets170- Security headers (CORS, XSS protection)171- Health check endpoint for load balancers172173## Health Checks & Monitoring174175### Container Health Checks176Define health checks in Docker Compose:177```yaml178services:179 backend:180 healthcheck:181 test: ["CMD", "curl", "-f", "http://localhost:8080/health"]182 interval: 30s183 timeout: 10s184 retries: 3185 start_period: 40s186187 frontend:188 healthcheck:189 test: ["CMD", "curl", "-f", "http://localhost:3000/health"]190 interval: 30s191 timeout: 3s192 retries: 3193```194195### Restart Policies196Configure appropriate restart policies:197```yaml198services:199 postgres:200 restart: unless-stopped201 backend:202 restart: unless-stopped203 frontend:204 restart: unless-stopped205```206207## Database Initialization208209### Schema & Seed Data210Database automatically initializes using scripts in [database/init/](mdc:database/init/):211- [01_schema.sql](mdc:database/init/01_schema.sql) - Table structure and indexes212- [02_seed_data.sql](mdc:database/init/02_seed_data.sql) - Sample data for development213214### Backup Strategies215```bash216# Create database backup217docker exec pos-postgres pg_dump -U postgres pos_system > backup.sql218219# Restore database220docker exec -i pos-postgres psql -U postgres pos_system < backup.sql221```222223## Development Workflow224Use the comprehensive [Makefile](mdc:Makefile) for all operations:225```bash226# Essential commands227make dev # Start development environment228make up # Start containers in background229make down # Stop all containers230make status # Check service status231```232233### Database Operations234```bash235# Interactive database management236make create-admin # Create super admin user237make backup # Backup database and files238make restore # Restore from backup239make db-shell # Access PostgreSQL shell240make db-reset # Reset with fresh data241```242243### Legacy Commands (use Makefile instead)244```bash245# Start all services (legacy)246docker-compose up -d247248# View logs (use: make logs)249docker-compose logs -f backend250251# Stop services (use: make down)252docker-compose down253254# Rebuild containers (use: make rebuild)255docker-compose up --build256```257258## Production Deployment259260### Container Registry261Build and push images for production deployment:262```bash263# Build images264docker build -t pos-backend:latest ./backend265docker build -t pos-frontend:latest ./frontend266267# Tag for registry268docker tag pos-backend:latest your-registry/pos-backend:v1.0.0269docker tag pos-frontend:latest your-registry/pos-frontend:v1.0.0270271# Push to registry272docker push your-registry/pos-backend:v1.0.0273docker push your-registry/pos-frontend:v1.0.0274```275276### Deployment Checklist277- [ ] Environment variables configured278- [ ] SSL/TLS certificates installed279- [ ] Database backups scheduled280- [ ] Monitoring and logging configured281- [ ] Security scanning completed282- [ ] Load balancer configured (if needed)283- [ ] Domain name and DNS configured284285## Security Best Practices286287### Container Security288- Use non-root users in containers where possible289- Keep base images updated290- Scan images for vulnerabilities291- Minimize attack surface (minimal base images)292- Use specific image tags, avoid 'latest'293294### Network Security295- Use internal networks for service communication296- Expose only necessary ports297- Implement proper firewall rules298- Use HTTPS/TLS for external communication299300## Performance Optimization301302### Build Optimization303- Use multi-stage builds to reduce image size304- Leverage Docker build cache effectively305- Use .dockerignore to exclude unnecessary files306- Optimize layer ordering for better caching307308### Runtime Optimization309- Set appropriate resource limits (CPU, memory)310- Use init systems for proper signal handling311- Configure log rotation to prevent disk space issues312- Monitor resource usage and adjust limits accordingly313314## Troubleshooting315316### Common Issues3171. **Port conflicts** - Ensure ports 3000, 8080, 5432 are available3182. **Volume permissions** - Check file permissions for mounted volumes3193. **Network connectivity** - Verify service communication within Docker network3204. **Environment variables** - Validate all required env vars are set3215. **Database connection** - Wait for database to be ready before starting backend322323### Debugging Commands324```bash325# Check container logs326docker-compose logs [service-name]327328# Execute commands in container329docker-compose exec backend sh330docker-compose exec postgres psql -U postgres pos_system331332# Check network connectivity333docker-compose exec backend wget -qO- http://postgres:5432334335# Inspect container details336docker inspect pos-backend337```338339## 🚀 Production Deployment Strategies340341### Container Registry Best Practices342```bash343# ✅ CORRECT: Multi-architecture builds for production344docker buildx create --name pos-builder --use345docker buildx build --platform linux/amd64,linux/arm64 -t pos-backend:latest ./backend --push346347# ✅ CORRECT: Semantic versioning for releases348docker build -t pos-backend:1.2.3 ./backend349docker build -t pos-backend:latest ./backend350351# Security scanning before deployment352docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \353 aquasec/trivy image pos-backend:1.2.3354```355356### Production Docker Compose357```yaml358# docker-compose.prod.yml - Production configuration359version: '3.8'360361services:362 postgres:363 image: postgres:15-alpine364 environment:365 POSTGRES_DB: ${DB_NAME}366 POSTGRES_USER: ${DB_USER}367 POSTGRES_PASSWORD_FILE: /run/secrets/db_password368 PGDATA: /var/lib/postgresql/data/pgdata369 volumes:370 - postgres_data:/var/lib/postgresql/data371 - ./database/init:/docker-entrypoint-initdb.d372 secrets:373 - db_password374 healthcheck:375 test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]376 interval: 10s377 timeout: 5s378 retries: 5379 start_period: 30s380 restart: unless-stopped381382 backend:383 image: your-registry/pos-backend:${VERSION}384 environment:385 DB_HOST: postgres386 DB_PORT: 5432387 DB_USER: ${DB_USER}388 DB_PASSWORD_FILE: /run/secrets/db_password389 JWT_SECRET_FILE: /run/secrets/jwt_secret390 GIN_MODE: release391 secrets:392 - db_password393 - jwt_secret394 depends_on:395 postgres:396 condition: service_healthy397 healthcheck:398 test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/health"]399 interval: 30s400 timeout: 10s401 retries: 3402 start_period: 40s403 restart: unless-stopped404 deploy:405 resources:406 limits:407 memory: 512M408 cpus: '0.5'409 reservations:410 memory: 256M411 cpus: '0.25'412413 frontend:414 image: your-registry/pos-frontend:${VERSION}415 environment:416 VITE_API_URL: ${API_URL}417 depends_on:418 backend:419 condition: service_healthy420 healthcheck:421 test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:80"]422 interval: 30s423 timeout: 3s424 retries: 3425 restart: unless-stopped426 ports:427 - "80:80"428 - "443:443"429 deploy:430 resources:431 limits:432 memory: 128M433 cpus: '0.25'434435secrets:436 db_password:437 external: true438 name: pos_db_password439 jwt_secret:440 external: true441 name: pos_jwt_secret442443volumes:444 postgres_data:445 driver: local446447networks:448 default:449 driver: overlay450 attachable: true451```452453### Docker Secrets Management454```bash455# ✅ CORRECT: Create production secrets456echo "your-strong-db-password" | docker secret create pos_db_password -457echo "your-jwt-secret-key-256-bits-long" | docker secret create pos_jwt_secret -458459# Deploy with secrets460docker stack deploy -c docker-compose.prod.yml pos-system461462# Rotate secrets (zero downtime)463echo "new-password" | docker secret create pos_db_password_v2 -464# Update compose file to use new secret465docker stack deploy -c docker-compose.prod.yml pos-system466docker secret rm pos_db_password467```468469## 🏗️ CI/CD Pipeline Patterns470471### GitHub Actions Workflow472```yaml473# .github/workflows/deploy.yml474name: Build and Deploy POS System475476on:477 push:478 branches: [ main ]479 pull_request:480 branches: [ main ]481482env:483 REGISTRY: ghcr.io484 IMAGE_BASE: ${{ github.repository }}485486jobs:487 test:488 runs-on: ubuntu-latest489 services:490 postgres:491 image: postgres:15492 env:493 POSTGRES_PASSWORD: postgres494 POSTGRES_DB: pos_test495 options: >-496 --health-cmd pg_isready497 --health-interval 10s498 --health-timeout 5s499 --health-retries 5500501 steps:502 - uses: actions/checkout@v4503504 - name: Set up Go505 uses: actions/setup-go@v4506 with:507 go-version: '1.21'508509 - name: Set up Node.js510 uses: actions/setup-node@v4511 with:512 node-version: '18'513 cache: 'npm'514 cache-dependency-path: frontend/package-lock.json515516 - name: Run backend tests517 run: |518 cd backend519 go test -v -race -coverprofile=coverage.out ./...520 go tool cover -html=coverage.out -o coverage.html521522 - name: Run frontend tests523 run: |524 cd frontend525 npm ci526 npm run test:coverage527528 - name: Upload coverage to Codecov529 uses: codecov/codecov-action@v3530531 security:532 runs-on: ubuntu-latest533 steps:534 - uses: actions/checkout@v4535536 - name: Run Trivy vulnerability scanner537 uses: aquasecurity/trivy-action@master538 with:539 scan-type: 'fs'540 scan-ref: '.'541 format: 'sarif'542 output: 'trivy-results.sarif'543544 - name: Upload Trivy scan results to GitHub Security tab545 uses: github/codeql-action/upload-sarif@v2546 with:547 sarif_file: 'trivy-results.sarif'548549 build:550 needs: [test, security]551 runs-on: ubuntu-latest552 outputs:553 backend-image: ${{ steps.meta-backend.outputs.tags }}554 frontend-image: ${{ steps.meta-frontend.outputs.tags }}555556 steps:557 - uses: actions/checkout@v4558559 - name: Set up Docker Buildx560 uses: docker/setup-buildx-action@v3561562 - name: Login to Container Registry563 uses: docker/login-action@v3564 with:565 registry: ${{ env.REGISTRY }}566 username: ${{ github.actor }}567 password: ${{ secrets.GITHUB_TOKEN }}568569 - name: Extract backend metadata570 id: meta-backend571 uses: docker/metadata-action@v5572 with:573 images: ${{ env.REGISTRY }}/${{ env.IMAGE_BASE }}/backend574 tags: |575 type=ref,event=branch576 type=ref,event=pr577 type=sha,prefix={{branch}}-578 type=raw,value=latest,enable={{is_default_branch}}579580 - name: Build and push backend581 uses: docker/build-push-action@v5582 with:583 context: ./backend584 platforms: linux/amd64,linux/arm64585 push: true586 tags: ${{ steps.meta-backend.outputs.tags }}587 labels: ${{ steps.meta-backend.outputs.labels }}588 cache-from: type=gha589 cache-to: type=gha,mode=max590591 - name: Extract frontend metadata592 id: meta-frontend593 uses: docker/metadata-action@v5594 with:595 images: ${{ env.REGISTRY }}/${{ env.IMAGE_BASE }}/frontend596 tags: |597 type=ref,event=branch598 type=ref,event=pr599 type=sha,prefix={{branch}}-600 type=raw,value=latest,enable={{is_default_branch}}601602 - name: Build and push frontend603 uses: docker/build-push-action@v5604 with:605 context: ./frontend606 platforms: linux/amd64,linux/arm64607 push: true608 tags: ${{ steps.meta-frontend.outputs.tags }}609 labels: ${{ steps.meta-frontend.outputs.labels }}610 cache-from: type=gha611 cache-to: type=gha,mode=max612613 deploy:614 needs: build615 runs-on: ubuntu-latest616 if: github.ref == 'refs/heads/main'617 environment: production618619 steps:620 - uses: actions/checkout@v4621622 - name: Deploy to production623 run: |624 # Replace with your deployment method (SSH, K8s, etc.)625 echo "Deploying POS System to production..."626 echo "Backend: ${{ needs.build.outputs.backend-image }}"627 echo "Frontend: ${{ needs.build.outputs.frontend-image }}"628```629630## 📊 Monitoring & Observability631632### Prometheus Monitoring Setup633```yaml634# monitoring/docker-compose.monitoring.yml635version: '3.8'636637services:638 prometheus:639 image: prom/prometheus:latest640 container_name: pos-prometheus641 command:642 - '--config.file=/etc/prometheus/prometheus.yml'643 - '--storage.tsdb.path=/prometheus'644 - '--web.console.libraries=/etc/prometheus/console_libraries'645 - '--web.console.templates=/etc/prometheus/consoles'646 - '--storage.tsdb.retention.time=200h'647 - '--web.enable-lifecycle'648 ports:649 - "9090:9090"650 volumes:651 - ./prometheus.yml:/etc/prometheus/prometheus.yml652 - prometheus_data:/prometheus653 restart: unless-stopped654655 grafana:656 image: grafana/grafana:latest657 container_name: pos-grafana658 ports:659 - "3001:3000"660 environment:661 - GF_SECURITY_ADMIN_USER=admin662 - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}663 - GF_USERS_ALLOW_SIGN_UP=false664 volumes:665 - grafana_data:/var/lib/grafana666 - ./grafana/provisioning:/etc/grafana/provisioning667 - ./grafana/dashboards:/var/lib/grafana/dashboards668 restart: unless-stopped669670 node-exporter:671 image: prom/node-exporter:latest672 container_name: pos-node-exporter673 command:674 - '--path.procfs=/host/proc'675 - '--path.rootfs=/rootfs'676 - '--path.sysfs=/host/sys'677 - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'678 ports:679 - "9100:9100"680 volumes:681 - /proc:/host/proc:ro682 - /sys:/host/sys:ro683 - /:/rootfs:ro684 restart: unless-stopped685686 postgres-exporter:687 image: prometheuscommunity/postgres-exporter:latest688 container_name: pos-postgres-exporter689 environment:690 DATA_SOURCE_NAME: "postgresql://${DB_USER}:${DB_PASSWORD}@postgres:5432/${DB_NAME}?sslmode=disable"691 ports:692 - "9187:9187"693 restart: unless-stopped694695 cadvisor:696 image: gcr.io/cadvisor/cadvisor:latest697 container_name: pos-cadvisor698 ports:699 - "8080:8080"700 volumes:701 - /:/rootfs:ro702 - /var/run:/var/run:ro703 - /sys:/sys:ro704 - /var/lib/docker/:/var/lib/docker:ro705 - /dev/disk/:/dev/disk:ro706 privileged: true707 devices:708 - /dev/kmsg709 restart: unless-stopped710711volumes:712 prometheus_data:713 grafana_data:714```715716### Application Metrics in Go Backend717```go718// metrics/metrics.go719package metrics720721import (722 "github.com/prometheus/client_golang/prometheus"723 "github.com/prometheus/client_golang/prometheus/promauto"724)725726var (727 OrdersCreated = promauto.NewCounterVec(728 prometheus.CounterOpts{729 Name: "pos_orders_created_total",730 Help: "Total number of orders created",731 },732 []string{"order_type", "user_role"},733 )734735 PaymentProcessed = promauto.NewCounterVec(736 prometheus.CounterOpts{737 Name: "pos_payments_processed_total",738 Help: "Total number of payments processed",739 },740 []string{"payment_method", "status"},741 )742743 DatabaseQueries = promauto.NewHistogramVec(744 prometheus.HistogramOpts{745 Name: "pos_database_query_duration_seconds",746 Help: "Database query duration",747 Buckets: prometheus.DefBuckets,748 },749 []string{"query_type"},750 )751752 HTTPRequestDuration = promauto.NewHistogramVec(753 prometheus.HistogramOpts{754 Name: "pos_http_request_duration_seconds",755 Help: "HTTP request duration",756 Buckets: prometheus.DefBuckets,757 },758 []string{"method", "path", "status_code"},759 )760)761762// Middleware for HTTP request metrics763func PrometheusMiddleware() gin.HandlerFunc {764 return gin.HandlerFunc(func(c *gin.Context) {765 start := time.Now()766767 c.Next()768769 duration := time.Since(start).Seconds()770 status := strconv.Itoa(c.Writer.Status())771772 HTTPRequestDuration.WithLabelValues(773 c.Request.Method,774 c.Request.URL.Path,775 status,776 ).Observe(duration)777 })778}779```780781### Logging Configuration782```go783// logging/logger.go784package logging785786import (787 "os"788 "github.com/sirupsen/logrus"789 "github.com/gin-gonic/gin"790)791792func SetupLogger() *logrus.Logger {793 logger := logrus.New()794795 // JSON logging for production796 if gin.Mode() == gin.ReleaseMode {797 logger.SetFormatter(&logrus.JSONFormatter{798 TimestampFormat: "2006-01-02T15:04:05.999Z07:00",799 })800 logger.SetLevel(logrus.InfoLevel)801 } else {802 logger.SetFormatter(&logrus.TextFormatter{803 FullTimestamp: true,804 })805 logger.SetLevel(logrus.DebugLevel)806 }807808 logger.SetOutput(os.Stdout)809 return logger810}811812// Structured logging middleware813func LoggingMiddleware(logger *logrus.Logger) gin.HandlerFunc {814 return gin.HandlerFunc(func(c *gin.Context) {815 start := time.Now()816817 c.Next()818819 logger.WithFields(logrus.Fields{820 "method": c.Request.Method,821 "path": c.Request.URL.Path,822 "status": c.Writer.Status(),823 "duration": time.Since(start),824 "ip": c.ClientIP(),825 "user_agent": c.Request.UserAgent(),826 "user_id": c.GetString("user_id"),827 }).Info("HTTP Request")828 })829}830```831832## 🔒 Production Security Hardening833834### Enhanced Dockerfile Security835```dockerfile836# Secure Golang Dockerfile837FROM golang:1.21-alpine AS builder838839# Create non-root user for build840RUN addgroup -g 1001 -S appgroup && \841 adduser -S appuser -u 1001 -G appgroup842843# Install security updates844RUN apk update && apk upgrade && apk add --no-cache ca-certificates git845846WORKDIR /app847COPY go.mod go.sum ./848RUN go mod download && go mod verify849850COPY . .851852# Build with security flags853RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \854 go build -ldflags='-w -s -extldflags "-static"' -o main .855856# Production stage with minimal attack surface857FROM alpine:3.18858859# Security updates and minimal tools860RUN apk update && apk upgrade && \861 apk add --no-cache ca-certificates && \862 rm -rf /var/cache/apk/*863864# Create non-root user865RUN addgroup -g 1001 -S appgroup && \866 adduser -S appuser -u 1001 -G appgroup867868# Set up app directory869WORKDIR /app870COPY --from=builder --chown=appuser:appgroup /app/main .871872# Switch to non-root user873USER appuser874875# Health check876HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \877 CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1878879EXPOSE 8080880CMD ["./main"]881```882883### Nginx Security Configuration884```nginx885# nginx.conf - Production security hardening886user nginx;887worker_processes auto;888pid /var/run/nginx.pid;889890events {891 worker_connections 1024;892 use epoll;893 multi_accept on;894}895896http {897 # Security headers898 add_header X-Frame-Options "SAMEORIGIN" always;899 add_header X-Content-Type-Options "nosniff" always;900 add_header X-XSS-Protection "1; mode=block" always;901 add_header Referrer-Policy "no-referrer-when-downgrade" always;902 add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';" always;903904 # Hide server version905 server_tokens off;906907 # Rate limiting908 limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;909 limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;910911 # SSL Configuration (when using HTTPS)912 ssl_protocols TLSv1.2 TLSv1.3;913 ssl_prefer_server_ciphers on;914 ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;915916 # Gzip compression917 gzip on;918 gzip_vary on;919 gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript;920921 server {922 listen 80;923 server_name localhost;924 root /usr/share/nginx/html;925 index index.html;926927 # API proxy with rate limiting928 location /api/v1/auth/login {929 limit_req zone=login burst=3 nodelay;930 proxy_pass http://backend:8080;931 proxy_set_header Host $host;932 proxy_set_header X-Real-IP $remote_addr;933 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;934 proxy_set_header X-Forwarded-Proto $scheme;935 }936937 location /api/ {938 limit_req zone=api burst=20 nodelay;939 proxy_pass http://backend:8080;940 proxy_set_header Host $host;941 proxy_set_header X-Real-IP $remote_addr;942 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;943 proxy_set_header X-Forwarded-Proto $scheme;944 }945946 # SPA routing947 location / {948 try_files $uri $uri/ /index.html;949 expires 1d;950 }951952 # Security for static assets953 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {954 expires 1y;955 add_header Cache-Control "public, immutable";956 }957 }958}959```960961## 🚀 Kubernetes Deployment (Optional)962963### Kubernetes Manifests964```yaml965# k8s/namespace.yaml966apiVersion: v1967kind: Namespace968metadata:969 name: pos-system970971---972# k8s/postgres.yaml973apiVersion: apps/v1974kind: StatefulSet975metadata:976 name: postgres977 namespace: pos-system978spec:979 serviceName: postgres980 replicas: 1981 selector:982 matchLabels:983 app: postgres984 template:985 metadata:986 labels:987 app: postgres988 spec:989 containers:990 - name: postgres991 image: postgres:15-alpine992 env:993 - name: POSTGRES_DB994 value: pos_system995 - name: POSTGRES_USER996 value: postgres997 - name: POSTGRES_PASSWORD998 valueFrom:999 secretKeyRef:1000 name: postgres-secret1001 key: password1002 volumeMounts:1003 - name: postgres-storage1004 mountPath: /var/lib/postgresql/data1005 ports:1006 - containerPort: 54321007 livenessProbe:1008 exec:1009 command: ["pg_isready", "-U", "postgres"]1010 initialDelaySeconds: 301011 periodSeconds: 101012 readinessProbe:1013 exec:1014 command: ["pg_isready", "-U", "postgres"]1015 initialDelaySeconds: 51016 periodSeconds: 51017 volumeClaimTemplates:1018 - metadata:1019 name: postgres-storage1020 spec:1021 accessModes: ["ReadWriteOnce"]1022 resources:1023 requests:1024 storage: 10Gi10251026---1027# k8s/backend.yaml1028apiVersion: apps/v11029kind: Deployment1030metadata:1031 name: backend1032 namespace: pos-system1033spec:1034 replicas: 21035 selector:1036 matchLabels:1037 app: backend1038 template:1039 metadata:1040 labels:1041 app: backend1042 spec:1043 containers:1044 - name: backend1045 image: your-registry/pos-backend:latest1046 env:1047 - name: DB_HOST1048 value: postgres-service1049 - name: DB_PASSWORD1050 valueFrom:1051 secretKeyRef:1052 name: postgres-secret1053 key: password1054 ports:1055 - containerPort: 80801056 livenessProbe:1057 httpGet:1058 path: /health1059 port: 80801060 initialDelaySeconds: 301061 periodSeconds: 101062 readinessProbe:1063 httpGet:1064 path: /health1065 port: 80801066 initialDelaySeconds: 51067 periodSeconds: 51068 resources:1069 requests:1070 memory: "256Mi"1071 cpu: "250m"1072 limits:1073 memory: "512Mi"1074 cpu: "500m"1075```10761077## 📈 Performance & Scaling Patterns10781079### Horizontal Pod Autoscaling (K8s)1080```yaml1081apiVersion: autoscaling/v21082kind: HorizontalPodAutoscaler1083metadata:1084 name: backend-hpa1085 namespace: pos-system1086spec:1087 scaleTargetRef:1088 apiVersion: apps/v11089 kind: Deployment1090 name: backend1091 minReplicas: 21092 maxReplicas: 101093 metrics:1094 - type: Resource1095 resource:1096 name: cpu1097 target:1098 type: Utilization1099 averageUtilization: 701100 - type: Resource1101 resource:1102 name: memory1103 target:1104 type: Utilization1105 averageUtilization: 801106```11071108### Docker Swarm Scaling1109```bash1110# Scale services in Docker Swarm1111docker service scale pos-system_backend=31112docker service scale pos-system_frontend=211131114# Rolling updates1115docker service update --image pos-backend:v1.2.3 pos-system_backend1116```11171118## 🔧 Advanced Deployment Tools11191120### Makefile Enhancement for Production1121```makefile1122# Production deployment commands1123.PHONY: deploy-prod deploy-staging backup-prod restore-prod11241125deploy-prod: ## Deploy to production1126 @echo "🚀 Deploying to production..."1127 docker stack deploy -c docker-compose.prod.yml pos-system1128 @echo "✅ Production deployment complete"11291130deploy-staging: ## Deploy to staging1131 @echo "🧪 Deploying to staging..."1132 docker-compose -f docker-compose.staging.yml up -d1133 @echo "✅ Staging deployment complete"11341135backup-prod: ## Backup production database1136 @echo "💾 Creating production backup..."1137 docker exec $$(docker ps -q -f name=pos-postgres) pg_dump -U postgres pos_system > "backup-prod-$$(date +%Y%m%d-%H%M%S).sql"1138 @echo "✅ Production backup complete"11391140restore-prod: ## Restore production from backup1141 @read -p "Enter backup file path: " backup; \1142 echo "🔄 Restoring production from $$backup..."; \1143 docker exec -i $$(docker ps -q -f name=pos-postgres) psql -U postgres pos_system < $$backup1144 @echo "✅ Production restore complete"11451146health-check: ## Check production health1147 @echo "🏥 Checking system health..."1148 @curl -f http://localhost/health || echo "❌ Frontend health check failed"1149 @curl -f http://localhost:8080/health || echo "❌ Backend health check failed"1150 @echo "✅ Health checks complete"1151```
Also in madebyaris/poinf-of-sales
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| madebyaris/poinf-of-sales.cursor/rules/admin-interface-patterns.mdc · 118 | Cursor rules | stylearchsecurityapi+2 | 62/100 | 3 days ago | |
| madebyaris/poinf-of-sales.cursor/rules/api-patterns.mdc · 118 | Cursor rules | lint-formatstylesecuritydatabase+3 | 62/100 | 3 days ago | |
| madebyaris/poinf-of-sales.cursor/rules/authentication-and-security-patterns.mdc · 118 | Cursor rules | setupteststylesecurity+4 | 81/100 | 3 days ago | |
| madebyaris/poinf-of-sales.cursor/rules/backend-golang.mdc · 118 | Cursor rules | testlint-formatstylearch+5 | 69/100 | 3 days ago | |
| madebyaris/poinf-of-sales.cursor/rules/business-logic-patterns.mdc · 118 | Cursor rules | teststyledatabaseperformance+1 | 50/100 | 3 days ago | |
| madebyaris/poinf-of-sales.cursor/rules/database-patterns.mdc · 118 | Cursor rules | stylearchtypessecurity+2 | 62/100 | 3 days ago | |
| madebyaris/poinf-of-sales.cursor/rules/development-workflow.mdc · 118 | Cursor rules | setupbuildteststyle+3 | 86/100 | 3 days ago | |
| madebyaris/poinf-of-sales.cursor/rules/frontend-react.mdc · 118 | Cursor rules | buildtestlint-formatstyle+4 | 69/100 | 3 days ago | |
| madebyaris/poinf-of-sales.cursor/rules/makefile-scripting.mdc · 118 | Cursor rules | setuplint-formatstylearch+2 | 81/100 | 3 days ago | |
| madebyaris/poinf-of-sales.cursor/rules/performance-optimization-patterns.mdc · 118 | Cursor rules | buildteststyledatabase+3 | 66/100 | 3 days ago | |
| madebyaris/poinf-of-sales.cursor/rules/project-architecture.mdc · 118 | Cursor rules | setupteststylearch+6 | 78/100 | 3 days ago | |
| madebyaris/poinf-of-sales.cursor/rules/react-native-mobile-patterns.mdc · 118 | Cursor rules | buildstylearchui+2 | 74/100 | 3 days ago | |
| madebyaris/poinf-of-sales.cursor/rules/role-based-access-patterns.mdc · 118 | Cursor rules | styletypessecuritydatabase+2 | 58/100 | 3 days ago | |
| madebyaris/poinf-of-sales.cursor/rules/tech-debt-prevention.mdc · 118 | Cursor rules | styletesting-strategyui | 50/100 | 3 days ago | |
| madebyaris/poinf-of-sales.cursor/rules/testing-patterns.mdc · 118 | Cursor rules | setupteststylearch+4 | 74/100 | 3 days ago | |
| madebyaris/poinf-of-sales.cursor/rules/user-journey-optimization.mdc · 118 | Cursor rules | styleperformanceagent-behaviour | 50/100 | 3 days ago |
Diff against .cursor/rules/admin-interface-patterns.mdc Diff against .cursor/rules/api-patterns.mdc Diff against .cursor/rules/authentication-and-security-patterns.mdc Diff against .cursor/rules/backend-golang.mdc Diff against .cursor/rules/business-logic-patterns.mdc Diff against .cursor/rules/database-patterns.mdc Diff against .cursor/rules/development-workflow.mdc Diff against .cursor/rules/frontend-react.mdc Diff against .cursor/rules/makefile-scripting.mdc Diff against .cursor/rules/performance-optimization-patterns.mdc Diff against .cursor/rules/project-architecture.mdc Diff against .cursor/rules/react-native-mobile-patterns.mdc Diff against .cursor/rules/role-based-access-patterns.mdc Diff against .cursor/rules/tech-debt-prevention.mdc Diff against .cursor/rules/testing-patterns.mdc Diff against .cursor/rules/user-journey-optimization.mdc
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126 | Cursor rules | setupbuildtestlint-format+6 | 100/100 | 3 days ago | |
| TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 45 | Cursor rules | testlint-formatstylearch+5 | 100/100 | 3 days ago | |
| dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 3 days ago | |
| deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 3 days ago | |
| markstev/mark-starter.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+6 | 99/100 | 3 days ago | |
| Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 3 days ago | |
| langflow-ai/langflow.cursor/rules/docs_development.mdc · 153k | Cursor rules | setupbuildtestlint-format+7 | 97/100 | 3 days ago | |
| TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 45 | Cursor rules | teststyletesting-strategysecurity+3 | 97/100 | 3 days ago |
