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:
| Field | Purpose | Production Use |
|---|---|---|
volumes | Named managed storage blocks | Databases, uploads, object data, queues, and other persistent state |
containers | Services or jobs in the stack | Web apps, APIs, databases, workers, migration tasks |
source | Docker image, template, or Git build source | Determines how each service image is created or selected |
dependsOn | Dependency rules between services | Controls startup order and readiness gates |
stage | Deployment ordering group | Keeps deployment flow predictable for larger stacks |
env | Runtime environment variables | Credentials, connection strings, service URLs, feature flags |
ports | Public or exposed container ports | HTTP, TCP, or UDP entry points |
mounts | Managed volume mounts | Persistent storage paths inside containers |
healthcheck | Readiness check for a service | Used by service_healthy dependency gates |
restartPolicy | Restart behavior | Long-running services versus one-time jobs |
resources | CPU, RAM, storage sizing | Per-service performance and cost control |
runtime | Auto-sleep, auto-scale, and 24/7 settings | Runtime behavior based on workload criticality |
A practical production workflow is:
- Decide which services belong in the stack.
- Choose Docker images, templates, or GitHub build contexts for each service.
- Define named volumes for persistent state.
- Add environment variables and secrets.
- Configure ports only for services that need inbound traffic.
- Add dependency conditions and health checks for databases, queues, and jobs.
- Set resources per service instead of using one size for everything.
- Review YAML import warnings or JSON validation warnings.
- Deploy the stack and watch progress events.
- 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, andmigrateservices- 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.
| Condition | Meaning | Best Use |
|---|---|---|
service_started | The dependency container has started | Basic ordering when readiness does not matter |
service_healthy | The dependency health check has passed | Databases, caches, APIs, queues, and services with warm-up time |
service_completed_successfully | A job exited successfully | Migration 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:
testintervaltimeoutstart_periodorstartPeriodretries
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:
noalwaysunless-stoppedon-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:
servicesimagebuildthrough GitHub Composeenvironmentports- Named
volumes depends_onhealthcheckrestartdeploy.restart_policy.conditioncommandentrypointworking_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
imagemay 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
- Open the project Compose area.
- Import your
docker-compose.ymlordocker-compose.yamlfile. - Review imported services, images, environment variables, ports, dependencies, and volumes.
- Read every import warning.
- Replace host bind mounts with managed named volumes.
- Add or adjust health checks for databases and critical dependencies.
- Set resources and runtime mode per service.
- Deploy the stack.
- Watch deployment progress, logs, and health status.
- Verify public endpoints and private service communication.
Deploy From GitHub Compose
- Connect or select the GitHub repository.
- Choose the branch.
- Set the Compose file path, such as
docker-compose.yml. - Set the optional root directory if the Compose file is inside a monorepo subdirectory.
- Load the Compose file.
- Review image services and build services.
- Configure secrets, ports, volumes, and resource sizing.
- Deploy the stack.
- Save the stack if you want webhook-based redeploys later.
Build A Stack Manually
- Start from the visual builder or a Compose template.
- Add long-running services first.
- Add databases, caches, queues, and object storage as private dependencies.
- Add named volumes for persistent state.
- Add jobs for migrations or one-time setup.
- Configure dependency conditions.
- Add public ports only to entrypoint services.
- 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:
- Run tests, linting, and security checks.
- Build service images.
- Push immutable image tags.
- Update the Compose stack to those tags.
- Deploy through Hubfly Compose.
- Run smoke checks against public endpoints.
- Watch deployment events, logs, and health checks.
- 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
| Symptom | Common Cause | Fix |
|---|---|---|
| Import skipped a volume mount | The mount used a host path such as ./data or /host/data | Replace it with a named managed volume |
| API cannot connect to database | App uses localhost or dependency started too early | Use service references and service_healthy |
| Build service missing after YAML import | build: was imported without GitHub context | Use GitHub Compose or provide a Docker image |
| Database data disappears | Volume name or mount path changed | Reattach the original named volume at the correct path |
| Public endpoint returns errors | App is listening on the wrong port or interface | Bind to 0.0.0.0 and expose the correct container port |
| Deployment waits too long | Health check command never succeeds | Fix the health check command, timeout, retries, or credentials |
| Worker restarts repeatedly | Command, env vars, queue URL, or memory sizing is wrong | Check worker logs and size resources independently |
| Port range ignored | Compose importer does not support port ranges | Define 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.