Back to Blog

Deploying a .NET Core Web API to Convox Cloud

Deploying a .NET Core Web API to Convox Cloud

As a .NET Core developer, you want deployments to be painless. You want to focus on writing code, not wrestling with infrastructure. Convox Cloud delivers exactly that—a fully-managed platform that handles SSL certificates, load balancing, health checks, and zero-downtime deployments automatically, so you can ship features faster.

In this tutorial, we'll deploy a production-ready ASP.NET Core Web API to Convox Cloud in minutes. We'll use the official convox-examples/dotnet-core repository to demonstrate how Convox makes production best practices effortless—from multi-stage Docker builds to automatic scaling.

Why Convox Cloud for .NET Core?

Convox Cloud provides the simplicity of a Platform-as-a-Service with the flexibility developers need. Unlike traditional PaaS offerings that lock you into their way of doing things, Convox uses standard Docker containers and a simple YAML configuration. This means:

  • No vendor lock-in: Your containerized .NET app runs the same way anywhere
  • Instant setup: Create a machine in under a minute, no cloud expertise required
  • Production-ready defaults: Automatic SSL, health checks, and rolling deployments out of the box
  • Predictable pricing: Fixed monthly costs instead of complex cloud billing

Prerequisites and Setup

First, let's get your Convox Cloud environment ready:

1. Create a Convox account at console.convox.com

2. Create your first Machine through the Console Onboarding (X-Small tier includes 250 free hours/month—perfect for development)

3. Install the Convox CLI:

macOS (Intel/AMD):

curl -L https://github.com/convox/convox/releases/latest/download/convox-macos -o /tmp/convox
sudo mv /tmp/convox /usr/local/bin/convox
sudo chmod 755 /usr/local/bin/convox

macOS (Apple Silicon/ARM):

curl -L https://github.com/convox/convox/releases/latest/download/convox-macos-arm64 -o /tmp/convox
sudo mv /tmp/convox /usr/local/bin/convox
sudo chmod 755 /usr/local/bin/convox

Linux (x86_64):

curl -L https://github.com/convox/convox/releases/latest/download/convox-linux -o /tmp/convox
sudo mv /tmp/convox /usr/local/bin/convox
sudo chmod 755 /usr/local/bin/convox

Linux (ARM64):

curl -L https://github.com/convox/convox/releases/latest/download/convox-linux-arm64 -o /tmp/convox
sudo mv /tmp/convox /usr/local/bin/convox
sudo chmod 755 /usr/local/bin/convox

Get your CLI key from the Convox Console:

  • Access the Account page in the top right corner of the Console
  • Or find it in the onboarding flow if you chose CLI deployment setup

Then authenticate by pasting the given command with key into your terminal.

Understanding the Example Application

Let's clone the example .NET Core API:

git clone https://github.com/convox-examples/dotnet-core
cd dotnet-core

This repository demonstrates several production best practices that Convox makes easy:

Multi-Stage Docker Build

The Dockerfile uses a two-stage build process:

  • Build stage: Uses the full .NET SDK to compile the application
  • Runtime stage: Creates a lean production image with just the ASP.NET runtime

This approach keeps your production images small (faster deployments) and secure (fewer attack surfaces).

Environment-Based Configuration

The application follows .NET Core best practices:

  • appsettings.json for default configuration
  • appsettings.Development.json for local development
  • Environment variables for production secrets

Notice how Program.cs reads the PORT environment variable:

var port = Environment.GetEnvironmentVariable("PORT") ?? "5000";
builder.WebHost.UseUrls($"http://+:{port}");

This pattern allows Convox to dynamically assign ports while keeping your code portable.

The convox.yml Configuration

The deployment configuration is refreshingly simple:

services:
  web:
    build: .
    port: 5000
    environment:
      - ASPNETCORE_ENVIRONMENT=Production

That's it! Convox handles the rest—load balancing, SSL certificates, health monitoring, and more.

Deploying to Convox Cloud

Now for the exciting part—let's deploy your API:

# Create the application on your Cloud Machine
convox cloud apps create dotnet-api -i your-machine-name

# Deploy the application
convox cloud deploy -a dotnet-api -i your-machine-name

During deployment, you'll see:

  1. Convox packaging your source code
  2. The multi-stage Docker build executing
  3. Your container image being pushed to the registry
  4. The new release being promoted with zero downtime

Once complete, find your application's URL:

convox cloud services -a dotnet-api -i your-machine-name

You'll see output like:

SERVICE  DOMAIN                                    PORTS
web      web.dotnet-api.cloud.convox.com         443:5000

Testing Your Deployed API

The example includes a HelloController with full CRUD operations. Let's test it:

# Health check endpoint
curl https://web.dotnet-api.cloud.convox.com/
# Returns: "OK"

# Get hello message
curl https://web.dotnet-api.cloud.convox.com/api/hello
# Returns: "Hello from .NET Core Web API!"

# Create a new message
curl -X POST https://web.dotnet-api.cloud.convox.com/api/hello \
  -H "Content-Type: application/json" \
  -d '"Hello Convox!"'

# Get a specific resource
curl https://web.dotnet-api.cloud.convox.com/api/hello/123

Notice that HTTPS works immediately—Convox automatically provisioned an SSL certificate from Let's Encrypt.

Production Features That Just Work

Automatic Health Checks

Convox continuously monitors the / endpoint (returning "OK"). If your application becomes unhealthy, Convox automatically replaces it with a healthy instance. No configuration needed.

Zero-Downtime Deployments

Make a code change and redeploy:

convox cloud deploy -a dotnet-api -i your-machine-name

Convox performs a rolling deployment—starting new containers before stopping old ones. Your API stays available throughout the update.

Environment Variables and Secrets

Configure your application without rebuilding:

convox cloud env set \
  ConnectionStrings__DefaultConnection="Server=db;Database=myapp;..." \
  ApiKey=secret-key-here \
  -a dotnet-api -i your-machine-name

These environment variables are securely stored and injected at runtime.

Scaling Your Application

Scale horizontally with a single command:

convox cloud scale web --count 3 --cpu 512 --memory 1024 -a dotnet-api -i your-machine-name

Or configure auto-scaling in your convox.yml:

services:
  web:
    build: .
    port: 5000
    scale:
      count: 1-5      # Scale between 1 and 5 instances
      cpu: 256
      memory: 512
      targets:
        cpu: 70       # Scale up when CPU exceeds 70%
        memory: 80    # Or when memory exceeds 80%

Extending Your Application

Adding a Database

Convox makes database integration simple. Update your convox.yml:

resources:
  database:
    type: postgres
    options:
      storage: 10
      version: 13

services:
  web:
    build: .
    port: 5000
    resources:
      - database

Convox automatically provisions a PostgreSQL instance and injects the connection URL as DATABASE_URL. In your C# code:

var connectionString = Environment.GetEnvironmentVariable("DATABASE_URL");
// Use with Entity Framework, Dapper, or your preferred ORM

Background Workers

Need background job processing? Add a worker service:

services:
  web:
    build: .
    port: 5000
  
  worker:
    build: .
    command: dotnet YourApp.dll --worker
    scale:
      count: 1
      cpu: 256
      memory: 512

Both services share the same codebase but run different commands. Scale and monitor them independently.

Custom Domains

Ready for production? Add your domain:

1. Get your application's router address:

convox cloud services -a dotnet-api -i your-machine-name

2. Create a CNAME record pointing to the router domain

3. Convox automatically provisions SSL for your custom domain

Monitoring and Debugging

View Application Logs

convox cloud logs -a dotnet-api -i your-machine-name

# Filter logs by service or time
convox cloud logs -s web --since 1h -a dotnet-api -i your-machine-name

Check Process Status

convox cloud ps -a dotnet-api -i your-machine-name

Run One-Off Commands

Need to run migrations or debug in production?

# Run database migrations
convox cloud run web "dotnet ef database update" -a dotnet-api -i your-machine-name

# Open an interactive shell
convox cloud run web bash -a dotnet-api -i your-machine-name

When to Use Convox Cloud vs. Rack

Convox Cloud is perfect for:

  • Quick prototypes and MVPs
  • Development and staging environments
  • Small to medium production workloads
  • Teams wanting zero infrastructure management
  • Predictable monthly pricing

Self-Hosted Rack is ideal when you need:

  • Full control over infrastructure
  • Compliance requirements (HIPAA, PCI)
  • Complex networking (VPC peering, private subnets)
  • Very large workloads
  • Direct access to cloud services (RDS, ElastiCache)

The beautiful part? Your application code and convox.yml work identically on both. Start with Cloud, migrate to Rack when needed—no code changes required.

Best Practices for .NET Core on Convox

  1. Always use multi-stage builds: Keep your images lean for faster deployments
  2. Configure via environment variables: Follow the 12-factor app methodology
  3. Include health endpoints: Let Convox monitor your application effectively
  4. Set resource limits: Prevent runaway processes from affecting other services
  5. Use structured logging: Make debugging easier with JSON-formatted logs
  6. Version your Database migrations: Use Entity Framework migrations or similar tools

Troubleshooting Common Issues

Application Won't Start?

  • Check logs: convox cloud logs -a dotnet-api -i your-machine-name
  • Verify PORT environment variable is being read correctly
  • Ensure your Dockerfile exposes the correct port

Build Failures?

  • Review build logs: convox cloud builds logs BUILD_ID -a dotnet-api -i your-machine-name
  • Verify .NET versions match between Dockerfile and project
  • Check that all required files are included in the Docker context

Performance Issues?

  • Monitor resource usage: convox cloud ps -a dotnet-api -i your-machine-name
  • Scale up if needed: convox cloud scale web --cpu 1000 --memory 2048
  • Consider adding caching layers (Redis) for frequently accessed data

Conclusion

Deploying .NET Core applications doesn't have to be complex. With Convox Cloud, you get enterprise-grade infrastructure in minutes, not weeks. The combination of standard Docker containers, simple YAML configuration, and production-ready defaults means you can focus on what matters—building great applications.

The convox-examples/dotnet-core repository demonstrates that production readiness doesn't require complexity. Multi-stage builds, environment-based configuration, health checks, and auto-scaling—it's all there, ready to use.

Ready to simplify your .NET Core deployments? Sign up for Convox Cloud today and deploy your first application in minutes. Check out our documentation for more advanced features, or reach out to cloud-support@convox.com if you need help.

Happy deploying!


Ready to deploy more applications on Convox? Explore our example repositories for other popular frameworks including Node.js, Rails, Django, Next.js, and PHP. For teams looking to automate workflows, check out our n8n deployment guide. See all examples at docs.convox.com/example-apps.

Let your team focus on what matters.