Store Deployment & Operations
This guide covers deployment procedures, monitoring, and operational tasks for the OpticWorks Store.
Infrastructure Overview
Section titled “Infrastructure Overview”┌─────────────────────────────────────────────────────────────────┐│ Production Infrastructure ││ ││ ┌───────────────────────────────────────────────────────────┐ ││ │ Cloudflare │ ││ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ ││ │ │ Workers │ │ Images │ │ R2 Storage │ │ ││ │ │ (Storefront)│ │ (Assets) │ │ (Backups) │ │ ││ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ ││ └───────────────────────────────────────────────────────────┘ ││ │ ││ ▼ ││ ┌───────────────────────────────────────────────────────────┐ ││ │ Hetzner Cloud │ ││ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ ││ │ │ Medusa │ │ PostgreSQL │ │ Redis │ │ ││ │ │ API │ │ 17 │ │ 7 │ │ ││ │ │ (2 vCPU) │ │ (4 vCPU) │ │ (2 vCPU) │ │ ││ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ ││ └───────────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────┘Deployment Procedures
Section titled “Deployment Procedures”Storefront Deployment
Section titled “Storefront Deployment”The storefront deploys automatically on push to main:
name: Deploy Storefront
on: push: branches: [main] paths: - 'apps/storefront/**'
jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Setup Node uses: actions/setup-node@v4 with: node-version: 20
- name: Install dependencies run: pnpm install --frozen-lockfile
- name: Build run: pnpm build:frontend env: NEXT_PUBLIC_MEDUSA_BACKEND_URL: ${{ secrets.MEDUSA_URL }}
- name: Deploy to Cloudflare uses: cloudflare/wrangler-action@v3 with: apiToken: ${{ secrets.CF_API_TOKEN }} workingDirectory: apps/storefrontBackend Deployment
Section titled “Backend Deployment”Backend deployments use Ansible:
# Deploy to stagingcd infra/ansibleansible-playbook deploy.yml -i inventory/staging.yml
# Deploy to productionansible-playbook deploy.yml -i inventory/production.yml --ask-vault-passDeployment Playbook:
- hosts: medusa become: yes vars: app_dir: /opt/medusa
tasks: - name: Pull latest code git: repo: 'https://github.com/r-mccarty/opticworks-store.git' dest: '{{ app_dir }}' version: 'main'
- name: Install dependencies command: pnpm install --frozen-lockfile args: chdir: '{{ app_dir }}/packages/medusa-backend'
- name: Run migrations command: pnpm medusa migrations run args: chdir: '{{ app_dir }}/packages/medusa-backend'
- name: Build command: pnpm build args: chdir: '{{ app_dir }}/packages/medusa-backend'
- name: Restart service systemd: name: medusa state: restartedEnvironment Configuration
Section titled “Environment Configuration”Staging
Section titled “Staging”| Component | Value |
|---|---|
| Storefront | staging.optic.works |
| API | api-staging.optic.works |
| Database | medusa-staging |
| Stripe | Test mode |
Production
Section titled “Production”| Component | Value |
|---|---|
| Storefront | optic.works |
| API | api.optic.works |
| Database | medusa-production |
| Stripe | Live mode |
Monitoring
Section titled “Monitoring”Health Checks
Section titled “Health Checks”# API health checkcurl https://api.optic.works/health
# Expected response:{ "status": "ok", "database": "connected", "redis": "connected"}Metrics Dashboard
Section titled “Metrics Dashboard”Access Grafana at: https://metrics.optic.works
Key Dashboards:
- API Performance
- Database Metrics
- Order Funnel
- Error Rates
Alerts
Section titled “Alerts”| Alert | Threshold | Action |
|---|---|---|
| API Error Rate | >1% | Page on-call |
| Response Time | >2s (p95) | Investigate |
| Database Connections | >80% | Scale up |
| Disk Usage | >80% | Clean up / expand |
| Payment Failures | >5% | Investigate immediately |
Database Operations
Section titled “Database Operations”Backups
Section titled “Backups”Automated daily backups to Cloudflare R2:
# Manual backupssh medusa-prod 'pg_dump -Fc medusa > /tmp/backup.dump'scp medusa-prod:/tmp/backup.dump ./backups/
# List backupsaws s3 ls s3://opticworks-backups/medusa/ --endpoint-url https://xxx.r2.cloudflarestorage.comRestore from Backup
Section titled “Restore from Backup”# Download backupaws s3 cp s3://opticworks-backups/medusa/2024-01-15.dump ./backup.dump \ --endpoint-url https://xxx.r2.cloudflarestorage.com
# Restore (CAUTION: destructive)ssh medusa-prod 'pg_restore -d medusa -c backup.dump'Migrations
Section titled “Migrations”# Check migration statusssh medusa-prod 'cd /opt/medusa && pnpm medusa migrations show'
# Run pending migrationsssh medusa-prod 'cd /opt/medusa && pnpm medusa migrations run'
# Rollback (if needed)ssh medusa-prod 'cd /opt/medusa && pnpm medusa migrations revert'Incident Response
Section titled “Incident Response”Severity Levels
Section titled “Severity Levels”| Level | Description | Response Time |
|---|---|---|
| SEV1 | Site down, payments failing | Immediate |
| SEV2 | Major feature broken | 1 hour |
| SEV3 | Minor issue, workaround exists | 4 hours |
| SEV4 | Cosmetic / low impact | Next business day |
SEV1 Runbook
Section titled “SEV1 Runbook”- Acknowledge - Respond in #incidents Slack channel
- Assess - Check monitoring dashboards
- Communicate - Update status page
- Mitigate - Apply quick fix or rollback
- Resolve - Permanent fix
- Post-mortem - Document and learn
Common Issues
Section titled “Common Issues”Payments Failing
Section titled “Payments Failing”- Check Stripe dashboard for errors
- Verify webhook secret is correct
- Check Hookdeck for failed deliveries
- Review Medusa logs:
journalctl -u medusa -f
Slow Response Times
Section titled “Slow Response Times”- Check database connections:
SELECT count(*) FROM pg_stat_activity - Check Redis memory:
redis-cli INFO memory - Review slow query log
- Check for background job backlog
500 Errors
Section titled “500 Errors”- Check Medusa logs:
journalctl -u medusa -f - Check recent deployments
- Verify environment variables
- Check database connectivity
Common Operations
Section titled “Common Operations”Add New Product
Section titled “Add New Product”- Log into Admin: https://api.optic.works/admin
- Navigate to Products → Add Product
- Fill in details, add images
- Set pricing and inventory
- Publish
Process Refund
Section titled “Process Refund”- Find order in Admin
- Click “Refund” button
- Select items and amount
- Add internal note
- Confirm refund
Generate Shipping Label
Section titled “Generate Shipping Label”- Find order in Admin
- Click “Create Fulfillment”
- Select shipping rate
- Buy label
- Print label
Update Inventory
Section titled “Update Inventory”# Via Admin UI# Products → [Product] → Variants → Edit Inventory
# Via APIcurl -X POST https://api.optic.works/admin/inventory-items/inv_123 \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"quantity": 100}'Scaling
Section titled “Scaling”Horizontal Scaling
Section titled “Horizontal Scaling”# Add more Medusa instancesansible-playbook scale.yml -e "medusa_instances=3"
# Update load balanceransible-playbook update-lb.ymlDatabase Scaling
Section titled “Database Scaling”For high load:
- Enable read replicas
- Configure connection pooling (PgBouncer)
- Add more memory to primary
Cache Optimization
Section titled “Cache Optimization”# Clear Redis cacheredis-cli -h redis.optic.works FLUSHDB
# Check cache hit rateredis-cli -h redis.optic.works INFO stats | grep keyspaceMaintenance Windows
Section titled “Maintenance Windows”Scheduled Maintenance
Section titled “Scheduled Maintenance”- Post notice on status page (24h advance)
- Enable maintenance mode:
Terminal window ssh storefront 'echo "maintenance" > /opt/storefront/.maintenance' - Perform maintenance
- Disable maintenance mode:
Terminal window ssh storefront 'rm /opt/storefront/.maintenance' - Update status page
Zero-Downtime Deploys
Section titled “Zero-Downtime Deploys”- Deploy to canary instance first
- Run health checks
- Gradually shift traffic (10% → 50% → 100%)
- Monitor error rates
- Rollback if issues detected
Access Management
Section titled “Access Management”SSH Access
Section titled “SSH Access”# Add to ~/.ssh/configHost medusa-prod HostName 1.2.3.4 User deploy IdentityFile ~/.ssh/opticworks
# Connectssh medusa-prodAdmin Access
Section titled “Admin Access”Request via IT ticket. Access levels:
- Viewer: Can view orders and products
- Editor: Can modify products and fulfill orders
- Admin: Full access including settings
Contacts
Section titled “Contacts”| Role | Contact | Escalation |
|---|---|---|
| On-Call Engineer | PagerDuty | Automatic |
| Engineering Lead | @ryan | For SEV1/2 |
| Product | @product | Order issues |
| Finance | @finance | Payment issues |