Deployment Guide
This guide covers deployment procedures for HMP across different environments.
Environments
| Environment | Purpose | URL |
|---|---|---|
| Development | Local development | localhost:3000 |
| Staging | Testing & QA | staging.hmpcloud.com |
| Production | Live system | api.hmpcloud.com |
Prerequisites
Infrastructure Requirements
- Kubernetes cluster (1.25+)
- PostgreSQL 14+
- Redis 7+
- S3-compatible storage
- Container registry
Tools Required
- kubectl
- Helm 3+
- Docker
- AWS CLI (or equivalent)
Build Process
Building Docker Images
# Build API image
docker build -t hmp/api:latest -f docker/Dockerfile.api .
# Build services
docker build -t hmp/reservation-service:latest -f docker/Dockerfile.service ./packages/services/reservation
docker build -t hmp/guest-service:latest -f docker/Dockerfile.service ./packages/services/guest
# ... other services
Tagging Images
# Tag with version
docker tag hmp/api:latest hmp/api:v1.2.3
# Tag with commit SHA
docker tag hmp/api:latest hmp/api:$(git rev-parse --short HEAD)
Pushing to Registry
# Login to registry
docker login registry.hmpcloud.com
# Push images
docker push hmp/api:v1.2.3
docker push hmp/reservation-service:v1.2.3
Kubernetes Deployment
Namespace Setup
# k8s/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: hmp-production
labels:
environment: production
Configuration
# k8s/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: hmp-config
namespace: hmp-production
data:
NODE_ENV: production
API_PORT: "3000"
LOG_LEVEL: info
Secrets
# k8s/secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: hmp-secrets
namespace: hmp-production
type: Opaque
data:
DATABASE_URL: <base64-encoded>
REDIS_URL: <base64-encoded>
JWT_SECRET: <base64-encoded>
Deployment
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hmp-api
namespace: hmp-production
spec:
replicas: 3
selector:
matchLabels:
app: hmp-api
template:
metadata:
labels:
app: hmp-api
spec:
containers:
- name: api
image: hmp/api:v1.2.3
ports:
- containerPort: 3000
envFrom:
- configMapRef:
name: hmp-config
- secretRef:
name: hmp-secrets
resources:
requests:
memory: "256Mi"
cpu: "200m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
Service
# k8s/service.yaml
apiVersion: v1
kind: Service
metadata:
name: hmp-api
namespace: hmp-production
spec:
selector:
app: hmp-api
ports:
- port: 80
targetPort: 3000
type: ClusterIP
Ingress
# k8s/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hmp-api
namespace: hmp-production
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- api.hmpcloud.com
secretName: hmp-api-tls
rules:
- host: api.hmpcloud.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hmp-api
port:
number: 80
Helm Deployment
Chart Structure
helm/hmp/
├── Chart.yaml
├── values.yaml
├── values-staging.yaml
├── values-production.yaml
└── templates/
├── deployment.yaml
├── service.yaml
├── ingress.yaml
└── ...
Install/Upgrade
# Install
helm install hmp ./helm/hmp \
--namespace hmp-production \
--values ./helm/hmp/values-production.yaml
# Upgrade
helm upgrade hmp ./helm/hmp \
--namespace hmp-production \
--values ./helm/hmp/values-production.yaml \
--set image.tag=v1.2.3
Database Migrations
Pre-Deployment Migrations
# Run migrations before deploying new version
kubectl run migrations \
--namespace hmp-production \
--image hmp/api:v1.2.3 \
--restart=Never \
--env-from=secret/hmp-secrets \
-- npm run db:migrate
# Verify migration completed
kubectl logs migrations -n hmp-production
Rollback Migrations
# If deployment fails, rollback migrations
kubectl run migration-rollback \
--namespace hmp-production \
--image hmp/api:v1.2.3 \
--restart=Never \
--env-from=secret/hmp-secrets \
-- npm run db:migrate:rollback
CI/CD Pipeline
GitHub Actions
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build and push Docker images
run: |
docker build -t hmp/api:${{ github.sha }} .
docker push hmp/api:${{ github.sha }}
deploy-staging:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy to staging
run: |
helm upgrade hmp ./helm/hmp \
--namespace hmp-staging \
--set image.tag=${{ github.sha }}
deploy-production:
needs: build
runs-on: ubuntu-latest
if: github.event_name == 'release'
steps:
- name: Deploy to production
run: |
helm upgrade hmp ./helm/hmp \
--namespace hmp-production \
--set image.tag=${{ github.event.release.tag_name }}
Rollback Procedures
Kubernetes Rollback
# View deployment history
kubectl rollout history deployment/hmp-api -n hmp-production
# Rollback to previous version
kubectl rollout undo deployment/hmp-api -n hmp-production
# Rollback to specific revision
kubectl rollout undo deployment/hmp-api -n hmp-production --to-revision=5
Helm Rollback
# View release history
helm history hmp -n hmp-production
# Rollback to previous release
helm rollback hmp -n hmp-production
# Rollback to specific revision
helm rollback hmp 5 -n hmp-production
Monitoring
Health Checks
// src/health.ts
app.get('/health', (req, res) => {
res.json({ status: 'healthy', version: process.env.VERSION });
});
app.get('/ready', async (req, res) => {
const dbHealthy = await checkDatabaseConnection();
const redisHealthy = await checkRedisConnection();
if (dbHealthy && redisHealthy) {
res.json({ status: 'ready' });
} else {
res.status(503).json({ status: 'not ready' });
}
});
Metrics
Prometheus metrics exposed at /metrics:
hmp_http_requests_total{method="GET", path="/reservations", status="200"} 1234
hmp_http_request_duration_seconds{method="GET", path="/reservations"} 0.045
hmp_database_connections_active 10
hmp_database_connections_idle 5
Logging
Structured JSON logs:
{
"level": "info",
"message": "Request completed",
"timestamp": "2026-01-22T10:30:00Z",
"requestId": "req_abc123",
"method": "POST",
"path": "/api/v1/reservations",
"status": 201,
"duration": 150
}
Security Checklist
Pre-deployment security verification:
- All secrets in secret manager
- No hardcoded credentials
- TLS certificates valid
- Network policies configured
- RBAC properly configured
- Container runs as non-root
- Resource limits set
- Security scanning passed