Docker hosting — 6 options compared

Once your application is an image, the language stops mattering and a different set of questions takes over: who builds it, which registry it comes from, what architecture it was built for, and what happens to the filesystem when the container is replaced.

Last updated 7 August 2026

Packaging an application as a container image is the point at which hosting becomes a genuinely portable decision. Every platform below takes an image and runs it, so you are no longer choosing a host that supports your language — you are choosing one whose build, registry, networking and storage model fit how you want to work.

That portability is real but not free. The things that break when you move a container between platforms are boringly consistent: an image built on an Apple Silicon laptop that will not start on an amd64 host, a private registry the platform cannot authenticate against, a process that ignores SIGTERM and gets killed mid-request on every deploy, and a volume somebody assumed was persistent. None of them are difficult; all of them are discovered late.

The short version: Fly.io is the cheapest way to keep a small container running, Cloud Run is the best fit when traffic is spiky and the container is stateless, Railway and Render are the smoothest if you want the platform to build the image for you, and Granite — our own platform — fits when you already build images in CI and want a private registry, databases and storage in the same project. If you only need to run one stateless container as cheaply as possible, we are not the cheapest and the table says so.

At a glance

Sorted by entry price. Every provider here can build and run a Docker service; the columns are what separates them.
ProviderFrom /moFree tierManaged DBPersistent diskDeploy from
Fly.io~$2Postgres (unmanaged app)Dockerfile, buildpack
Railway$5yes ($1 credits)Git, Dockerfile, template
Render$7yes (spins down)Git, Dockerfile
Granite$9from AdvancedGit, Docker image
Koyeb$29limitedServerless PostgresGit, Dockerfile
Google Cloud Runusage-basedyes (monthly allowance)via Cloud SQLno (use GCS)Container image

Entry prices as published by each provider on 7 August 2026, sorted cheapest first. Usage, bandwidth and databases are billed on top almost everywhere — treat this column as a starting point, not a monthly bill.

Who builds the image, and does it need to keep anything?

Pick the category before you pick the provider — it decides more than the logo does.

Build on the platform, or build in CI? This is the first real fork, and it matters more than the choice of provider. Letting the platform build from a Dockerfile is fewer moving parts and one less system to maintain. Building in your own CI and pushing a finished image means the artefact you tested is byte-for-byte the one that runs, builds happen on hardware you control, and deploys are a pull rather than a compile. Most teams start with the first and move to the second, so it is worth choosing a platform that supports both.

Serverless containers — Cloud Run, and Koyeb's scale-to-zero — are the most literal expression of the container contract: an image, a port, and nothing else. The constraint is that instances exist only to serve requests. No local state, no background loops, no long-lived connections. Containers designed for a server rarely survive that transition without changes.

A managed platform sits in the middle and is where most containers end up: a long-lived process, a managed database beside it, TLS and rollouts handled, and a persistent volume available for the cases that genuinely need one.

Docker Compose is not a deployment target. Worth stating because it is such a common expectation. Compose describes services on one machine; a platform models each service as its own resource with its own scaling, and the relationships between them as network and configuration. Some platforms can import a Compose file as a starting point, but the mental model has to change — and on a single rented server, running Compose yourself is a perfectly legitimate alternative to any of this.

Where should the container run?

Long-lived process, a database beside it, maybe a volume

Managed platform

Prebuilt image or platform build, with storage and databases in the same project.

Granite · Railway · Render

Stateless, request-driven, and idle much of the time

Serverless containers

Free while idle — no local state, no background work, no open connections.

Cloud Run · Koyeb

Several containers that only make sense together, and you like the machine

Compose on a VPS

Cheapest per gigabyte, and every operational duty stays yours.

Hetzner · DigitalOcean · anyone

The question that decides this is not which language is inside the image — it is whether the container needs to keep anything, and who builds it.

The options

Prices as published by each provider on the date above. Check them before you commit — they move.

Fly.io

Best for
The cheapest way to keep a small container online, and the best option for several regions.
Pricing
Pay as you go. The smallest shared-cpu-1x machine with 256 MB RAM works out at roughly $2.02/month, billed per second.
  • Cheapest entry point in this table, billed per second, so stopped machines cost only storage.
  • Runs your image essentially as-is, with volumes, private networking and multi-region routing available on the same primitives.
  • Machines are an explicit, scriptable concept, which suits teams that want to orchestrate deployments themselves.
  • That explicitness is also the cost: machines, volumes and networking are yours to understand and maintain.
  • Databases are apps you run and back up yourself rather than managed services.
  • No free tier for new organisations since October 2024.

Railway

Best for
Letting the platform build the image from a Dockerfile and wiring services together quickly.
Pricing
Hobby is $5/month including $5 of usage credits; Pro is $20/month per workspace including $20 of credits. A free plan gives $1 of monthly credits, and there is a 30-day trial.
  • Builds from a Dockerfile or from source without one, and deploys prebuilt images from a registry too.
  • Services in a project reach each other privately, so a container and its database need no public endpoint.
  • The template catalogue covers most off-the-shelf images people want to self-host.
  • Usage-based billing on top of the base fee makes the monthly cost hard to forecast.
  • The Pro fee is charged per workspace, which adds up for small teams.

Render

Best for
A predictable monthly bill for a container that just needs to run.
Pricing
Free web services are available but spin down after 15 minutes without traffic. The cheapest paid instance, Starter, is $7/month for 0.5 vCPU and 512 MB RAM.
  • Builds from a Dockerfile or pulls an existing image, with a real free tier for evaluating.
  • Managed Postgres and Redis, persistent disks, background workers and cron jobs in one account.
  • Fixed instance sizes, which makes the bill easy to explain to whoever signs it off.
  • Free services spin down after 15 minutes idle.
  • Fixed sizes mean scaling is a step change, and costs climb quickly beyond one small instance.

Granite

Best for
Teams that already build images in CI and want the registry, the databases and the storage in one project.
Pricing
Hobby is $9/month and includes $15 of monthly usage credits. Advanced is $39/month with $50 of credits, Professional $149/month with $200. Every plan has unlimited workspace seats.
  • A private Docker registry is part of the platform, so images built in your CI have somewhere to live that the runtime can already authenticate against.
  • Deploy a prebuilt image or let Granite build from GitHub, GitLab or Bitbucket — the two paths are interchangeable per resource.
  • Managed Postgres, MySQL, Valkey and S3-compatible storage sit in the same project over internal DNS, with no public endpoints on the databases.
  • HTTP apps, background workers and cron jobs are all just containers with different commands, so one image can back several resources.
  • Unlimited workspace seats on every plan, and flat pricing that does not move with traffic.
  • No free tier — the cheapest way in is $9/month.
  • Persistent volumes start on the Advanced plan, so Hobby suits stateless containers only.
  • Fewer regions than the hyperscalers, and no multi-region routing yet.

Koyeb

Best for
Global edge deployment of a container with scale-to-zero, if the entry price is acceptable.
Pricing
The Pro plan is $29/month; Scale is $299/month. Serverless Postgres has a small free allowance.
  • Runs your image at edge locations that are included rather than sold separately.
  • Scale-to-zero available for containers that start quickly.
  • The highest entry price of any managed option here.
  • Smaller ecosystem and community than Railway or Render, so there are fewer worked examples when something is unusual.

Google Cloud Run

Best for
Stateless containers with spiky traffic, where paying nothing while idle matters most.
Pricing
No monthly fee. You pay per request and per resource-second, with a monthly free allowance. Cloud SQL and networking are billed separately.
  • Takes any container image and scales to zero, so an idle service is genuinely free.
  • Effectively unlimited scale ceiling, with per-request billing.
  • The most container-native model here: the contract is simply an image that listens on a port.
  • No persistent disk, so any container that expects to write state locally needs redesigning before it will work at all.
  • Instances are request-scoped, which rules out long-lived connections and any background loop that runs between requests.
  • Registry, database, secrets and networking are separate GCP products you assemble and bill separately.

What a Docker app actually needs from a host

The requirements that matter for Docker are different from the ones every generic hosting listicle repeats.
Container-specific criteria
These have nothing to do with the language inside the image, which is exactly why they are the ones that catch people out.
Architecture, not just tags
An image built on an Apple Silicon laptop is arm64, and most platforms run amd64. The failure is abrupt and unhelpful — exec format error, or a container that exits immediately — and it happens after a successful build and push. Build multi-arch with buildx, or set the target platform explicitly, and check what your host actually runs before you debug anything else.
Where the image lives
A public image is easy everywhere. A private one needs the platform to authenticate against your registry, which means credentials, rotation and — on some platforms — a specific registry type. A registry inside the same platform removes that entirely; a registry outside it is one more set of credentials to keep working.
Deploy by digest, not by latest
A mutable tag means two replicas started an hour apart can be running different code, and a rollback is not reproducible. Tag with the commit SHA and deploy by digest so a deployment identifies exactly one image. Platforms differ in whether they resolve the tag once at deploy time or on every pull, which is precisely the ambiguity you are removing.
PID 1 and SIGTERM
Rolling deploys send SIGTERM and then wait. A CMD written in shell form runs your process under /bin/sh, which does not forward signals, so the container is killed after the grace period with requests still in flight — on every single deploy. Use exec form, handle the signal, or add a tiny init process, and match your shutdown timeout to the platform's grace period.
Listen on the port you were given
Almost every platform injects a PORT environment variable and expects the container to bind it on 0.0.0.0. Hard-coding a port, or binding 127.0.0.1, produces a container that runs perfectly and receives no traffic — a health check that never passes, with completely healthy application logs.
The filesystem is not storage
The container filesystem is discarded when the container is replaced, which happens on every deploy, and it is not shared between replicas. Anything that must survive belongs in a database, a bucket, or an explicitly attached volume — and a volume usually binds the service to a single instance, which is a scaling decision as much as a storage one.
Image size is a deploy-time cost
The image is pulled on every deploy and every scale-up, so its size is latency you pay repeatedly. Multi-stage builds that leave the toolchain behind routinely cut images by five to a hundred times depending on the stack. Order the layers so the parts that rarely change sit underneath the parts that change on every commit.
Secrets do not belong in layers
Anything copied into an image stays in its history even if a later layer deletes it, and anyone who can pull the image can read it. Use build-time secret mounts for credentials the build genuinely needs, and inject runtime configuration as environment variables from the platform's encrypted storage.
Whose health check?
The HEALTHCHECK instruction in a Dockerfile is generally ignored by hosting platforms — they run their own HTTP or TCP probes and route traffic on the result. Configure the probe on the platform, point it at an endpoint that reflects readiness rather than merely being listening, and give it a start delay long enough for your slowest boot.

So which should you pick?

One small container, as cheaply as possible. Fly.io, at roughly $2/month for a 256 MB machine, billed per second.

Stateless and idle most of the day. Cloud Run. The container contract is at its purest here, and an idle service is genuinely free — provided nothing in the image expects a disk, a background loop or an open connection.

You want the platform to build it and to explain the bill. Render for fixed pricing, Railway if you would rather assemble a stack from templates.

You already build images in CI. This is where we would argue for Granite. The private registry is part of the platform, so pushing from CI and deploying by digest needs no external credentials; managed Postgres, MySQL, Valkey and S3-compatible storage sit in the same project over internal DNS with no public database endpoints; and web apps, workers and cron jobs are all just containers with different commands, so one image can back all three. From $9/month with $15 of usage credits.

Looking for advice specific to what is inside the image? The Go, Django and Next.js comparisons cover image size, memory and build caching per stack, and the Docker registry page covers pushing and pulling private images.

Hosting for other stacks

Go hosting

Six ways to run a Go binary, from a $2 machine to scale-to-zero — and why Go stays cheap longer.

Django hosting

Seven options weighed on the things Django actually needs: media storage, a real Postgres, Celery workers and enough memory for gunicorn.

Next.js hosting

Vercel and six alternatives, weighed on the things that actually break when you self-host: ISR across replicas, image optimization and build-time env vars.

Rails hosting

Six platforms plus Kamal, weighed on what Rails really needs: a release phase for migrations, a job runner, Active Storage and enough memory for Puma.

Laravel hosting

Laravel Cloud and six alternatives, weighed on queue workers, the scheduler, writable storage and the caches you must rebuild on every deploy.

FastAPI hosting

Six platforms weighed on what an ASGI service actually needs: worker processes, connections that stay open, and a database pool that does not multiply out of control.

Flask hosting

Seven options for the framework that ships no opinions — weighed on the WSGI server you have to bring, the session key you must keep stable, and the extensions that decide the rest.

Symfony hosting

Six platforms weighed on the things Symfony assumes: a warmed cache built at build time, Messenger workers that restart on deploy, and Doctrine migrations that run exactly once.

Remix hosting

Seven platforms for a framework that renders on every request — weighed on streaming, adapters, and how far the loaders sit from the database.

Spring Boot hosting

Six platforms weighed on what the JVM actually asks for: memory it is allowed to use, a container that knows its own limits, and a start-up you can afford to repeat.

Static site hosting

Five ways to serve HTML that is already written — and an honest note about which of them we are not the right answer for.

Docker hosting questions

More questions? Email us at support@granite.so

Be first in line for updates
and special pricing
Get early access to new features and exclusive discounts delivered straight to your inbox