A comprehensive demonstration of production-ready cloud deployment patterns for modern web applications. This project showcases enterprise-grade deployment strategies including multi-cloud deployment, container orchestration, infrastructure as code, security best practices, monitoring, and CI/CD workflows.
graph TD
A[Internet] -->|HTTPS| B(Railway Load Balancer)
B --> C[Nginx Reverse Proxy]
C --> D[Node.js App :3001]
D --> E[(PostgreSQL)]
D --> F[(Redis Cache)]
D --> G[Jaeger Tracing]
style B fill:#f9f,stroke:#333,stroke-width:2px
style D fill:#bbf,stroke:#333,stroke-width:2px
| Component | Implementation | Industry Value | | :— | :— | :— | | High Availability | Horizontal Scaling + Auto-healing | Minimizes digital service downtime | | Security Architecture | Zero-Trust & Nginx Hardening | Protects sensitive data against cyber threats | | Observability | Jaeger Distributed Tracing | Rapid incident response and performance optimization | | Automation | Full CI/CD via GitHub Actions | Accelerates software delivery lifecycle (SDLC) |
# Connect your GitHub repository
git clone https://github.com/PkLavc/cloud-deployment-showcase.git
cd cloud-deployment-showcase
railway login
railway init
# Add PostgreSQL
railway add postgresql
# Add Redis
railway add redis
# Add Jaeger (optional, for tracing)
railway add jaeger
Set the following environment variables in Railway dashboard:
# Database (auto-provided by Railway)
DATABASE_URL=$
# Redis (auto-provided by Railway)
REDIS_URL=$
# Webhook Secrets (generate secure random strings)
STRIPE_WEBHOOK_SECRET=whsec_your_secure_stripe_secret
PAYPAL_WEBHOOK_SECRET=your_secure_paypal_secret
GITHUB_WEBHOOK_SECRET=your_secure_github_secret
# OpenTelemetry
OTEL_SERVICE_NAME=event-driven-integration-service
JAEGER_ENDPOINT=$
# Application
NODE_ENV=production
PORT=3001
# Run migrations on Railway
railway run npm run prisma:migrate
# Generate Prisma client
railway run npm run prisma:generate
# Deploy to Railway
railway up
Railway will automatically build and deploy using the provided Dockerfile.
# Build stage
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# Production stage
FROM node:18-alpine AS production
WORKDIR /app
# Install dumb-init for proper signal handling
RUN apk add --no-cache dumb-init
# Copy built application
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/prisma ./prisma
# Create logs directory
RUN mkdir -p logs
# Switch to non-root user
USER node
EXPOSE 3001
# Use dumb-init to handle signals properly
ENTRYPOINT ["dumb-init", "--"]
CMD ["npm", "run", "start:prod"]
events {
worker_connections 1024;
}
http {
upstream app_backend {
server app:3001;
}
server {
listen 80;
server_name your-domain.com;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
# Health check endpoint
location /health {
proxy_pass http://app_backend;
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;
}
# API endpoints
location / {
proxy_pass http://app_backend;
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;
# Timeout settings
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# Logs
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
}
}
[build]
builder = "dockerfile"
[deploy]
healthcheckPath = "/health"
healthcheckTimeout = 300
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 10
https://your-app.railway.app/health# View application logs
railway logs
# View specific service logs
railway logs --service postgresql
name: Deploy to Railway
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- run: npm ci
- run: npm run build
- run: npm run test
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy to Railway
uses: railwayapp/railway-deploy@v1
with:
railway-token: $
Total Monthly Cost: ~$13/month
Database Connection Failed
# Check Railway variables
railway variables
# Test connection
railway run npm run prisma:studio
Webhook Signature Invalid
Health Check Failing
# Check logs
railway logs
# Manual health check
curl https://your-app.railway.app/health
Pros: More control, familiar AWS ecosystem Cons: More complex setup, higher maintenance
Pros: Simple deployment, managed services Cons: Limited customization, vendor lock-in
Pros: Developer-friendly, automatic scaling, integrated services Cons: Less control than self-managed infrastructure
This deployment showcases:
Patrick - Computer Engineer To view other projects and portfolio details, visit: https://pklavc.github.io/projects.html
This showcase demonstrates practical cloud deployment skills for production applications.