DEV Community

Daniel Ioni
Daniel Ioni

Posted on

๐Ÿš€ Deploying MyZubster to Production

๐Ÿš€ Deploying MyZubster to Production

Complete guide to deploying MyZubster โ€“ from development to production
๐Ÿ“Œ What You'll Learn

This guide covers everything you need to deploy MyZubster to production:

โœ… Docker containerization โ€“ Build and run all services

โœ… Cloud deployment โ€“ AWS, DigitalOcean, and Vercel

โœ… Kubernetes โ€“ Scale your deployment

โœ… SSL/TLS โ€“ Secure your domain with HTTPS

โœ… Monitoring โ€“ Track performance and uptime

โœ… Logging โ€“ Centralized log management

โœ… Backup & Recovery โ€“ Protect your data

โœ… CI/CD โ€“ Automated deployment pipeline
Enter fullscreen mode Exit fullscreen mode

๐Ÿงฉ Architecture Overview
text

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Production Architecture โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ Load Balancer (Nginx/Cloudflare) โ”‚ โ”‚
โ”‚ โ”‚ https://myzubster.com โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ”‚ โ”‚
โ”‚ โ–ผ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ Reverse Proxy (Nginx/Traefik) โ”‚ โ”‚
โ”‚ โ”‚ SSL Termination โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ”‚ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚
โ”‚ โ–ผ โ–ผ โ–ผ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ Gateway โ”‚ โ”‚ Marketplace โ”‚ โ”‚ Mobile App โ”‚ โ”‚
โ”‚ โ”‚ (Port 3000) โ”‚ (Port 4000) โ”‚ (Vercel) โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ”‚ โ”‚
โ”‚ โ–ผ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ Database Layer โ”‚ โ”‚
โ”‚ โ”‚ โ”‚ โ”‚
โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚
โ”‚ โ”‚ โ”‚ MongoDB โ”‚ โ”‚ PostgreSQL โ”‚ โ”‚ Redis โ”‚ โ”‚ โ”‚
โ”‚ โ”‚ โ”‚ (Gateway) โ”‚ โ”‚(Marketplace)โ”‚ โ”‚ (Cache) โ”‚ โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ Monitoring & Logging โ”‚ โ”‚
โ”‚ โ”‚ โ”‚ โ”‚
โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚
โ”‚ โ”‚ โ”‚ Prometheus โ”‚ โ”‚ Grafana โ”‚ โ”‚ ELK Stack โ”‚ โ”‚ โ”‚
โ”‚ โ”‚ โ”‚ (Metrics) โ”‚ โ”‚(Dashboard) โ”‚ โ”‚ (Logs) โ”‚ โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ› ๏ธ Tech Stack for Production
Component Technology Purpose
Containerization Docker + Docker Compose Service isolation
Orchestration Kubernetes (optional) Scaling and management
Reverse Proxy Nginx / Traefik SSL, load balancing
Database PostgreSQL / MongoDB Data persistence
Cache Redis Session store, rate limiting
Monitoring Prometheus + Grafana Metrics and alerts
Logging ELK Stack (Elasticsearch, Logstash, Kibana) Log aggregation
CI/CD GitHub Actions Automated deployment
Cloud AWS / DigitalOcean / Vercel Hosting
๐Ÿ“‚ Production File Structure
text

myzubster-production/
โ”œโ”€โ”€ docker-compose.prod.yml # Production Docker Compose
โ”œโ”€โ”€ .env.prod # Production environment variables
โ”œโ”€โ”€ nginx/
โ”‚ โ”œโ”€โ”€ nginx.conf # Nginx configuration
โ”‚ โ””โ”€โ”€ ssl/
โ”‚ โ”œโ”€โ”€ myzubster.crt
โ”‚ โ””โ”€โ”€ myzubster.key
โ”œโ”€โ”€ gateway/
โ”‚ โ”œโ”€โ”€ Dockerfile.prod
โ”‚ โ””โ”€โ”€ .env.prod
โ”œโ”€โ”€ marketplace/
โ”‚ โ”œโ”€โ”€ Dockerfile.prod
โ”‚ โ””โ”€โ”€ .env.prod
โ”œโ”€โ”€ monitoring/
โ”‚ โ”œโ”€โ”€ prometheus.yml # Prometheus configuration
โ”‚ โ””โ”€โ”€ grafana-datasources.yml # Grafana datasources
โ”œโ”€โ”€ scripts/
โ”‚ โ”œโ”€โ”€ backup.sh # Database backup script
โ”‚ โ”œโ”€โ”€ deploy.sh # Deployment script
โ”‚ โ””โ”€โ”€ health-check.sh # Health check script
โ””โ”€โ”€ kubernetes/
โ”œโ”€โ”€ deployment.yaml
โ”œโ”€โ”€ service.yaml
โ””โ”€โ”€ ingress.yaml

๐Ÿ”ง Step 1: Docker Production Setup
1.1 Dockerfile for Gateway

File: gateway/Dockerfile.prod
dockerfile

Build stage

FROM node:18-alpine AS builder

WORKDIR /app

Copy package files

COPY package*.json ./
RUN npm ci --only=production

Copy source code

COPY . .

Production stage

FROM node:18-alpine

WORKDIR /app

Install production dependencies

COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app ./

Create non-root user

RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001

USER nodejs

EXPOSE 3000

CMD ["node", "server.js"]

1.2 Dockerfile for Marketplace

File: marketplace/Dockerfile.prod
dockerfile

Build stage

FROM node:18-alpine AS builder

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .

Production stage

FROM node:18-alpine

WORKDIR /app

COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app ./

RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001

USER nodejs

EXPOSE 4000

CMD ["node", "server.js"]

1.3 Docker Compose Production

File: docker-compose.prod.yml
yaml

version: '3.8'

services:
# PostgreSQL for Marketplace
postgres:
image: postgres:15-alpine
container_name: myzubster-postgres
restart: always
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=myzubster
- POSTGRES_USER=myzubster
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
networks:
- myzubster-network

# MongoDB for Gateway
mongodb:
image: mongo:6
container_name: myzubster-mongodb
restart: always
volumes:
- mongodb_data:/data/db
environment:
- MONGO_INITDB_ROOT_USERNAME=${MONGO_USERNAME}
- MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD}
networks:
- myzubster-network

# Redis for caching
redis:
image: redis:7-alpine
container_name: myzubster-redis
restart: always
networks:
- myzubster-network

# Gateway
gateway:
build:
context: ./gateway
dockerfile: Dockerfile.prod
container_name: myzubster-gateway
restart: always
environment:
- NODE_ENV=production
- PORT=3000
- MONGODB_URI=mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@mongodb:27017/myzubster?authSource=admin
- JWT_SECRET=${GATEWAY_JWT_SECRET}
- WEBHOOK_URL=http://marketplace:4000/webhook/order-update
- WEBHOOK_SECRET=${WEBHOOK_SECRET}
- REDIS_URL=redis://redis:6379
depends_on:
- mongodb
- redis
networks:
- myzubster-network

# Marketplace
marketplace:
build:
context: ./marketplace
dockerfile: Dockerfile.prod
container_name: myzubster-marketplace
restart: always
environment:
- NODE_ENV=production
- PORT=4000
- DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/myzubster
- JWT_SECRET=${MARKETPLACE_JWT_SECRET}
- MYZUBSTER_API_URL=http://gateway:3000/api
- MYZUBSTER_API_TOKEN=${MYZUBSTER_API_TOKEN}
- WEBHOOK_SECRET=${WEBHOOK_SECRET}
- REDIS_URL=redis://redis:6379
- COMMISSION_PERCENTAGE=${COMMISSION_PERCENTAGE}
depends_on:
- postgres
- redis
- gateway
networks:
- myzubster-network

# Nginx Reverse Proxy
nginx:
image: nginx:alpine
container_name: myzubster-nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
depends_on:
- gateway
- marketplace
networks:
- myzubster-network

# Prometheus for monitoring
prometheus:
image: prom/prometheus:latest
container_name: myzubster-prometheus
restart: always
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
networks:
- myzubster-network

# Grafana for dashboards
grafana:
image: grafana/grafana:latest
container_name: myzubster-grafana
restart: always
environment:
- GF_SECURITY_ADMIN_USER=${GRAFANA_USER}
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
volumes:
- ./monitoring/grafana-datasources.yml:/etc/grafana/provisioning/datasources/datasources.yml
- grafana_data:/var/lib/grafana
networks:
- myzubster-network

# Logstash for log aggregation
logstash:
image: docker.elastic.co/logstash/logstash:8.10.0
container_name: myzubster-logstash
restart: always
environment:
- XPACK_MONITORING_ENABLED=false
volumes:
- ./monitoring/logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro
networks:
- myzubster-network

# Elasticsearch for logs
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.10.0
container_name: myzubster-elasticsearch
restart: always
environment:
- discovery.type=single-node
- xpack.security.enabled=false
- ES_JAVA_OPTS=-Xms512m -Xmx512m
volumes:
- elasticsearch_data:/usr/share/elasticsearch/data
networks:
- myzubster-network

# Kibana for log visualization
kibana:
image: docker.elastic.co/kibana/kibana:8.10.0
container_name: myzubster-kibana
restart: always
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
networks:
- myzubster-network

volumes:
postgres_data:
mongodb_data:
prometheus_data:
grafana_data:
elasticsearch_data:

networks:
myzubster-network:
driver: bridge

๐ŸŒ Step 2: Nginx Configuration

File: nginx/nginx.conf
nginx

events {
worker_connections 1024;
}

http {
upstream gateway {
server gateway:3000;
}

upstream marketplace {
    server marketplace:4000;
}

# Redirect HTTP to HTTPS
server {
    listen 80;
    server_name myzubster.com www.myzubster.com;
    return 301 https://$server_name$request_uri;
}

# HTTPS Server
server {
    listen 443 ssl http2;
    server_name myzubster.com www.myzubster.com;

    # SSL Configuration
    ssl_certificate /etc/nginx/ssl/myzubster.crt;
    ssl_certificate_key /etc/nginx/ssl/myzubster.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # Security Headers
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";
    add_header Referrer-Policy "strict-origin-when-cross-origin";

    # Gateway API
    location /api/gateway/ {
        proxy_pass http://gateway/api/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        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;
    }

    # Marketplace API
    location /api/ {
        proxy_pass http://marketplace/api/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        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;
    }

    # Health check endpoint
    location /health {
        access_log off;
        return 200 "healthy\n";
        add_header Content-Type text/plain;
    }

    # Static files (for admin dashboard)
    location /admin/ {
        proxy_pass http://marketplace/admin/;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
    }
}
Enter fullscreen mode Exit fullscreen mode

}

โ˜๏ธ Step 3: Cloud Deployment
3.1 Deploy to DigitalOcean (Droplet)

Script: scripts/deploy-digitalocean.sh
bash

!/bin/bash

DigitalOcean Deployment Script

Usage: ./deploy-digitalocean.sh

set -e

Configuration

DROPLET_IP="your-droplet-ip"
DROPLET_USER="root"
PROJECT_DIR="/opt/myzubster"

echo "๐Ÿš€ Deploying MyZubster to DigitalOcean..."

Build Docker images

echo "๐Ÿ“ฆ Building Docker images..."
docker-compose -f docker-compose.prod.yml build

Push images to registry (or scp to server)

echo "๐Ÿ“ค Uploading to server..."
tar czf myzubster.tar.gz \
docker-compose.prod.yml \
.env.prod \
gateway/ \
marketplace/ \
nginx/ \
monitoring/

scp myzubster.tar.gz $DROPLET_USER@$DROPLET_IP:$PROJECT_DIR/

Deploy on server

ssh $DROPLET_USER@$DROPLET_IP << 'ENDSSH'
cd /opt/myzubster
tar xzf myzubster.tar.gz

Load environment variables

export $(cat .env.prod | xargs)

Start services

docker-compose -f docker-compose.prod.yml pull
docker-compose -f docker-compose.prod.yml up -d

Run migrations

docker-compose -f docker-compose.prod.yml exec marketplace npm run db:migrate

Health check

sleep 10
curl -f http://localhost:4000/health || exit 1

echo "โœ… Deployment successful!"
ENDSSH

echo "๐ŸŽ‰ Deployment complete!"

3.2 Deploy to Vercel (Admin Dashboard)

File: admin/vercel.json
json

{
"version": 2,
"builds": [
{
"src": "package.json",
"use": "@vercel/static-build",
"config": {
"distDir": "dist"
}
}
],
"routes": [
{
"src": "/(.*)",
"dest": "/index.html"
}
],
"env": {
"VITE_API_URL": "https://api.myzubster.com",
"VITE_GROQ_API_KEY": "@groq_api_key"
}
}

๐Ÿ” Step 4: SSL/TLS Configuration
4.1 Generate SSL Certificate (Let's Encrypt)

Script: scripts/ssl-setup.sh
bash

!/bin/bash

SSL Setup Script

Usage: ./ssl-setup.sh

set -e

DOMAIN="myzubster.com"
EMAIL="admin@myzubster.com"

echo "๐Ÿ”’ Setting up SSL with Let's Encrypt..."

Install Certbot

apt-get update
apt-get install -y certbot python3-certbot-nginx

Generate certificate

certbot --nginx \
-d $DOMAIN \
-d www.$DOMAIN \
--non-interactive \
--agree-tos \
--email $EMAIL

Auto-renewal

echo "0 0 1 * * certbot renew --quiet" | crontab -

echo "โœ… SSL setup complete!"

4.2 Manual SSL Setup (Using OpenSSL)
bash

Generate private key

openssl genrsa -out myzubster.key 2048

Generate certificate signing request

openssl req -new -key myzubster.key -out myzubster.csr

Self-signed certificate (development only)

openssl x509 -req -days 365 -in myzubster.csr -signkey myzubster.key -out myzubster.crt

๐Ÿ“Š Step 5: Monitoring Configuration
5.1 Prometheus Configuration

File: monitoring/prometheus.yml
yaml

global:
scrape_interval: 15s
evaluation_interval: 15s

alerting:
alertmanagers:
- static_configs:
- targets: []

rule_files:

  • "alerts.yml"

scrape_configs:

  • job_name: 'prometheus'
    static_configs:

    • targets: ['localhost:9090']
  • job_name: 'gateway'
    metrics_path: '/metrics'
    static_configs:

    • targets: ['gateway:3000']
  • job_name: 'marketplace'
    metrics_path: '/metrics'
    static_configs:

    • targets: ['marketplace:4000']
  • job_name: 'postgres'
    static_configs:

    • targets: ['postgres-exporter:9187']
  • job_name: 'mongodb'
    static_configs:

    • targets: ['mongodb-exporter:9216']
  • job_name: 'nginx'
    static_configs:

    • targets: ['nginx-exporter:9113']

5.2 Alert Rules

File: monitoring/alerts.yml
yaml

groups:

  • name: myzubster_alerts
    rules:

    • alert: HighErrorRate expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05 for: 5m labels: severity: critical annotations: summary: "High error rate detected" description: "Error rate is {{ $value }}"
    • alert: ServiceDown expr: up == 0 for: 1m labels: severity: critical annotations: summary: "Service {{ $labels.job }} is down" description: "Service has been down for more than 1 minute"
    • alert: HighLatency expr: histogram_quantile(0.95, http_request_duration_seconds_bucket) > 1 for: 5m labels: severity: warning annotations: summary: "High latency detected" description: "95th percentile latency is {{ $value }}s"
    • alert: DatabaseConnection expr: pg_stat_database_numbackends > 100 for: 5m labels: severity: warning annotations: summary: "Database connections high" description: "There are {{ $value }} database connections"
    • alert: LowDiskSpace expr: node_filesystem_avail_bytes / node_filesystem_size_bytes < 0.1 for: 5m labels: severity: critical annotations: summary: "Low disk space" description: "Only {{ $value }}% disk space available"

๐Ÿ“ Step 6: Backup & Recovery
6.1 Backup Script

File: scripts/backup.sh
bash

!/bin/bash

Backup Script

Usage: ./backup.sh

set -e

BACKUP_DIR="/backups"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30

echo "๐Ÿ“ฆ Starting backup at $DATE..."

Create backup directory

mkdir -p $BACKUP_DIR

Backup PostgreSQL (Marketplace)

echo "๐Ÿ’พ Backing up PostgreSQL..."
docker exec myzubster-postgres pg_dump -U myzubster myzubster > $BACKUP_DIR/postgres_$DATE.sql
gzip $BACKUP_DIR/postgres_$DATE.sql

Backup MongoDB (Gateway)

echo "๐Ÿ’พ Backing up MongoDB..."
docker exec myzubster-mongodb mongodump --username $MONGO_USERNAME --password $MONGO_PASSWORD --out /tmp/mongodb_backup
docker cp myzubster-mongodb:/tmp/mongodb_backup $BACKUP_DIR/mongodb_$DATE
tar czf $BACKUP_DIR/mongodb_$DATE.tar.gz -C $BACKUP_DIR mongodb_$DATE
rm -rf $BACKUP_DIR/mongodb_$DATE

Backup environment files

echo "๐Ÿ’พ Backing up environment files..."
cp .env.prod $BACKUP_DIR/env_$DATE.prod

Upload to S3 (optional)

aws s3 cp $BACKUP_DIR s3://myzubster-backups/ --recursive

Clean old backups

echo "๐Ÿงน Cleaning backups older than $RETENTION_DAYS days..."
find $BACKUP_DIR -name ".sql.gz" -mtime +$RETENTION_DAYS -delete
find $BACKUP_DIR -name "
.tar.gz" -mtime +$RETENTION_DAYS -delete

echo "โœ… Backup completed: $BACKUP_DIR"

6.2 Recovery Script

File: scripts/recover.sh
bash

!/bin/bash

Recovery Script

Usage: ./recover.sh

set -e

BACKUP_FILE=$1

if [ -z "$BACKUP_FILE" ]; then
echo "โŒ Usage: ./recover.sh "
exit 1
fi

echo "๐Ÿ”„ Starting recovery from $BACKUP_FILE..."

Stop services

echo "โน๏ธ Stopping services..."
docker-compose -f docker-compose.prod.yml down

Restore PostgreSQL

echo "๐Ÿ’พ Restoring PostgreSQL..."
docker-compose -f docker-compose.prod.yml up -d postgres
sleep 10
gunzip -c $BACKUP_FILE | docker exec -i myzubster-postgres psql -U myzubster myzubster

Restore MongoDB

echo "๐Ÿ’พ Restoring MongoDB..."
docker cp $BACKUP_FILE myzubster-mongodb:/tmp/
docker exec myzubster-mongodb mongorestore --username $MONGO_USERNAME --password $MONGO_PASSWORD /tmp/$(basename $BACKUP_FILE)

Start services

echo "โ–ถ๏ธ Starting services..."
docker-compose -f docker-compose.prod.yml up -d

echo "โœ… Recovery completed!"

๐Ÿ”„ Step 7: CI/CD Pipeline
7.1 GitHub Actions Workflow

File: .github/workflows/deploy.yml
yaml

name: Deploy to Production

on:
push:
branches:
- main
workflow_dispatch:

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
test:
name: Test
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3

  - name: Setup Node.js
    uses: actions/setup-node@v3
    with:
      node-version: '18'

  - name: Install dependencies
    run: |
      cd marketplace
      npm ci
      cd ../gateway
      npm ci

  - name: Run tests
    run: |
      cd marketplace
      npm test
      cd ../gateway
      npm test

  - name: Run linting
    run: |
      cd marketplace
      npm run lint
      cd ../gateway
      npm run lint
Enter fullscreen mode Exit fullscreen mode

build:
name: Build Docker Images
runs-on: ubuntu-latest
needs: test
steps:
- name: Checkout code
uses: actions/checkout@v3

  - name: Set up Docker Buildx
    uses: docker/setup-buildx-action@v2

  - name: Log in to Container Registry
    uses: docker/login-action@v2
    with:
      registry: ${{ env.REGISTRY }}
      username: ${{ github.actor }}
      password: ${{ secrets.GITHUB_TOKEN }}

  - name: Build and push Gateway
    uses: docker/build-push-action@v4
    with:
      context: ./gateway
      push: true
      tags: ${{ env.REGISTRY }}/${{ github.repository }}/gateway:latest
      cache-from: type=gha
      cache-to: type=gha,mode=max

  - name: Build and push Marketplace
    uses: docker/build-push-action@v4
    with:
      context: ./marketplace
      push: true
      tags: ${{ env.REGISTRY }}/${{ github.repository }}/marketplace:latest
      cache-from: type=gha
      cache-to: type=gha,mode=max
Enter fullscreen mode Exit fullscreen mode

deploy:
name: Deploy to Server
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy via SSH
uses: appleboy/ssh-action@v0.1.5
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
script: |
cd /opt/myzubster
docker-compose -f docker-compose.prod.yml pull
docker-compose -f docker-compose.prod.yml up -d
docker system prune -f
sleep 10
curl -f http://localhost:4000/health || exit 1
echo "โœ… Deployment successful!"

notify:
name: Send Notification
runs-on: ubuntu-latest
needs: deploy
steps:
- name: Send Slack notification
uses: slackapi/slack-github-action@v1.23.0
with:
channel-id: ${{ secrets.SLACK_CHANNEL_ID }}
slack-message: |
๐Ÿš€ Deployment Successful!
๐Ÿ“ฆ Version: ${{ github.sha }}
๐Ÿ“ Commit: ${{ github.event.head_commit.message }}
๐Ÿ‘ค Author: ${{ github.actor }}
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}

๐Ÿ“Š Step 8: Health Monitoring
8.1 Health Check Script

File: scripts/health-check.sh
bash

!/bin/bash

Health Check Script

Usage: ./health-check.sh

set -e

echo "๐Ÿ” Running health checks..."

Check Gateway

echo "๐Ÿ“ก Checking Gateway..."
if curl -f -s -o /dev/null "http://localhost:3000/api/health"; then
echo "โœ… Gateway is healthy"
else
echo "โŒ Gateway is unhealthy"
exit 1
fi

Check Marketplace

echo "๐Ÿ“ก Checking Marketplace..."
if curl -f -s -o /dev/null "http://localhost:4000/health"; then
echo "โœ… Marketplace is healthy"
else
echo "โŒ Marketplace is unhealthy"
exit 1
fi

Check PostgreSQL

echo "๐Ÿ“ก Checking PostgreSQL..."
if docker exec myzubster-postgres pg_isready -U myzubster; then
echo "โœ… PostgreSQL is healthy"
else
echo "โŒ PostgreSQL is unhealthy"
exit 1
fi

Check MongoDB

echo "๐Ÿ“ก Checking MongoDB..."
if docker exec myzubster-mongodb mongosh --eval "db.runCommand({ping: 1})"; then
echo "โœ… MongoDB is healthy"
else
echo "โŒ MongoDB is unhealthy"
exit 1
fi

Check Redis

echo "๐Ÿ“ก Checking Redis..."
if docker exec myzubster-redis redis-cli ping | grep -q "PONG"; then
echo "โœ… Redis is healthy"
else
echo "โŒ Redis is unhealthy"
exit 1
fi

echo "โœ… All services are healthy!"

๐Ÿš€ Step 9: Quick Deployment Commands
Deploy Everything
bash

Clone repository

git clone https://github.com/DanielIoni-creator/myzubster.git
cd myzubster

Copy production environment

cp .env.example .env.prod

Edit .env.prod with your values

nano .env.prod

Set up SSL

./scripts/ssl-setup.sh

Start services

docker-compose -f docker-compose.prod.yml up -d

Run health check

./scripts/health-check.sh

๐Ÿ› Troubleshooting
"Port already in use"
bash

Find and kill process

sudo lsof -i :443
sudo kill -9 [PID]

"Cannot connect to database"
bash

Check if PostgreSQL is running

docker ps | grep postgres

Check logs

docker logs myzubster-postgres

"SSL certificate expired"
bash

Renew Let's Encrypt certificate

certbot renew --dry-run

Renew with force

certbot renew --force-renewal

"High memory usage"
bash

Check container stats

docker stats

Optimize MongoDB

docker exec myzubster-mongodb mongosh --eval "db.adminCommand({setParameter: 1, cacheSizeGB: 2})"

๐Ÿ“š Resources

Docker Documentation: docs.docker.com

Kubernetes Documentation: kubernetes.io

DigitalOcean: digitalocean.com

AWS: aws.amazon.com

Let's Encrypt: letsencrypt.org

Prometheus: prometheus.io

Grafana: grafana.com
Enter fullscreen mode Exit fullscreen mode

๐ŸŒ Connect with Me

๐Ÿ“– Blog & Articles: DEV.to - Daniel Ioni
๐Ÿฆ X (Twitter): @myzubster
๐Ÿ’ผ LinkedIn: Daniel Ioni
๐Ÿ™ GitHub: DanielIoni-creator
๐ŸŽต TikTok: @h4x0r_23

โญ Star the project on GitHub โ€“ it helps a lot!

Built with โค๏ธ for privacy, freedom, and decentralization.

Happy deploying! ๐Ÿš€
โœ… Instructions for Publishing

Copy all the content above

Go to dev.to/new

Set the editor to Markdown mode

Paste the content

Title: Deploying MyZubster to Production: From Dev to Prod

Tags: devops, docker, kubernetes, opensource

Publish!
Enter fullscreen mode Exit fullscreen mode

Top comments (0)