Compose Stacks

Compose Stacks let you deploy a multi-service application as one coordinated system inside a Hubfly Space project. Use Compose when your application is more than one container: an API with PostgreSQL, a web app with Redis and workers, a backend with MinIO object storage, or a release that needs a migration job before the main service starts.

Hubfly Compose is designed for production container workflows. It maps supported Docker Compose concepts into Hubfly-managed containers, project networking, managed volumes, runtime resources, health gates, deployment ordering, logs, and rollback behavior.

Hubfly Compose is a managed deployment workflow, not a local Docker Compose engine. It imports and normalizes common Compose patterns, then deploys each service as Hubfly infrastructure inside the project.

Overview

A Compose Stack is the recommended Hubfly workflow for applications that need multiple services to run together. Instead of deploying each container manually and wiring networking, storage, environment variables, and startup order by hand, you define the stack once and deploy the services as a coordinated unit.

Compose Stacks are useful for:

  • Web app plus API deployments
  • API plus database deployments
  • Frontend, backend, worker, and cache stacks
  • PostgreSQL, MySQL, Redis, MinIO, NGINX, and queue-backed applications
  • Docker Compose YAML migration into managed infrastructure
  • GitHub-hosted Compose files with build contexts
  • Release workflows with one-time migration or seed jobs
  • Stateful services that need managed persistent volumes
  • DevOps teams that want repeatable multi-container deployments

Use a single-container deployment when one image, one template, one Git app, or one CLI deploy is enough. Use Compose when the application behaves like a system and the services should be deployed, connected, observed, and rolled back together.

Use Cases

Use Compose for an app and database. A common production pattern is an API service, a PostgreSQL service, and a managed volume mounted at /var/lib/postgresql/data. The API depends on database readiness and receives the database hostname through an environment variable or dynamic service reference.

Use Compose for web and worker separation. A web container can handle HTTP traffic while one or more worker containers process queues, scheduled jobs, email delivery, or background tasks. This keeps resource sizing and restart behavior separate.

Use Compose for object storage and media-heavy workloads. A MinIO service can use a managed volume and stay private or expose only the endpoints needed by trusted clients.

Use Compose for migration jobs. A migration container can run once, complete successfully, and allow the API or web service to start afterward using service_completed_successfully.

Use Compose for repository-based stacks. GitHub Compose can read a Compose file from a repository, resolve image: services, build build: services from repository context, and save the stack for later redeploys.

Avoid Compose when a single service is enough, when the workload depends on host bind mounts, when it requires direct host-level access, or when you expect every Docker Compose feature to behave exactly like it does on a developer laptop.

Architecture And Workflow Overview

A Compose Stack contains:

FieldPurposeProduction Use
volumesNamed managed storage blocksDatabases, uploads, object data, queues, and other persistent state
containersServices or jobs in the stackWeb apps, APIs, databases, workers, migration tasks
sourceDocker image, template, or Git build sourceDetermines how each service image is created or selected
dependsOnDependency rules between servicesControls startup order and readiness gates
stageDeployment ordering groupKeeps deployment flow predictable for larger stacks
envRuntime environment variablesCredentials, connection strings, service URLs, feature flags
portsPublic or exposed container portsHTTP, TCP, or UDP entry points
mountsManaged volume mountsPersistent storage paths inside containers
healthcheckReadiness check for a serviceUsed by service_healthy dependency gates
restartPolicyRestart behaviorLong-running services versus one-time jobs
resourcesCPU, RAM, storage sizingPer-service performance and cost control
runtimeAuto-sleep, auto-scale, and 24/7 settingsRuntime behavior based on workload criticality

A practical production workflow is:

  1. Decide which services belong in the stack.
  2. Choose Docker images, templates, or GitHub build contexts for each service.
  3. Define named volumes for persistent state.
  4. Add environment variables and secrets.
  5. Configure ports only for services that need inbound traffic.
  6. Add dependency conditions and health checks for databases, queues, and jobs.
  7. Set resources per service instead of using one size for everything.
  8. Review YAML import warnings or JSON validation warnings.
  9. Deploy the stack and watch progress events.
  10. Verify service health, logs, endpoints, and storage behavior.

Requirements

Before deploying a production Compose Stack, prepare:

  • A Hubfly Space project in the target region
  • A Compose definition from the visual builder, Hubfly JSON, Docker Compose YAML, template, or GitHub repository
  • Docker images, templates, or Git build contexts for each service
  • Registry credentials for private images if required
  • Environment variables and secrets for every service
  • Named managed volumes for persistent data
  • Correct mount paths for databases, uploads, object storage, and app state
  • Public ports only for services that should receive external traffic
  • Health checks for dependencies that need readiness, not just process startup
  • A backup and restore plan for stateful services

For GitHub Compose, you also need the repository, branch, Compose file path, optional root directory, and deploy trigger preference.

Supported Environments

Compose works best for Docker-compatible services that can run as containers and communicate over project networking.

Good fits include:

  • api, web, worker, scheduler, and migrate services
  • PostgreSQL, MySQL, Redis, MinIO, NGINX, and similar infrastructure containers
  • Monorepos where multiple services are built from different contexts
  • Compose files that use named volumes for persistent data
  • Applications that can connect to dependencies through service names or environment variables
  • Services that expose explicit HTTP, TCP, or UDP ports

Less ideal fits include:

  • Compose files that depend on host bind mounts such as ./data:/data
  • Services that require direct access to the host Docker socket
  • Workloads requiring custom Docker networks as separate runtime networks
  • Services that require privileged host behavior not represented in Hubfly Compose
  • Local-only development Compose files with hardcoded laptop paths

Ways To Start

Compose Templates

Use Compose templates when you want a guided starting point for a common multi-service stack. Templates can prefill service names, images, ports, environment variable patterns, volumes, and dependencies.

Templates are best for teams that want a working baseline before customizing resources, secrets, storage size, domains, and runtime behavior.

Visual Builder

The visual builder is the safest way to create or modify a stack directly in Hubfly Space. Use it when you want to configure services without hand-editing JSON or YAML.

The visual builder supports service source selection, resources, runtime settings, environment variables, volumes, mounts, dependencies, health checks, restart policies, network aliases, command overrides, entrypoints, working directories, and Linux capability settings.

Hubfly Compose JSON

Hubfly Compose JSON is the native stack format. It uses version 1.0 and represents Hubfly-specific concepts directly.

Use JSON when you want a repeatable stack definition, an internal template, a stack you can export and review in code, or a format that preserves Hubfly concepts more directly than generic Docker Compose YAML.

Docker Compose YAML Import

Docker Compose YAML import helps migrate existing docker-compose.yml files into Hubfly Space. The importer reads common Compose fields, creates Hubfly services, imports named volumes, maps supported ports, dependencies, health checks, restart policies, commands, entrypoints, working directories, environment variables, and network aliases.

YAML import is a migration path. It is intentionally practical rather than byte-for-byte identical to running Docker Compose on a local Docker host.

GitHub Compose

GitHub Compose deploys a Compose file directly from a GitHub repository. It can load a compose file from a selected branch, use a root directory, resolve services with image:, and build services with build: from repository context.

Use GitHub Compose when the Compose file lives with the application source and should participate in repository-based deployment workflows.

Service Source Types

Compose services can use different source types depending on the flow.

Docker Image Services

Docker image services run prebuilt images. Use them for official images such as postgres, redis, nginx, and minio, or for application images already built by CI.

Private images can be used when the required registry authentication is configured.

Template Services

Template services use Hubfly templates as service sources. They are useful when a service has known defaults, common ports, expected environment variables, or a standard startup pattern.

Git Build Services

Git build services are supported through GitHub Compose when a repository Compose file contains build: definitions. Hubfly resolves the repository, branch, commit, build context, Dockerfile, build args, and target stage.

Supported build fields include:

  • Build context
  • Dockerfile path
  • Build arguments
  • Target stage

Basic YAML import without GitHub repository context treats build: as unsupported and falls back to an image-based service when possible. Use GitHub Compose when you want Hubfly to build services from repository contexts.

Services And Jobs

Compose containers can be long-running service containers or one-time job containers.

Use service for processes that should keep running:

  • Web servers
  • APIs
  • Databases
  • Redis or queue services
  • Workers
  • Schedulers

Use job for processes that should complete:

  • Database migrations
  • Seed scripts
  • One-time setup tasks
  • Asset preparation
  • Index creation

Jobs are useful with service_completed_successfully. For example, deploy PostgreSQL, wait for it to be healthy, run a migration job, then start the API only after the migration job exits successfully.

Dependency Conditions

Compose dependency conditions control when a service can start relative to another service.

ConditionMeaningBest Use
service_startedThe dependency container has startedBasic ordering when readiness does not matter
service_healthyThe dependency health check has passedDatabases, caches, APIs, queues, and services with warm-up time
service_completed_successfullyA job exited successfullyMigration jobs, seed jobs, setup tasks

Use service_started only when startup order is enough. Use service_healthy when the dependent service must be ready to accept connections. Use service_completed_successfully when a later service depends on a job finishing correctly.

Dependency Example

services:
  db:
    image: postgres:16
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app"]
      interval: 10s
      timeout: 5s
      retries: 10
 
  api:
    image: ghcr.io/acme/api:prod
    depends_on:
      db:
        condition: service_healthy

Health Checks And Health Gates

Health checks are critical for production Compose deployments. A container can be running while the application inside it is still booting, migrating, loading indexes, accepting connections, or waiting on dependencies.

Hubfly Compose supports health check fields commonly used by Docker Compose:

  • test
  • interval
  • timeout
  • start_period or startPeriod
  • retries

Example database health check:

{
  "test": ["CMD-SHELL", "pg_isready -U app"],
  "interval": "10s",
  "timeout": "5s",
  "retries": 10
}

Use health checks for databases, queues, search engines, object storage, APIs with startup work, and any dependency that should not be consumed until it is ready.

Dynamic Service References

Dynamic service references let a later service use runtime details from an earlier service.

Supported token patterns include:

{{service:db.host}}
{{service:db.ip}}
{{service:db.containerId}}
{{service:db.dockerId}}

You can use these tokens in environment variable values, command arguments, entrypoint arguments, and health check tests.

Example:

DATABASE_HOST={{service:db.host}}
DATABASE_PORT=5432

The referenced service must deploy earlier or already exist in the project context. If a token points to a service that is not available yet, the value may remain unresolved and the deployment will record a warning.

Environment Variables

Compose environment variables are runtime configuration values for each service. Use them for database credentials, service URLs, feature flags, ports, runtime mode, API keys, and integration settings.

Environment variables can be provided as arrays or key-value objects in Docker Compose YAML. Secret values can be marked as secret in Hubfly so they are redacted in deployment logs.

Practical app and database pattern:

POSTGRES_DB=app
POSTGRES_USER=app
POSTGRES_PASSWORD=change-me
DATABASE_HOST={{service:db.host}}
DATABASE_PORT=5432
DATABASE_URL=postgres://app:change-me@{{service:db.host}}:5432/app

Keep service-specific values on the service that needs them. Use project-level variables for shared defaults used across multiple containers.

Volumes And Persistent Storage

Compose Stacks use managed named volumes for persistent data. A named Compose volume becomes a Hubfly managed volume that can be mounted into one or more services.

Use volumes for:

  • Database data directories
  • Redis persistence files
  • MinIO object storage
  • Uploaded files
  • Queue state
  • Search indexes
  • Application-generated files that must survive redeploys

Supported named volume pattern:

volumes:
  db-data:
 
services:
  db:
    image: postgres:16
    volumes:
      - db-data:/var/lib/postgresql/data

Host bind mounts are skipped because Hubfly services run on managed regional infrastructure, not on your local machine.

Unsupported host bind mount pattern:

services:
  app:
    volumes:
      - ./local-path:/app
      - /host/path:/data

For production databases, use High Performance storage. For large-file workloads such as MinIO, media stores, backups, artifacts, and datasets, use Balanced storage. For normal application files and low-intensity persistent state, use Standard storage.

Networking And Ports

All Compose services run on the project network. Services can communicate privately without publishing every dependency to the internet.

Compose networking supports:

  • Private service-to-service communication
  • Managed project network aliases
  • Public HTTP endpoints
  • Public TCP endpoints
  • UDP port mappings
  • Custom domains after deployment
  • Load balancers for multi-target traffic

Docker Compose network definitions are not recreated as separate Docker networks. Hubfly uses the project network and imports supported aliases where possible.

Port Mapping

Common short and long port formats are supported:

ports:
  - "8080:80"
  - "5432"
  - target: 6379
    published: 6379
    protocol: tcp

Port ranges are skipped during import. Publish only services that need inbound traffic. Keep databases, queues, caches, and internal APIs private unless there is a specific operational reason to expose them.

Restart Policies

Supported restart policy names are:

  • no
  • always
  • unless-stopped
  • on-failure

Services with restart behavior are treated as long-running services. A restart policy of no can be treated as a job-style container.

Docker Compose deploy restart policy conditions are mapped where possible. Restart delay and restart window settings are currently ignored during YAML import, so review import warnings before deploying.

Resource And Runtime Settings

Each Compose service can define CPU, RAM, storage, runtime behavior, and scaling-related limits where supported.

Resource fields include:

  • CPU
  • RAM
  • Storage
  • Maximum CPU for eligible scaling modes
  • Maximum RAM for eligible scaling modes

Runtime fields include:

  • Auto-sleep
  • Auto-scale
  • 24/7 runtime
  • Auto-scale mode where supported

Shared-tier services use locked runtime behavior. Dedicated services provide more control and are usually the right choice for production services, databases, queues, and always-on applications.

Allocate resources per service. A database, API, worker, frontend, and cache rarely need the same CPU and memory profile.

Configuration Reference

A Hubfly Compose JSON stack uses version 1.0.

Minimal JSON shape:

{
  "version": "1.0",
  "name": "api-stack",
  "volumes": [
    {
      "name": "db-data",
      "sizeMB": 10240
    }
  ],
  "containers": [
    {
      "name": "db",
      "source": {
        "type": "docker",
        "image": "postgres:16"
      },
      "mounts": [
        {
          "volume": "db-data",
          "mountPath": "/var/lib/postgresql/data"
        }
      ]
    }
  ]
}

Container names and volume names are normalized into deployment-safe names. Duplicate names are made unique. Shared-tier services that request resources beyond the shared profile are normalized to dedicated behavior.

Docker Compose YAML Compatibility

YAML import supports a practical subset of Docker Compose.

Supported or partially supported fields include:

  • services
  • image
  • build through GitHub Compose
  • environment
  • ports
  • Named volumes
  • depends_on
  • healthcheck
  • restart
  • deploy.restart_policy.condition
  • command
  • entrypoint
  • working_dir
  • Network aliases on the project network

Unsupported or adjusted fields include:

  • Host bind mounts are skipped
  • Non-volume mounts are skipped
  • Port ranges are skipped
  • Custom Docker networks are mapped to the project network
  • Unsupported dependency conditions fall back to service_started
  • Restart delay and restart window are ignored
  • Services without image may need manual input unless using GitHub Compose build context

If the importer reports warnings, review them before deploying. Warnings are especially important for volumes, ports, networks, build sections, and missing images.

Setup Steps

Deploy From Docker Compose YAML

  1. Open the project Compose area.
  2. Import your docker-compose.yml or docker-compose.yaml file.
  3. Review imported services, images, environment variables, ports, dependencies, and volumes.
  4. Read every import warning.
  5. Replace host bind mounts with managed named volumes.
  6. Add or adjust health checks for databases and critical dependencies.
  7. Set resources and runtime mode per service.
  8. Deploy the stack.
  9. Watch deployment progress, logs, and health status.
  10. Verify public endpoints and private service communication.

Deploy From GitHub Compose

  1. Connect or select the GitHub repository.
  2. Choose the branch.
  3. Set the Compose file path, such as docker-compose.yml.
  4. Set the optional root directory if the Compose file is inside a monorepo subdirectory.
  5. Load the Compose file.
  6. Review image services and build services.
  7. Configure secrets, ports, volumes, and resource sizing.
  8. Deploy the stack.
  9. Save the stack if you want webhook-based redeploys later.

Build A Stack Manually

  1. Start from the visual builder or a Compose template.
  2. Add long-running services first.
  3. Add databases, caches, queues, and object storage as private dependencies.
  4. Add named volumes for persistent state.
  5. Add jobs for migrations or one-time setup.
  6. Configure dependency conditions.
  7. Add public ports only to entrypoint services.
  8. Deploy and verify logs, health checks, and endpoints.

Deployment Examples

API With PostgreSQL

services:
  db:
    image: postgres:16
    environment:
      POSTGRES_DB: app
      POSTGRES_USER: app
      POSTGRES_PASSWORD: change-me
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app"]
      interval: 10s
      timeout: 5s
      retries: 10
 
  api:
    image: ghcr.io/acme/api:prod
    depends_on:
      db:
        condition: service_healthy
    environment:
      DATABASE_HOST: "{{service:db.host}}"
      DATABASE_PORT: "5432"
    ports:
      - "3000:3000"
 
volumes:
  db-data:

Production notes: use High Performance storage for db-data, keep PostgreSQL private, expose only the API, and use immutable image tags for production releases.

Web App With Worker And Redis

services:
  redis:
    image: redis:7
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 10
 
  web:
    image: ghcr.io/acme/web:2026-05-28
    depends_on:
      redis:
        condition: service_healthy
    environment:
      REDIS_HOST: "{{service:redis.host}}"
    ports:
      - "8080:8080"
 
  worker:
    image: ghcr.io/acme/web:2026-05-28
    depends_on:
      redis:
        condition: service_healthy
    command: ["npm", "run", "worker"]
    environment:
      REDIS_HOST: "{{service:redis.host}}"

Production notes: size the worker separately from the web service. Workers often need different CPU, memory, restart, and scaling behavior.

Migration Job Before API

services:
  db:
    image: postgres:16
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app"]
      interval: 10s
      timeout: 5s
      retries: 10
 
  migrate:
    image: ghcr.io/acme/api:prod
    command: ["npm", "run", "migrate"]
    restart: "no"
    depends_on:
      db:
        condition: service_healthy
 
  api:
    image: ghcr.io/acme/api:prod
    depends_on:
      migrate:
        condition: service_completed_successfully
    ports:
      - "3000:3000"

Production notes: migration jobs should be idempotent when possible and should run only after backups are validated for production databases.

CI/CD Integration

Compose can be used with several CI/CD patterns.

Use image-based CI/CD when your pipeline builds and tests images before deployment. The Compose stack references immutable image tags, and Hubfly deploys those images.

Use GitHub Compose when your repository owns the Compose file and services with build: contexts should be built from source during deployment.

Use exported Hubfly Compose JSON when you want a reviewed, Hubfly-native stack definition stored as an internal deployment artifact.

A production CI/CD workflow looks like this:

  1. Run tests, linting, and security checks.
  2. Build service images.
  3. Push immutable image tags.
  4. Update the Compose stack to those tags.
  5. Deploy through Hubfly Compose.
  6. Run smoke checks against public endpoints.
  7. Watch deployment events, logs, and health checks.
  8. Roll forward with a fixed image tag if a service fails.

Avoid using floating tags such as latest for production unless your team intentionally accepts the rollback and traceability risk.

Docker And Kubernetes Considerations

If you are coming from Docker Compose, expect familiar service, image, environment, port, volume, dependency, and health check concepts. The main difference is that Hubfly deploys services onto managed project infrastructure instead of running Docker Compose on your local host.

If you are coming from Kubernetes, think of a Compose Stack as a lighter deployment unit for related services. Managed volumes behave like persistent storage from an operational point of view, service-to-service communication happens over project networking, and health checks act as readiness gates for dependency flow.

Hubfly Compose does not require you to write Kubernetes manifests, Services, Deployments, StatefulSets, or PersistentVolumeClaims. It is intended for teams that want production-grade multi-container deployment without operating a Kubernetes cluster.

Networking Considerations

Keep internal dependencies private. Databases, Redis, queues, search engines, and admin tools should usually be reachable only from other services in the project.

Expose one public entry point when possible. Many stacks only need the web or API service published publicly; database and worker services should stay private.

Use clear service names. Names such as api, web, worker, db, redis, minio, and migrate make environment variables, dynamic references, logs, and incident response easier.

Do not rely on localhost for cross-service communication. In containers, localhost refers to the same container. Use service references, aliases, or environment variables that point to the dependency service.

Security Best Practices

Keep secrets out of Compose files when possible. Use Hubfly secret environment variables for passwords, tokens, private keys, API credentials, and database URLs.

Do not expose databases publicly unless there is a deliberate operational requirement and strong access control. Private project networking is the safer default.

Use least privilege for Linux capabilities. The visual builder exposes capability controls, but production services should not receive broad capabilities unless the image truly requires them.

Avoid host bind mounts. They are not portable, they can leak assumptions from local development, and Hubfly skips them during import.

Use private registry credentials carefully. Rotate credentials and prefer scoped tokens where the registry supports them.

Scaling Considerations

Scale by service role, not by stack size. APIs, workers, databases, caches, and object stores have different bottlenecks.

Increase CPU for compute-heavy APIs, build-heavy services, workers, and request handlers under CPU pressure.

Increase RAM for databases, caches, JVM services, Node.js apps under memory pressure, and services with large in-memory queues.

Increase storage capacity before databases or object stores approach full usage. Running near full disk can cause failed writes, corrupted transactions, blocked compaction, and failed uploads.

Use High Performance storage for database-style workloads with many short random reads and writes. Use Balanced storage for large-file workloads such as MinIO, media, backups, artifacts, and datasets.

Split services when one container is doing too much. Separate web, worker, scheduler, migration, database, and cache roles so each can be sized and operated independently.

Performance Notes

Startup order is not the same as readiness. Use health checks when a dependency needs time to become usable.

Database performance depends heavily on storage mode, RAM, and connection behavior. Use High Performance storage for production databases and avoid running them at the edge of memory limits.

Object storage and media workloads benefit from large-file throughput. Use Balanced storage for MinIO, backups, large uploads, artifacts, and datasets.

Workers should be tuned separately from web services. A worker that processes large jobs can consume CPU or memory very differently from the HTTP service using the same image.

Public endpoints should point to services that are actually designed to accept external traffic. Publishing every port increases security and operational risk.

Monitoring And Logging

Monitor Compose deployments at both stack and service level.

Watch:

  • Deployment progress events
  • Service startup and rollback events
  • Container logs
  • Health check failures
  • CPU and memory usage per service
  • Storage growth per volume
  • Public endpoint availability
  • Background worker failures
  • Database and queue connection errors
  • Project budget usage

For production apps, add application-level logs that identify the service, request or job ID, dependency name, and error type. Avoid logging secrets or full connection strings.

Rollback Behavior

If a Compose deployment fails after creating new services, Hubfly attempts to roll back services created during that deployment. Rollback helps avoid leaving a project in a partially deployed state.

Rollback is not a replacement for release discipline. You should still review import warnings, use immutable image tags, add health checks, validate secrets, and test database migrations before production deployment.

Troubleshooting

YAML Import Fails

Check that the file is valid YAML, includes a top-level services section, and defines each service as an object. Remove local-only development fields that are not needed in production.

YAML Imports But Warnings Appear

Review every warning. Common warnings include skipped host bind mounts, unsupported build sections outside GitHub Compose, skipped port ranges, custom networks mapped to project networking, unsupported dependency conditions, and services missing images.

Service Starts Before A Dependency Is Ready

Use service_healthy and add a real health check to the dependency. service_started only confirms that the container started, not that the database, API, queue, or cache is ready.

Dynamic Service Reference Does Not Resolve

Check that the referenced service name is correct, that the target service deploys earlier, and that the token uses a supported field such as host, ip, containerId, or dockerId.

Database Starts Empty After Redeploy

Verify that the same named volume is still attached to the database data directory. A changed volume name or mount path can make the database initialize a new empty data directory.

Service Is Running But Not Reachable

Check that the service listens on the configured container port and binds to 0.0.0.0. Also verify the public HTTP or TCP endpoint and confirm the service is meant to be public.

Deployment Rolls Back

Check the failing image, registry credentials, required environment variables, dependency health checks, volume names, command overrides, entrypoints, and service logs.

Common Errors

SymptomCommon CauseFix
Import skipped a volume mountThe mount used a host path such as ./data or /host/dataReplace it with a named managed volume
API cannot connect to databaseApp uses localhost or dependency started too earlyUse service references and service_healthy
Build service missing after YAML importbuild: was imported without GitHub contextUse GitHub Compose or provide a Docker image
Database data disappearsVolume name or mount path changedReattach the original named volume at the correct path
Public endpoint returns errorsApp is listening on the wrong port or interfaceBind to 0.0.0.0 and expose the correct container port
Deployment waits too longHealth check command never succeedsFix the health check command, timeout, retries, or credentials
Worker restarts repeatedlyCommand, env vars, queue URL, or memory sizing is wrongCheck worker logs and size resources independently
Port range ignoredCompose importer does not support port rangesDefine explicit individual ports

Best Practices

Use explicit service names: api, web, worker, db, redis, minio, and migrate are easier to operate than generic names.

Keep production Compose files focused on runtime behavior. Remove local development bind mounts, test-only services, and machine-specific paths before import.

Use named volumes for every stateful service. Do not rely on ephemeral container storage for databases, uploads, object storage, queues, or indexes.

Add health checks to databases, caches, object stores, APIs with warm-up time, and any dependency used by service_healthy.

Use immutable image tags for production deployments. Avoid deploying unknown future versions under the same tag.

Separate services and jobs. Long-running processes should be service containers; migrations and setup tasks should be job containers.

Review import warnings before deployment. Warnings usually point to behavior that changed during migration from Docker Compose to Hubfly.

Production Recommendations

For production APIs, use dedicated runtime, explicit CPU and RAM, health checks, private dependencies, and public endpoints only on the API or web service.

For production databases, use managed volumes, High Performance storage, stable mount paths, backups, and service_healthy dependency gates.

For MinIO and large-file services, use Balanced storage, monitor growth, and avoid colocating unrelated data on the same volume.

For workers, deploy them as separate services from the web process so they can be restarted, scaled, and sized independently.

For migrations, use jobs and service_completed_successfully so the application does not start before schema changes finish.

For GitHub Compose, keep the Compose file close to the app code, pin production image tags or commits, and save the stack for repeatable redeploys.

Limitations

Hubfly Compose does not run Docker Compose exactly like a local Docker host. It maps supported Compose concepts into Hubfly-managed infrastructure.

Host bind mounts are not supported. Use named managed volumes instead.

Custom Docker networks are mapped to the project network rather than recreated as separate Docker networks.

Port ranges are skipped during YAML import.

build: requires GitHub Compose context if Hubfly needs to build from repository source. Basic YAML import without repository context cannot build local paths from your machine.

Restart delay and restart window settings are ignored during import.

Persistent volumes are not backups. Use application-aware backups and test restores for production data.

FAQ

Is Hubfly Compose The Same As Docker Compose?

No. Hubfly Compose imports and maps supported Docker Compose concepts into Hubfly-managed containers, project networking, volumes, runtime settings, health gates, and rollback behavior.

Can I Import An Existing docker-compose.yml?

Yes. YAML import supports common service, image, environment, port, named volume, dependency, health check, restart, command, entrypoint, working directory, and network alias settings. Unsupported fields are skipped or converted with warnings.

Can Compose Build Services From Source?

Yes, through GitHub Compose when build: sections can be resolved against a GitHub repository, branch, commit, Compose file path, and build context.

Can Compose Services Use Private Images?

Yes. Use Docker image services with registry authentication for private registries.

Can A Service Wait For A Database?

Yes. Add a database health check and make the dependent service use service_healthy.

Can I Run Database Migrations?

Yes. Use a job container and make the application depend on it with service_completed_successfully.

Can Compose Create Volumes?

Yes. Named Compose volumes are imported as managed Hubfly volumes. Host bind mounts are skipped.

Can I Redeploy A GitHub Compose Stack Automatically?

Yes. GitHub Compose stacks can be saved so repository webhooks can trigger future redeploys based on repository, branch, Compose file path, and deploy trigger settings.

Real-World Examples

SaaS API Stack

A production SaaS stack might include api, worker, db, and redis. The API exposes HTTP, the worker stays private, PostgreSQL uses a High Performance volume, Redis stays on the project network, and both app services depend on dependency health checks.

WordPress-Style CMS Stack

A CMS stack might include an app service, a database service, and a media volume. The app exposes HTTP, the database stays private, uploaded media uses managed storage, and database backups are handled separately from the volume lifecycle.

MinIO Object Storage Stack

A MinIO stack uses a Balanced volume mounted at the object data path. Public access is limited to the required endpoint, credentials are stored as secrets, and storage growth is monitored because object data can expand quickly.

Monorepo GitHub Compose Stack

A monorepo might define api, web, and worker services with separate build: contexts. GitHub Compose resolves each context from the repository, builds each service, deploys them to the project network, and saves the stack for webhook redeploys.

Feedback

Was this page helpful?

Tell us whether this page helped you complete the task you came here for.