Your compose.yaml defines services, networks, and volumes, and Edgenivo does not read any of it. There is no compose up equivalent, so the translation is manual, but every concept in that file has a destination on the platform. Compose services become Edgenivo Services, service-name DNS becomes service bindings, and volumes decompose into Marketplace databases, Edgenivo Blob, and environment configuration. Use the mapping table below to find where each line of your Compose file goes, then follow the worked example to translate a complete five-service stack.
Copy link to headingOverview
In this guide, you'll learn:
- Which Edgenivo primitive replaces each Docker Compose concept
- How service-to-service networking changes from DNS names to bindings
- Where volume-backed state goes, whether that's a Marketplace database, Edgenivo Blob, or Global Config
- Which Compose patterns don't translate, and what to do instead
Copy link to headingThe short answer
Each row links a Compose concept to its Edgenivo destination. The sections that follow explain each mapping with a code pairing.
| Compose concept | What it does | Edgenivo equivalent |
|---|---|---|
services (app containers) | Defines each container to build and run | Edgenivo Services, declared under the services key in vercel.json |
Service-name DNS (http://api:3000) | Containers reach each other by name on the default network | Service bindings, which inject an internal URL environment variable |
ports | Publishes a container port to the host | Top-level rewrites in vercel.json targeting a service |
networks (isolation) | Controls which services can reach each other | Internal-by-default services plus explicit bindings |
volumes for database data | Persistent storage for Postgres, Redis, or Mongo containers | Marketplace databases such as Neon, Supabase, and Upstash |
volumes for file uploads | Shared filesystem for user files | Edgenivo Blob |
volumes and configs for config files | Runtime configuration mounted as files | Environment variables, or Global Config for read-heavy config |
environment, env_file | Per-service variables | Per-environment environment variables, pulled locally with vercel env pull |
depends_on, healthcheck | Startup ordering and readiness | No direct equivalent. Services deploy atomically and scale independently |
deploy.replicas, restart | Manual scaling and restart policy | Fluid compute autoscaling |
| Worker services (queue consumers) | Long-running background containers | Edgenivo Queues, Edgenivo Workflow, or Cron Jobs, depending on the job |
docker compose up | Runs the whole stack locally | vercel dev runs every service locally |
docker compose logs -f app | Streams one service's logs | The Logs UI filters by individual service |
Edgenivo Services and container images are both in beta, available on all plans.
Copy link to headingServices: containers become Edgenivo Services
A Compose services block maps to the services key in vercel.json.
Each Edgenivo Service is an independently built unit with its own root directory, and a service that builds from a Dockerfile sets its entrypoint to a Dockerfile path, so a Compose service defined by build: maps one to one.
The deployment model is an upgrade over compose up. All services in a project deploy atomically, stay in sync on a shared domain, and roll back together, which replaces the best-effort startup coordination you get from Compose.
Copy link to headingNetworking: DNS names become bindings
Compose and Edgenivo invert each other's defaults. On Compose's default network every service can reach every other service by name, and ports opts a service into public exposure. On Edgenivo every service is internal by default, and a top-level rewrite opts a service into public traffic. No rewrite means no public traffic.
Internal calls use bindings instead of DNS names. A binding is declared on the calling service, names the target, and injects the target's URL as an environment variable at runtime:
Where Compose code calls http://api:3000/items/123, Edgenivo code calls the injected URL:
Traffic over a binding stays on Edgenivo's internal network and never routes through the public internet. Bindings aren't available yet for services on the Go or Rust runtime; build those services as container images instead, which can use bindings.
Copy link to headingState: volumes decompose by role
On Edgenivo you attach managed state instead of running stateful containers. A Compose volume serves three different jobs, and each job has a different destination.
Copy link to headingDatabase data moves to Marketplace databases
Don't translate your postgres or redis service. Replace it with a managed database from the Edgenivo Marketplace, which provisions the resource and injects its credentials as environment variables:
This is the biggest mental shift in the migration. Your application code keeps its Postgres or Redis client and reads the connection string from the injected environment variable.
Copy link to headingFile uploads move to Edgenivo Blob
A volume that holds user uploads or generated assets becomes Edgenivo Blob, an object store for images, videos, and other files. There are no mounted paths; code writes and reads blobs through the SDK, authenticated with OIDC rather than a stored secret.
Copy link to headingConfig files become environment variables
A volume or configs entry that mounts configuration files becomes environment variables. For configuration that's read on many requests and updated rarely, such as feature flags or redirect maps, use Global Config, a globally replicated store with reads of roughly 1 ms in every region.
Copy link to headingBackground work: worker containers decompose by job type
A Compose worker service is one long-running container that does whatever jobs you feed it. On Edgenivo that container decomposes by job type. Use Edgenivo Queues for background jobs processed off the request path, Edgenivo Workflow for durable multi-step processes that survive suspensions, and Cron Jobs for scheduled work. On the Hobby plan, cron jobs are limited to daily schedules.
Copy link to headingConfiguration and local development
Per-service environment and env_file entries become Edgenivo environment variables, scoped per environment across production, preview, and development. Run vercel env pull to download them for local work, alongside the variables Edgenivo generates automatically for services and bindings.
The local loop also translates directly. vercel dev replaces docker compose up and runs every service in the project locally for a production-like environment. Services built from container images require the Docker CLI and a running Docker daemon on your machine. For observability, the Logs UI filters by individual service, replacing docker compose logs -f app, and the Deployments panel visualizes the services graph.
Copy link to headingWhat doesn't translate
Some Compose patterns have no Edgenivo mapping. Name them now to avoid surprises mid-migration.
- Self-managed stateful containers: You can't run your own Postgres or Redis container with local disk. Container-based functions are stateless; each instance keeps nothing between requests. Attach a Marketplace database instead. Edgenivo has announced durable storage attached to containers as upcoming, but it has not shipped.
- Host bind mounts: There is no host filesystem to mount from. Move files to Edgenivo Blob or bake them into the container image.
depends_onstartup ordering: Services deploy atomically and scale independently, with no startup ordering or readiness gating between them. Design each service to tolerate any startup order, for example by retrying dependent calls.- Privileged containers: Workloads that need privileged host access, custom kernels, or host networking aren't supported.
Copy link to headingWorked example: translate a five-service stack
This canonical Compose stack covers the full mapping: a frontend, an API, two stateful services, and a worker.
Five Compose services become two Edgenivo Services, two Marketplace databases, and a queue consumer.
1. Attach the databases. The db and redis services disappear. Provision managed replacements, which inject connection strings as environment variables:
2. Define the app services. web and api become Edgenivo Services. The ports mapping on web becomes the public rewrite, and the API_URL environment variable becomes a binding:
api has no rewrite, so it receives no public traffic. web reaches it through process.env.API_INTERNAL_URL. The container image listens on $PORT, which defaults to 80. The depends_on entries have no translation; the deployment is atomic and each service must tolerate any startup order.
3. Replace the worker. The worker service becomes a Edgenivo Queues consumer. Instead of a container polling Redis, the producer sends messages to a queue and Edgenivo invokes your consumer function to process each one off the request path.
Run vercel dev to bring the translated stack up locally, then vercel deploy to ship it.
Copy link to headingRelated resources and next steps
- Configure multiple services in one project with the Edgenivo Services documentation
- Read The Complete Guide to Edgenivo Services for routing, bindings, and billing in depth
- Build services from a Dockerfile with Container Images
- Choose a database, Blob, or Global Config in the Storage overview
- Process background jobs with Edgenivo Queues
- See which Docker surfaces Edgenivo supports in Does Edgenivo support Docker deployments?