Skip to main content
The Blackjack API is fully containerized and can be deployed to various cloud platforms. This guide covers deployment to Render and other cloud providers.

Live Demo

The application is deployed on Render:

Deployment to Render

Render is a cloud platform that provides automatic deployments from Docker images.

Prerequisites

  1. GitHub account with repository access
  2. Render account (https://render.com)
  3. Docker image pushed to Docker Hub or GitHub Container Registry

Setup Steps

1. Create MongoDB Database

  1. In Render Dashboard, click NewMongoDB
  2. Configure:
    • Name: blackjack-mongo
    • Region: Choose closest to your users
    • Plan: Free or Starter
  3. Click Create Database
  4. Copy the Internal Connection String (looks like mongodb://...)

2. Create MySQL Database

  1. Click NewPostgreSQL (or use external MySQL provider like PlanetScale)
  2. For MySQL specifically, consider:
  3. Copy the connection details

3. Create Web Service

  1. Click NewWeb Service
  2. Connect your GitHub repository or use Docker image
  3. Configure:
    • Name: blackjack-api
    • Environment: Docker
    • Region: Same as databases
    • Instance Type: Free or Starter
    • Docker Image: ccasr/blackjack-api:latest

4. Configure Environment Variables

Set the following environment variables in Render:
# Spring Profile
SPRING_PROFILES_ACTIVE=prod

# MongoDB Configuration
SPRING_DATA_MONGODB_URI=mongodb://...

# MySQL Configuration (R2DBC)
SPRING_R2DBC_URL=r2dbc:mysql://host:port/database
SPRING_R2DBC_USERNAME=your_username
SPRING_R2DBC_PASSWORD=your_password

# Flyway Configuration (JDBC)
SPRING_FLYWAY_ENABLED=true
SPRING_FLYWAY_URL=jdbc:mysql://host:port/database
SPRING_FLYWAY_USER=your_username
SPRING_FLYWAY_PASSWORD=your_password

# Server Configuration
PORT=8080

5. Deploy

  1. Click Create Web Service
  2. Render will automatically:
    • Pull the Docker image
    • Run database migrations (Flyway)
    • Start the application
    • Generate a public URL

Production Configuration

The application uses application-prod.yml for production deployments:
spring:
  data:
    mongodb:
      uri: ${SPRING_DATA_MONGODB_URI}

  r2dbc:
    url: ${SPRING_R2DBC_URL}
    username: ${SPRING_R2DBC_USERNAME}
    password: ${SPRING_R2DBC_PASSWORD}

  flyway:
    enabled: ${SPRING_FLYWAY_ENABLED:true}
    url: ${SPRING_FLYWAY_URL}
    user: ${SPRING_FLYWAY_USER}
    password: ${SPRING_FLYWAY_PASSWORD}
    locations: classpath:db/migration

server:
  port: ${PORT:8080}
All sensitive values are loaded from environment variables.

Deployment to AWS

AWS Elastic Container Service (ECS)

1. Push Image to ECR

# Authenticate with ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <account-id>.dkr.ecr.us-east-1.amazonaws.com

# Tag image
docker tag blackjack-api:latest <account-id>.dkr.ecr.us-east-1.amazonaws.com/blackjack-api:latest

# Push image
docker push <account-id>.dkr.ecr.us-east-1.amazonaws.com/blackjack-api:latest

2. Create Task Definition

Create task-definition.json:
{
  "family": "blackjack-api",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "512",
  "memory": "1024",
  "containerDefinitions": [
    {
      "name": "blackjack-api",
      "image": "<account-id>.dkr.ecr.us-east-1.amazonaws.com/blackjack-api:latest",
      "portMappings": [
        {
          "containerPort": 8080,
          "protocol": "tcp"
        }
      ],
      "environment": [
        {
          "name": "SPRING_PROFILES_ACTIVE",
          "value": "prod"
        }
      ],
      "secrets": [
        {
          "name": "SPRING_DATA_MONGODB_URI",
          "valueFrom": "arn:aws:secretsmanager:region:account-id:secret:mongodb-uri"
        },
        {
          "name": "SPRING_R2DBC_PASSWORD",
          "valueFrom": "arn:aws:secretsmanager:region:account-id:secret:mysql-password"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/blackjack-api",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "ecs"
        }
      }
    }
  ]
}

3. Create Services

# Create ECS cluster
aws ecs create-cluster --cluster-name blackjack-cluster

# Register task definition
aws ecs register-task-definition --cli-input-json file://task-definition.json

# Create service
aws ecs create-service \
  --cluster blackjack-cluster \
  --service-name blackjack-api \
  --task-definition blackjack-api \
  --desired-count 2 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[subnet-xxx],securityGroups=[sg-xxx],assignPublicIp=ENABLED}"

AWS Databases

MongoDB Atlas

Use MongoDB Atlas for managed MongoDB:
  1. Create cluster at https://cloud.mongodb.com
  2. Whitelist AWS IP ranges
  3. Get connection string
  4. Set SPRING_DATA_MONGODB_URI environment variable

Amazon RDS for MySQL

aws rds create-db-instance \
  --db-instance-identifier blackjack-mysql \
  --db-instance-class db.t3.micro \
  --engine mysql \
  --master-username admin \
  --master-user-password <password> \
  --allocated-storage 20

Deployment to Google Cloud Platform (GCP)

Cloud Run

# Push to Google Container Registry
docker tag blackjack-api:latest gcr.io/<project-id>/blackjack-api:latest
docker push gcr.io/<project-id>/blackjack-api:latest

# Deploy to Cloud Run
gcloud run deploy blackjack-api \
  --image gcr.io/<project-id>/blackjack-api:latest \
  --platform managed \
  --region us-central1 \
  --allow-unauthenticated \
  --set-env-vars SPRING_PROFILES_ACTIVE=prod \
  --set-secrets SPRING_DATA_MONGODB_URI=mongodb-uri:latest \
  --set-secrets SPRING_R2DBC_PASSWORD=mysql-password:latest

Deployment to Heroku

Using Container Registry

# Login to Heroku Container Registry
heroku container:login

# Tag and push
docker tag blackjack-api:latest registry.heroku.com/<app-name>/web
docker push registry.heroku.com/<app-name>/web

# Release
heroku container:release web -a <app-name>

# Set environment variables
heroku config:set SPRING_PROFILES_ACTIVE=prod -a <app-name>
heroku config:set SPRING_DATA_MONGODB_URI=<uri> -a <app-name>

Environment Variables Reference

Required Variables

VariableDescriptionExample
SPRING_PROFILES_ACTIVESpring profile to useprod
SPRING_DATA_MONGODB_URIMongoDB connection stringmongodb://user:pass@host:27017/blackjack
SPRING_R2DBC_URLR2DBC MySQL connection URLr2dbc:mysql://host:3306/blackjack
SPRING_R2DBC_USERNAMEMySQL usernameblackjack
SPRING_R2DBC_PASSWORDMySQL passwordyour-password
SPRING_FLYWAY_URLJDBC URL for Flyway migrationsjdbc:mysql://host:3306/blackjack
SPRING_FLYWAY_USERMySQL user for migrationsblackjack
SPRING_FLYWAY_PASSWORDMySQL password for migrationsyour-password

Optional Variables

VariableDescriptionDefault
PORTServer port8080
SPRING_FLYWAY_ENABLEDEnable database migrationstrue
LOGGING_LEVEL_ROOTLog levelINFO

Database Migration

Flyway automatically runs migrations on application startup.

Migration Files

Migrations are located in src/main/resources/db/migration/:
  • V1__create_player_table.sql
  • V2__add_indexes.sql
  • etc.

Manual Migration

If you need to run migrations manually:
# Using Maven
./mvnw flyway:migrate

# Using Docker
docker run --rm \
  -e SPRING_PROFILES_ACTIVE=prod \
  -e SPRING_FLYWAY_URL=<url> \
  -e SPRING_FLYWAY_USER=<user> \
  -e SPRING_FLYWAY_PASSWORD=<password> \
  ccasr/blackjack-api:latest \
  flyway migrate

Health Checks and Monitoring

Health Check Endpoint

The application exposes Spring Boot Actuator health endpoint:
curl https://your-app.com/actuator/health
Response:
{
  "status": "UP",
  "components": {
    "mongo": { "status": "UP" },
    "r2dbc": { "status": "UP" }
  }
}

Configure Health Checks

Most platforms support automated health checks: Render:
  • Health Check Path: /actuator/health
  • Port: 8080
AWS ECS:
"healthCheck": {
  "command": ["CMD-SHELL", "curl -f http://localhost:8080/actuator/health || exit 1"],
  "interval": 30,
  "timeout": 5,
  "retries": 3,
  "startPeriod": 60
}
Kubernetes:
livenessProbe:
  httpGet:
    path: /actuator/health
    port: 8080
  initialDelaySeconds: 60
  periodSeconds: 10

Security Best Practices

1. Use Secrets Management

Never hardcode credentials. Use platform-specific secret managers:
  • AWS: AWS Secrets Manager or Systems Manager Parameter Store
  • GCP: Secret Manager
  • Render: Environment Variables (encrypted)
  • Heroku: Config Vars

2. Enable HTTPS

Most cloud platforms provide automatic HTTPS:
  • Render: Automatic SSL certificates
  • Heroku: Automatic SSL
  • AWS: Use Application Load Balancer with ACM certificates
  • GCP: Cloud Run provides automatic HTTPS

3. Network Security

  • Keep databases in private networks
  • Use VPC peering or private endpoints
  • Configure security groups/firewall rules
  • Enable database authentication

4. Update Dependencies

Regularly update:
./mvnw versions:display-dependency-updates
./mvnw versions:use-latest-versions

Performance Optimization

1. Connection Pooling

Configure R2DBC connection pool:
spring:
  r2dbc:
    pool:
      initial-size: 10
      max-size: 20
      max-idle-time: 30m

2. JVM Tuning

Set JVM options for containerized environments:
ENTRYPOINT ["java","-XX:+UseContainerSupport","-XX:MaxRAMPercentage=75.0","-jar","/app/app.jar"]

3. Enable Compression

server:
  compression:
    enabled: true
    mime-types: application/json,application/xml,text/html,text/xml,text/plain

Scaling

Horizontal Scaling

The application is stateless and can be scaled horizontally: Render:
  • Dashboard → Service → Scale → Adjust instance count
AWS ECS:
aws ecs update-service \
  --cluster blackjack-cluster \
  --service blackjack-api \
  --desired-count 5
Kubernetes:
kubectl scale deployment blackjack-api --replicas=5

Auto-scaling

Configure auto-scaling based on CPU/memory: AWS ECS Auto Scaling:
aws application-autoscaling register-scalable-target \
  --service-namespace ecs \
  --scalable-dimension ecs:service:DesiredCount \
  --resource-id service/blackjack-cluster/blackjack-api \
  --min-capacity 2 \
  --max-capacity 10

Troubleshooting

Application Won’t Start

  1. Check environment variables are set correctly
  2. Verify database connectivity
  3. Review application logs
  4. Ensure Flyway migrations completed successfully

Database Connection Issues

# Test MongoDB connection
mongosh "${SPRING_DATA_MONGODB_URI}"

# Test MySQL connection
mysql -h host -u user -p database

High Memory Usage

Adjust JVM heap size:
JAVA_OPTS="-Xmx512m -Xms256m"

Continuous Deployment

Set up CI/CD pipelines for automatic deployments:

GitHub Actions Example

name: Deploy to Render

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Build Docker image
        run: docker build -t blackjack-api:latest .
      
      - name: Push to Docker Hub
        run: |
          echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
          docker tag blackjack-api:latest ccasr/blackjack-api:latest
          docker push ccasr/blackjack-api:latest
      
      - name: Deploy to Render
        run: |
          curl -X POST https://api.render.com/deploy/srv-xxx?key=${{ secrets.RENDER_DEPLOY_KEY }}

Cost Optimization

Free Tier Options

  • Render: Free tier for web services (spins down after inactivity)
  • Railway: $5 free credit per month
  • MongoDB Atlas: Free M0 cluster (512MB)
  • PlanetScale: Free tier with 5GB storage

Production Recommendations

  • API: Render Starter ($7/month) or AWS Fargate
  • MongoDB: MongoDB Atlas M10 ($0.08/hour)
  • MySQL: AWS RDS db.t3.small ($0.017/hour)

Next Steps

Build docs developers (and LLMs) love