Tutorial  ·  June 2026

Deploy a Self-Hosted Screenshot API on Render

What you'll have: Openkova running on Render as a Docker Web Service with persistent storage, automatic HTTPS, and a .onrender.com subdomain — set up entirely from the Render dashboard, no CLI required.

Prerequisites

Option A: Deploy from the Render dashboard

Step 1: Create a new Web Service

In the Render dashboard, click New → Web Service. On the source selection screen, choose Deploy an existing image from a registry and enter:

ghcr.io/scnix-git/openkova:latest

Step 2: Configure the service

On the configuration screen, set:

Step 3: Set environment variables

Scroll to the Environment Variables section and add:

CHROMIUM_PATH    /usr/bin/chromium
OPENKOVA_STORAGE_PATH    /data
PORT    3000

Step 4: Add a persistent disk

Scroll to the Disks section and click Add Disk:

Render disks cost $0.25/GB/month. 1 GB = $0.25/mo on top of the Web Service cost.

Step 5: Deploy

Click Create Web Service. Render pulls the Docker image, attaches the disk, and starts the service. The first deploy takes 2–4 minutes. Once the health check passes, your service is live at https://openkova.onrender.com (or your custom subdomain).

# Test your deployment
curl -X POST https://openkova.onrender.com/api/convert/snippet \
  -H "Content-Type: application/json" \
  -d '{"html":"<h1 style=\"font-family:sans-serif;padding:40px\">Hello Render</h1>","format":"png"}' \
  --output test.png

Option B: Deploy with render.yaml (Infrastructure as Code)

Fork the Openkova repository and add a render.yaml to the root. Render detects this file and configures the service on the first deploy:

# render.yaml
services:
  - type: web
    name: openkova
    runtime: docker
    dockerfilePath: ./Dockerfile
    plan: starter
    healthCheckPath: /
    envVars:
      - key: CHROMIUM_PATH
        value: /usr/bin/chromium
      - key: OPENKOVA_STORAGE_PATH
        value: /data
      - key: PORT
        value: 3000
    disk:
      name: openkova-data
      mountPath: /data
      sizeGB: 1

Connect your GitHub fork to a new Render Web Service — Render reads the render.yaml automatically and pre-fills the configuration. Push to your default branch to trigger redeployments.

Add a custom domain

In your service settings, open the Custom Domains tab. Enter your domain and Render shows the DNS records to add:

# For a subdomain (recommended)
CNAME   api.yourdomain.com   openkova.onrender.com

# For a root domain, Render provides an A record

Render provisions the SSL certificate automatically once DNS propagates.

Plan comparison for a screenshot API

Render planRAMAlways on?PriceSuitable?
Free512 MB✗ Spins down$0✗ Cold-start timeouts
Starter512 MB$7/mo✓ Recommended minimum
Standard2 GB$25/mo✓ High concurrency
Pro4 GB$85/mo✓ Production workloads

The free tier is not suitable for a screenshot API. After 15 minutes without a request, Render suspends the container — the next request triggers a cold start that takes 10–30 seconds, long enough to timeout most HTTP clients waiting for a screenshot.

Monitoring and logs

Render streams logs in real time from the dashboard under the Logs tab of your service. Filter by log type (app, deploy, error) and download log archives for debugging.

For uptime monitoring, enable Render's built-in health check by setting the health check path to / — Openkova returns a 200 response at the root.

Environment variable reference

VariableValueRequired
CHROMIUM_PATH/usr/bin/chromiumYes
OPENKOVA_STORAGE_PATH/dataYes (with disk)
PORT3000Yes
NEXT_PUBLIC_SITE_URLYour .onrender.com URL or custom domainNo

Frequently asked questions

Can I deploy a screenshot API on Render?

Yes. Create a Docker-based Web Service using ghcr.io/scnix-git/openkova:latest, set CHROMIUM_PATH=/usr/bin/chromium, and add a persistent disk at /data. Use the Starter plan or above — the free tier spins down and causes cold-start timeouts.

Why can't I use the Render free tier for a screenshot API?

Render's free tier suspends services after 15 minutes without requests. The next request triggers a cold start of 10–30 seconds — most HTTP clients timeout before the screenshot is returned. The Starter plan ($7/mo) keeps the service always on.

How do I persist screenshots on Render?

Add a Render Disk in your service settings with mount path /data. Set OPENKOVA_STORAGE_PATH=/data. Render disks persist across restarts and redeployments at $0.25/GB/month.

Can I use render.yaml to configure Openkova?

Yes. Add a render.yaml to your repository with the Docker image, environment variables, and disk configuration. Render reads it on the first deploy and pre-fills the Web Service settings.

More deployment options

Prefer a different platform? Openkova runs anywhere Docker runs.

Deploy on Railway →Deploy on Fly.io →Docker Compose guide →