You buy one Miget plan (a Resource) and run an entire application inside it: a public API, a background worker, scheduled cron jobs, a managed database, and a managed cache. Every service shares the plan’s CPU through the Fair Scheduler, so adding services doesn’t change your price. There is no per-service billing. You pay for the plan’s RAM, vCPU, and storage once, then split that capacity across as many services as you need.
Every service in this guide draws from the same plan quota. The Fair Scheduler distributes CPU fairly across all of them under load, so a busy worker can’t starve your API and a burst of API traffic can’t stall your cron jobs.

The services

Public API

An HTTP service that listens on port 5000 and accepts inbound traffic.

Background worker

A private app running a non-web command - just another process, kept off the public network.

Cron jobs

Scheduled tasks that run on a fixed cadence.

Managed data

A managed PostgreSQL database and a managed Valkey cache, wired in automatically.

Option A: one Compose Stack

The cleanest way to describe a multi-service app is a single Docker Compose Stack. Keep your standard compose.yaml for local development, then add a compose.miget.yaml overlay that tells Miget how to size and expose each service using the x-miget keys.
services:
  web:                 # public HTTP entry - must listen on port 5000
    x-miget:
      ram: "1024"
  worker:
    x-miget:
      ram: "512"
      private: true
  db:
    x-miget:
      managed: postgres
      cpu: "500m"
      ram: "1Gi"
      storage: "5Gi"
  cache:
    x-miget:
      managed: valkey
      ram: "256Mi"
What each block does:
  • web is your public entry point. It must listen on port 5000 - that is the port Miget routes external traffic to.
  • worker is marked private: true, so it runs inside the plan but is never exposed to the internet. Reach it over private networking.
  • db uses managed: postgres, so Miget provisions and runs a managed PostgreSQL instance instead of building the image. Miget injects DATABASE_URL into your services.
  • cache uses managed: valkey, so Miget provisions a managed Valkey instance and injects REDIS_URL into your services.
Mark every service that shouldn’t take public traffic as private: true. Only the service listening on port 5000 needs to be reachable from outside the plan.
Point Miget at the repository containing both compose.yaml and compose.miget.yaml, and the whole stack deploys into one Resource. See Docker Compose Stacks for the full overlay reference.

Option B: individual services

If you’d rather assemble the stack piece by piece, deploy each service into the same Resource from the dashboard.
1

Create the API app

Create your app, have it listen on port 5000, and deploy it with a git push. This is your public HTTP entry point.
2

Add a PostgreSQL addon

From the app’s Addons tab, add a PostgreSQL addon. Miget injects DATABASE_URL into the app so your API can connect immediately.
3

Add a Valkey addon

Still on the Addons tab, add a Valkey addon. Miget injects REDIS_URL for your cache connection.
4

Deploy the worker

Deploy your worker as a separate app whose start command runs a non-web process. Keep it private with no public port - it’s just another app running a background command inside the same plan.
5

Add cron jobs

Add a Cron Job for each scheduled task. Cron jobs run on your defined schedule and share the plan’s capacity like every other service.
Share configuration across these services with secrets, so values like your PORT and any credentials stay consistent.

Next steps

Fair Scheduler

How CPU is shared fairly across every service in your plan.

Resource plans

Pick the plan size that fits your whole stack.

Docker Compose Stacks

The full x-miget overlay reference for multi-service deploys.

Private networking

Connect your services to each other without exposing them.