Hosting Infrastructure
Related docs:
SDLC/DEPLOYMENT·CI/CD Pipeline·Microservices
1. Environment Topology
The Pakashop infrastructure is split into two identical stacks (Staging and Production) to ensure safe testing before going live.
| Component | Staging Environment (main) | Production Environment (production) |
|---|---|---|
| Frontend | Vercel (Staging) | Vercel (Production) |
| Backend API | AWS EC2 (Staging) | AWS EC2 (Production) |
| Database | RDS PostgreSQL (Staging) | RDS PostgreSQL (Production) |
| Redis | EC2 Redis (Staging) | EC2 Redis (Production) |
| Search | Meilisearch (Staging EC2) | Meilisearch (Production EC2) |
| CDN/DNS/WAF | Cloudflare | Cloudflare |
2. EC2 Infrastructure
Both Staging and Production EC2 instances run Ubuntu 22.04 LTS with Nginx as a reverse proxy.
2.1 Process Management (systemd)
All 19 services are managed by systemd unit files located in /etc/systemd/system/.
| Service | Unit Name | Port | Language |
|---|---|---|---|
| API Gateway | pakashop-gateway.service | 8000 | Node.js |
| Backend API | pakashop-backend.service | 3080 | Node.js |
| Config | pakashop-config.service | 3085 | Node.js |
| Notifications | pakashop-notifications.service | 3090 | Node.js |
| Tracking | pakashop-tracking.service | 3120 | Node.js |
| Scheduler | pakashop-scheduler.service | 3004 | Node.js |
| Fraud | pakashop-fraud.service | 3006 | Node.js |
| Coupon | pakashop-coupon.service | 3008 | Node.js |
| Loyalty | pakashop-loyalty.service | 3010 | Node.js |
pakashop-whatsapp.service | 3009 | Node.js | |
| Reports | pakashop-reports.service | 3011 | Node.js |
| Reconciliation | pakashop-reconciliation.service | 3012 | Node.js |
| Invoicing | pakashop-invoicing.service | 3013 | Node.js |
| Pricing | pakashop-pricing.service | 3014 | Node.js |
| Settlement | pakashop-settlement.service | 3016 | Node.js |
| Search | pakashop-search.service | 3005 | Go |
| Analytics | pakashop-analytics.service | 3007 | Go |
| Moderation | pakashop-moderation.service | 3110 | Python |
| Recommendations | pakashop-recommendations.service | 3100 | Python |
2.2 Example systemd Unit File
# /etc/systemd/system/pakashop-backend.service
[Unit]
Description=Pakashop Backend API
After=network.target postgresql.service redis.service
Wants=postgresql.service redis.service
[Service]
Type=simple
User=deploy
Group=deploy
WorkingDirectory=/opt/pakashop/services/backend
Environment=NODE_ENV=production
EnvironmentFile=/opt/pakashop/.env.production
ExecStart=/usr/bin/node src/index.js
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=pakashop-backend
# Resource limits
LimitNOFILE=65536
# Security hardening (commented out until tested)
# NoNewPrivileges=true
# ProtectSystem=strict
# ProtectHome=true
# ReadWritePaths=/opt/pakashop/services/backend/tmp
[Install]
WantedBy=multi-user.target
2.3 Nginx Configuration
# /etc/nginx/sites-available/pakashop
upstream gateway {
server 127.0.0.1:8000;
}
server {
listen 443 ssl http2;
server_name pakashop.store www.pakashop.store;
ssl_certificate /etc/ssl/certs/pakashop.crt;
ssl_certificate_key /etc/ssl/private/pakashop.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers on;
# WebSocket support for tracking
location /api/v1/tracking/ws {
proxy_pass http://gateway;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
proxy_read_timeout 86400;
}
# SSE support for notifications
location /api/v1/notifications/stream {
proxy_pass http://gateway;
proxy_http_version 1.1;
proxy_set_header Connection '';
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 86400;
}
# All other API requests
location /api/ {
proxy_pass http://gateway;
proxy_http_version 1.1;
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;
proxy_set_header X-Internal-Key $http_x_internal_key;
# Rate limiting
limit_req zone=api burst=100 nodelay;
limit_req_status 429;
}
# Static assets (if served from EC2)
location /static/ {
alias /opt/pakashop/frontend/public/;
expires 1y;
add_header Cache-Control "public, immutable";
}
# Health check endpoint (bypass auth)
location /health {
proxy_pass http://gateway;
access_log off;
}
}
# Redirect HTTP to HTTPS
server {
listen 80;
server_name pakashop.store www.pakashop.store;
return 301 https://$server_name$request_uri;
}
3. Deployment and Branch Mapping
- Staging: Deployed automatically when code is pushed to the
mainbranch. - Production: Deployed automatically when code is pushed to the
productionbranch.
All deployments use the centralized scripts/deploy.sh script, which is branch-aware and pulls the latest code from the branch currently checked out on the host.
4. Environment Files
4.1 Production Environment (/opt/pakashop/.env.production)
# Database
DATABASE_URL=postgresql://user:pass@pakashop-prod.cluster-xxx.us-east-1.rds.amazonaws.com:5432/pakashop
DIRECT_DATABASE_URL=postgresql://user:pass@localhost:5432/pakashop
# Redis
REDIS_URL=redis://localhost:6379
# Meilisearch
MEILISEARCH_URL=http://localhost:7700
MEILISEARCH_API_KEY=master_key
# JWT
JWT_SECRET=xxx
TOTP_ENCRYPTION_KEY=xxx
# Gateway keys
PAKASHOP_CLIENT_KEY=xxx
INTERNAL_API_KEY=xxx
# Payment providers
PAYMENT_PROVIDER=AUTO
PAWAPAY_API_KEY=xxx
PAWAPAY_BASE_URL=https://api.pawapay.io
PAWAPAY_WEBHOOK_SECRET=xxx
FLUTTERWAVE_SECRET_KEY=FLWSECK-xxx
FLUTTERWAVE_SECRET_HASH=xxx
FLUTTERWAVE_BASE_URL=https://api.flutterwave.com/v3
FLUTTERWAVE_REDIRECT_URL=https://pakashop.store/payment/callback
# Email
RESEND_API_KEY=xxx
ZOHO_MAIL_PASSWORD=xxx
# Cloudinary
CLOUDINARY_CLOUD_NAME=xxx
CLOUDINARY_API_KEY=xxx
CLOUDINARY_API_SECRET=xxx
# Content moderation
SIGHTENGINE_API_USER=xxx
SIGHTENGINE_API_SECRET=xxx
# WhatsApp
WHATSAPP_BUSINESS_ID=xxx
TWILIO_ACCOUNT_SID=xxx
TWILIO_AUTH_TOKEN=xxx
# ZRA
ZRA_VSDC_API_KEY=xxx
ZRA_MOCK_MODE=false
# Observability
MIDDLEWARE_API_KEY=xxx
ENABLE_OBSERVABILITY=true
# Feature flags
FEATURE_FLAGS_REDIS_KEY=pakashop:feature_flags
4.2 Deployment User
The deploy user on EC2 has limited privileges:
# /etc/sudoers.d/deploy
deploy ALL=(ALL) NOPASSWD: /bin/systemctl restart pakashop-*
deploy ALL=(ALL) NOPASSWD: /bin/systemctl reload nginx
deploy ALL=(ALL) NOPASSWD: /opt/pakashop/scripts/deploy.sh
5. Security Hardening
5.1 EC2 Security Groups
| Port | Protocol | Source | Purpose |
|---|---|---|---|
| 22 | TCP | Office IP only | SSH access |
| 80 | TCP | 0.0.0.0/0 | HTTP redirect |
| 443 | TCP | 0.0.0.0/0 | HTTPS traffic |
| 6379 | TCP | VPC only | Redis (no external access) |
| 5432 | TCP | VPC only | PostgreSQL (no external access) |
| 7700 | TCP | VPC only | Meilisearch (no external access) |
5.2 Cloudflare Configuration
- SSL/TLS: Full (strict) — encrypts traffic between Cloudflare and origin
- WAF: OWASP Top 10 rules enabled
- DDoS Protection: Always on
- Bot Management: Challenge suspicious traffic
- Page Rules: Cache static assets, bypass cache for API
5.3 systemd Sandboxing (Optional)
For enhanced security, uncomment the following in each systemd unit file:
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/pakashop/services/<service>/tmp
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictRealtime=true
RestrictSUIDSGID=true
Note: Test thoroughly before enabling in production. Some services may require additional ReadWritePaths for temporary file storage.
6. Maintenance and Monitoring
- Logs: All environments ship logs to
journald. Live logs can be viewed withjournalctl -u <unit> -f. - Health Checks: Middleware.io monitors both Staging and Production stacks with separate environment tags.
- Status Dashboard: Use
./scripts/pakashop-status.shon either host to see a color-coded status of all local services. - Backups: Nightly automated database backups to S3 via GitHub Actions (
db-backup.yml).
For internal use only. Do not distribute outside Pakashop engineering.