Deploy a Self-Hosted Screenshot API on Render
.onrender.com subdomain — set up entirely from the Render dashboard, no CLI required.Prerequisites
- A Render account — free to sign up
- A paid Render plan — the Starter tier ($7/mo) is the minimum for a screenshot API. The free tier spins down after 15 minutes of inactivity, causing cold-start delays that timeout screenshot requests.
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:latestStep 2: Configure the service
On the configuration screen, set:
- Name:
openkova(or any name you prefer) - Region: choose the region closest to your application servers
- Instance Type: Starter ($7/mo) minimum — provides 512 MB RAM and keeps the service always on
Step 3: Set environment variables
Scroll to the Environment Variables section and add:
CHROMIUM_PATH /usr/bin/chromium
OPENKOVA_STORAGE_PATH /data
PORT 3000Step 4: Add a persistent disk
Scroll to the Disks section and click Add Disk:
- Name:
openkova-data - Mount Path:
/data - Size: 1 GB (increase later via the dashboard as needed)
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.pngOption 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: 1Connect 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 recordRender provisions the SSL certificate automatically once DNS propagates.
Plan comparison for a screenshot API
| Render plan | RAM | Always on? | Price | Suitable? |
|---|---|---|---|---|
| Free | 512 MB | ✗ Spins down | $0 | ✗ Cold-start timeouts |
| Starter | 512 MB | ✓ | $7/mo | ✓ Recommended minimum |
| Standard | 2 GB | ✓ | $25/mo | ✓ High concurrency |
| Pro | 4 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
| Variable | Value | Required |
|---|---|---|
CHROMIUM_PATH | /usr/bin/chromium | Yes |
OPENKOVA_STORAGE_PATH | /data | Yes (with disk) |
PORT | 3000 | Yes |
NEXT_PUBLIC_SITE_URL | Your .onrender.com URL or custom domain | No |
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.
Prefer a different platform? Openkova runs anywhere Docker runs.