Skip to content
intermediate Phase 16 · DevOps & Deployment

Cloud Deployment

Deploy to Vercel, Netlify, AWS, or Railway with environment variables, domains, and SSL.

1h
0 problems
Topic Progress 0%

Vercel and Netlify for Frontend Deployment

Vercel and Netlify for Frontend Deployment

Vercel Project Setup

Vercel provides zero-config deployment for frontend frameworks like Next.js, Astro, and React. When you connect your GitHub repository, Vercel automatically detects the framework and configures build settings.

// vercel.json
{
  "buildCommand": "npm run build",
  "outputDirectory": "dist",
  "framework": "astro",
  "rewrites": [
    { "source": "/api/:path*", "destination": "/api" }
  ],
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        { "key": "X-Content-Type-Options", "value": "nosniff" },
        { "key": "X-Frame-Options", "value": "DENY" }
      ]
    }
  ]
}

Environment Variables on Vercel

# Set via CLI
vercel env add DATABASE_URL production
vercel env add JWT_SECRET production
vercel env add API_KEY preview  # Different value for preview deployments

# List all environment variables
vercel env ls

# Pull remote env vars to local .env.local
vercel env pull .env.local

Environment variables can be scoped to Production, Preview, or Development environments. This allows you to use different API endpoints or database URLs for each environment.

Netlify Configuration

Netlify offers similar capabilities with a slightly different configuration approach:

# netlify.toml
[build]
  command = "npm run build"
  publish = "dist"

[build.environment]
  NODE_VERSION = "18"
  NODE_ENV = "production"

[[redirects]]
  from = "/api/*"
  to = "/.netlify/functions/:splat"
  status = 200

[[headers]]
  for = "/*"
  [headers.values]
    X-Frame-Options = "DENY"
    X-Content-Type-Options = "nosniff"
    Referrer-Policy = "strict-origin-when-cross-origin"
# Deploy to Netlify via CLI
netlify deploy --prod --dir=dist

# Set environment variables
netlify env:set DATABASE_URL "postgresql://..."
netlify env:set JWT_SECRET "your-secret-key" --scopes functions

Preview Deployments

Both platforms automatically create preview deployments for pull requests. Every push to a branch generates a unique URL where stakeholders can review changes before merging. This is invaluable for team collaboration and QA testing.

Custom Domains and SSL

# Vercel
cd my-app
vercel domains add myapp.com
vercel domains add www.myapp.com

# Netlify
netlify domains:add myapp.com
netlify domains:add www.myapp.com

Both platforms auto-provision SSL certificates via Let's Encrypt. DNS configuration requires adding CNAME records pointing to the platform's load balancers.

AWS Deployment with ECS and Lambda

AWS Deployment with ECS and Lambda

AWS ECS with Fargate

Elastic Container Service (ECS) with Fargate provides serverless container orchestration. You define task definitions that specify how your application containers should run, and AWS handles the underlying infrastructure.

// ecs-task-definition.json
{
  "family": "myapp",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512",
  "containerDefinitions": [
    {
      "name": "app",
      "image": "123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:latest",
      "portMappings": [{ "containerPort": 3000 }],
      "environment": [
        { "name": "NODE_ENV", "value": "production" }
      ],
      "secrets": [
        { "name": "DATABASE_URL", "valueFrom": "arn:aws:ssm:us-east-1:123456789:parameter/myapp/DATABASE_URL" }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/myapp",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "ecs"
        }
      },
      "healthCheck": {
        "command": ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"],
        "interval": 30,
        "timeout": 5,
        "retries": 3
      }
    }
  ]
}

AWS Lambda for Serverless APIs

// lambda-handler.js
exports.handler = async (event) => {
  const response = {
    statusCode: 200,
    headers: {
      'Content-Type': 'application/json',
      'Access-Control-Allow-Origin': '*'
    },
    body: JSON.stringify({ message: 'Hello from Lambda' })
  };
  return response;
};
# serverless.yml
service: myapi
provider:
  name: aws
  runtime: nodejs18.x
  region: us-east-1
  environment:
    DATABASE_URL: ${ssm:/myapp/DATABASE_URL}
functions:
  api:
    handler: lambda-handler.handler
    events:
      - http:
          path: /{proxy+}
          method: ANY

AWS RDS for Managed PostgreSQL

# terraform/rds.tf
resource "aws_db_instance" "main" {
  identifier     = "myapp-db"
  engine         = "postgres"
  engine_version = "15"
  instance_class = "db.t3.micro"
  allocated_storage = 20

  db_name  = "myapp"
  username = var.db_username
  password = var.db_password

  vpc_security_group_ids = [aws_security_group.db.id]
  db_subnet_group_name   = aws_db_subnet_group.main.name

  backup_retention_period = 7
  multi_az               = true
  storage_encrypted      = true
  deletion_protection     = true
}

AWS S3 + CloudFront for CDN

resource "aws_s3_bucket" "assets" {
  bucket = "myapp-static-assets"
}

resource "aws_cloudfront_distribution" "cdn" {
  origin {
    domain_name = aws_s3_bucket.assets.bucket_regional_domain_name
    origin_id   = "S3-assets"
  }

  enabled             = true
  default_root_object = "index.html"

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "S3-assets"
    viewer_protocol_policy = "redirect-to-https"

    forwarded_values {
      query_string = false
      cookies { forward = "none" }
    }
  }
}

AWS offers more control but requires more configuration. Use ECS for containerized apps, Lambda for serverless functions, and CloudFront for global content delivery.

Railway and Render for Simple PaaS

Railway and Render for Simple PaaS

Railway Deployment

Railway provides an excellent balance between simplicity and power. It supports Docker, Nixpacks (auto-detection), and custom buildpacks. Railway automatically provisions databases, provides environment variable management, and offers built-in monitoring.

// railway.json
{
  "$schema": "https://railway.app/railway.schema.json",
  "build": {
    "builder": "NIXPACKS"
  },
  "deploy": {
    "numReplicas": 2,
    "restartPolicyType": "ON_FAILURE",
    "restartPolicyMaxRetries": 10,
    "startCommand": "node dist/server.js"
  }
}
# nixpacks.toml
[phases.setup]
  nixPkgs = ["postgresql", "ffmpeg"]

[phases.build]
  cmds = ["npm run build"]

[start]
  cmd = "node dist/server.js"
  
[variables]
  NODE_ENV = "production"

Railway's database plugin can be added with one click in the dashboard. It automatically sets the DATABASE_URL environment variable and provides connection pooling.

Render Deployment

Render offers a similar experience with its render.yaml blueprint system. It supports web services, static sites, databases, background workers, and cron jobs.

# render.yaml
services:
  - type: web
    name: myapp
    runtime: node
    plan: starter
    buildCommand: npm install && npm run build
    startCommand: node dist/server.js
    healthCheckPath: /health
    envVars:
      - key: NODE_ENV
        value: production
      - key: DATABASE_URL
        fromDatabase:
          name: myapp-db
          property: connectionString
      - key: JWT_SECRET
        generateValue: true

  - type: database
    name: myapp-db
    runtime: postgres
    plan: starter
    databaseName: myapp
    diskSizeGB: 10

  - type: worker
    name: myapp-worker
    runtime: node
    buildCommand: npm install && npm run build
    startCommand: node dist/worker.js
    envVars:
      - key: DATABASE_URL
        fromDatabase:
          name: myapp-db
          property: connectionString

Comparing PaaS Options

Feature Railway Render Heroku
Free Tier Yes (limited) Yes (limited) No
Database Built-in Postgres/MySQL Built-in Postgres Add-on
Auto-scaling Yes Yes (paid) Yes
Docker Support Yes Yes Yes
Pricing Usage-based Instance-based Dyno-based

Deployment Checklist

  • Environment variables configured for production
  • Database migrations run successfully
  • Health check endpoint responding correctly
  • SSL certificate provisioned and working
  • Custom domain configured with correct DNS records
  • CORS settings allow your frontend domain
  • Logging enabled and accessible
  • Error tracking configured (Sentry, LogRocket)
  • Monitoring alerts set up for downtime
  • Backup strategy in place for database
  • Rollback procedure documented and tested

Quiz

1. What is the primary advantage of using preview deployments in Vercel or Netlify?

Question 1 options

2. When deploying to AWS ECS with Fargate, where should sensitive configuration values like DATABASE_URL be stored?

Question 2 options

3. What does the `numReplicas: 2` setting in railway.json accomplish?

Question 3 options

Flashcards

Question

What is Cloud Deployment?

Answer

Cloud Deployment covers important concepts and best practices.

Question

What is Cloud Deployment?

Answer

Cloud Deployment covers important concepts and best practices.

Question

What is Cloud Deployment?

Answer

Cloud Deployment covers important concepts and best practices.

Revision Notes

Key Takeaways

  • 1. Vercel and Netlify excel at frontend/JAMstack deployments with automatic preview environments and SSL
  • 2. AWS provides maximum flexibility but requires more configuration; use ECS for containers and Lambda for serverless
  • 3. Railway and Render offer the best balance of simplicity and features for full-stack applications
  • 4. Always use environment variables for secrets—never hard-code credentials in source code
  • 5. Set up health check endpoints to enable automatic recovery and monitoring
  • 6. Use managed database services (RDS, Railway Postgres) instead of self-hosting for production

Interview Tips

  • Explain the trade-offs between PaaS (Railway, Render) vs IaaS (AWS ECS) for different project scales
  • Describe how preview deployments improve team collaboration and code quality
  • Discuss strategies for managing environment variables across development, staging, and production
  • Explain the purpose of health checks and how they enable zero-downtime deployments
  • Compare blue-green deployments vs rolling updates for minimizing downtime

Cheat Sheet

Vercel: vercel.json config, vercel env add KEY production, vercel domains add domain.com
Netlify: netlify.toml config, netlify env:set KEY value, netlify deploy --prod
Railway: railway.json config, database URL via DATABASE_URL env var, nixpacks for builds
Render: render.yaml blueprint, envVars with fromDatabase for linked DBs, healthCheckPath
AWS ECS: task definition JSON, Fargate for serverless containers, SSM for secrets
All platforms: Use env vars for secrets, set up health checks, configure custom domains with SSL