Architecture
Hubfly Space is built around a simple operating belief: developers should be able to ship real containers, multi-service apps, databases, internal tools, GPU workloads, and production services without turning every deployment into a custom infrastructure project.
This page explains how to think when using Hubfly Space. It is not only a diagram of internal components. It is the culture of the platform: what Hubfly tries to make easy, what it keeps explicit, what it refuses to hide, and how you should approach each deployment decision.
The best Hubfly workflow is not “click deploy and hope.” The best workflow is: understand the service, choose the right deployment shape, keep private things private, expose only deliberate entry points, attach persistent storage intentionally, and grow from a simple deploy into a production system step by step.
The Hubfly way of thinking
Hubfly Space is designed for builders who want control without carrying the full operational burden of raw servers, reverse proxies, Docker hosts, firewall scripts, volume wiring, build machines, and deployment glue.
When you deploy on Hubfly, think in five questions:
| Question | What you are deciding |
|---|---|
| What am I running? | Git app, Docker image, template, Compose stack, GPU workload, database, worker, or internal tool |
| What needs to persist? | Volumes, database data, uploaded files, model weights, generated assets, or nothing |
| What should be public? | HTTP endpoint, TCP endpoint, custom domain, load balancer, or no public ingress |
| What should stay private? | Databases, queues, Redis, admin tools, internal APIs, debug ports, and maintenance interfaces |
| How will this grow? | More CPU/RAM, manual replicas, load balancing, Compose dependencies, logs, storage, CI/CD, and team access |
That is the platform culture. Hubfly gives you a strong default path, but the important decisions stay visible.
Why Hubfly Space exists
Most deployment platforms make one of two tradeoffs:
- They hide almost everything, which feels easy at first but becomes restrictive when the app needs real networking, storage, or multi-service behavior.
- They expose raw infrastructure too early, which gives control but forces every user to become their own platform team.
Hubfly Space tries to sit in the useful middle.
You still deploy containers. You still choose ports, volumes, environment variables, runtime size, domains, and dependencies. But Hubfly handles the repetitive platform work around building, scheduling, proxying, private networking, volume attachment, tunnel access, and operational visibility.
The goal is not to make infrastructure disappear. The goal is to make infrastructure understandable and usable.
The mental model
Think of a Hubfly project as a production workspace for one application, environment, team boundary, or customer deployment.
A project can contain:
- Single containers
- Compose stacks
- Templates
- Git deployments
- Docker image deployments
- Managed volumes
- Private network aliases
- Public endpoints
- Custom domains
- Load balancers
- Firewall rules
- HubTunnels
- GPU workloads
- Team access and permissions
The project is the boundary. Inside that boundary, services can communicate privately. Outside that boundary, traffic only enters through the access paths you create.
The platform layers
Hubfly Space is easier to understand when you separate the platform into layers.
| Layer | What it means to users | How to think about it |
|---|---|---|
| Source | Where the deployable workload comes from | Git, Docker image, template, Compose definition, CLI upload, or GPU template |
| Build | How source becomes a runnable image | Automatic detection when possible, manual config when needed |
| Runtime | How the service runs | CPU, RAM, disk, env vars, commands, restart behavior, health, scaling |
| Storage | What survives redeploys | Attach volumes deliberately; do not store important data only in ephemeral container layers |
| Network | How services talk | Private by default inside a project; public only when you create ingress |
| Edge | How public traffic reaches services | Proxy routes, SSL, domains, load balancers, redirects, Firewall, TCP streams |
| Access | How operators reach private services | HubTunnels for temporary local access without public exposure |
| Operations | How you run it over time | Logs, rollouts, sync, billing, scale, cleanup, and production checks |
When something goes wrong, identify the layer first. A build error is not a proxy error. A private database connection issue is not a public DNS issue. A full disk is not a scaling issue. Hubfly works best when you reason in layers.
Hubcell, briefly
Hubfly runs containers on a containerization platform we built called Hubcell.
Hubcell is the runtime foundation underneath Hubfly Space. It manages the practical container operations that users expect the platform to handle: creating runtime units, applying resource settings, attaching volumes, inspecting running services, managing execution sessions, and giving Hubfly a consistent way to operate containers across regions.
You do not need to learn Hubcell to use Hubfly. The user-facing model is still projects, containers, volumes, endpoints, Compose stacks, and tunnels. But it is useful to know that Hubfly is not only a dashboard over generic scripts. There is a dedicated container runtime layer underneath the product, built to make Hubfly’s deployment model consistent.
Think of it this way:
| Product concept | Runtime foundation |
|---|---|
| Hubfly container | A Hubcell-managed runtime unit |
| Hubfly volume | A runtime-attached persistent storage unit |
| Terminal/session/log operations | Runtime operations exposed through Hubfly |
| Scaling and runtime updates | Hubfly orchestration applied through the runtime layer |
The reason this matters: Hubfly can make container behavior feel cohesive because the platform controls the deployment model from source to runtime to edge routing.
Hubfly Builder
Hubfly Builder is the build system that turns source code into deployable container images.
The Builder philosophy is practical: detect what can be detected, respect what the repository already declares, and give the user manual control when automatic detection is not enough.
When you deploy from Git, Hubfly tries to understand the project shape:
- Is there a Dockerfile?
- Is there a package manager or framework hint?
- Is there a build command?
- Is there a start command?
- Is there a working directory?
- Are there build-time environment variables?
- Does the repo need manual runtime settings?
The goal is not magic for its own sake. The goal is to produce a production-wise image and launch it with the least unnecessary ceremony.
Automatic detection vs manual control
Automatic detection is useful when the app follows common conventions. Manual control is useful when the app has special requirements.
| Use automatic detection when | Use manual config when |
|---|---|
| The repo follows a common framework layout | The app has a nonstandard monorepo structure |
| The default build/start commands are correct | The build command needs flags or a custom working directory |
| The Dockerfile is already correct | You need to override runtime commands or init behavior |
| The app is a standard web service | The app is a worker, scheduler, migration job, or custom runtime |
| You want the fastest first deploy | You need reproducibility and explicit operations |
Good Hubfly culture is to start simple, then make the parts explicit as the app becomes important.
For a prototype, automatic detection is fine. For production, write down the runtime assumptions: command, port, env vars, health behavior, storage, scaling plan, and rollback path.
Dockerfile-first or Builder-first?
Hubfly supports both mindsets.
Use a Dockerfile when:
- Your team already maintains container images.
- You need exact OS packages or system dependencies.
- You need a reproducible build across local, CI, and production.
- You want full control over layers, caching, and runtime.
- You already publish images to a registry.
Use Hubfly Builder when:
- You want Hubfly to build directly from Git.
- Your app follows common framework conventions.
- You want a faster path from repository to running service.
- You prefer managing deploy settings in Hubfly instead of maintaining a custom Dockerfile immediately.
A mature team can use both: Builder for straightforward apps and Dockerfiles for specialized services.
The proxy layer
The proxy layer is how public traffic enters Hubfly-managed services.
When you expose a container or load balancer, Hubfly configures routing for HTTP or TCP traffic. For HTTP services, the proxy layer can handle domain routing, SSL, force HTTPS, edge templates, headers, redirects, custom domains, and Firewall integration. For TCP services, it can publish stream-style access when the protocol truly needs raw TCP exposure.
The important idea is separation:
- Running a container does not automatically make it public.
- Adding a volume does not expose data.
- Creating a database does not mean the database has an internet port.
- Public access is a separate, deliberate step.
This is one of Hubfly’s core design choices. Deploy first. Expose deliberately.
Private-first networking
Every production system has two kinds of traffic:
| Traffic type | Hubfly approach |
|---|---|
| Service-to-service traffic | Private project networking |
| User/customer traffic | Public endpoints, domains, load balancers, and Firewall |
| Operator/admin traffic | HubTunnels |
Keep databases, queues, caches, internal APIs, and admin dashboards private unless there is a clear reason to expose them.
The platform gives you public ingress tools, but it does not assume every port should be public. That is intentional.
How to think about storage
Containers are replaceable. Important data is not.
That is the storage culture in Hubfly.
If a service writes data that must survive redeploys, restarts, rebuilds, or replacement, attach a volume. If the data is temporary cache, generated scratch files, or disposable build output, it may not need persistent storage.
Use this decision table:
| Data type | Storage approach |
|---|---|
| Database data | Persistent volume |
| User uploads | Persistent volume or object storage pattern |
| Model weights | Persistent volume if downloaded at runtime; image layer if baked intentionally |
| Build artifacts | Usually not a runtime volume |
| Cache | Usually disposable unless warm cache matters |
| Logs | Platform/application logs; avoid relying on container filesystem as archive |
A common mistake is deploying a database as if it were a stateless web app. In Hubfly, databases should be treated as stateful services with persistent volumes, private networking, backup planning, and careful scaling decisions.
How to think about Compose
Compose is for systems, not just “multiple containers.”
Use Compose when the application behaves as a group:
- Web app plus database
- API plus worker plus queue
- App plus Redis plus object storage
- Internal API plus scheduler
- Multi-service development environment promoted into a managed deployment
When deploying Compose on Hubfly, think about responsibilities:
| Compose concern | How to approach it |
|---|---|
| Service boundaries | Name services according to their role: web, api, worker, postgres, redis |
| Dependencies | Start databases and queues before apps that depend on them |
| Volumes | Attach persistent storage to stateful services only |
| Public ports | Expose only user-facing services |
| Internal access | Use private networking for service-to-service communication |
| Secrets | Use environment variables and avoid baking secrets into images |
| Rollback | Expect stack deployment to be coordinated, not a set of random one-off launches |
Compose is powerful because it lets you express the shape of an app. But it also makes bad assumptions visible. If every service publishes a public port, the stack is probably not production-ready.
How to think about scaling
Scaling is not only “more replicas.” It is choosing the correct pressure release.
Ask what problem you are solving:
| Symptom | First thought |
|---|---|
| CPU or RAM is too low | Vertical auto-scale or larger runtime size |
| Requests need more parallel capacity | Manual replicas behind a load balancer |
| One instance cannot serve enough traffic | Load-balanced replicas |
| Worker queue is backed up | More worker replicas or better queue design |
| Database is slow | Query/index/storage tuning before generic replicas |
| App crashes under traffic | Logs, health checks, resource limits, and dependency behavior first |
Hubfly supports vertical auto-scale and manual replicas, but production scaling still requires understanding the workload. Stateless HTTP apps are easier to replicate. Databases need database-native replication patterns. Workers need idempotency. File uploads need shared storage or object storage patterns.
How to think about Firewall and tunnels
Hubfly gives you both Firewall and HubTunnels because they solve different problems.
| Tool | Purpose |
|---|---|
| Firewall | Protect public HTTP domains at the edge |
| HubTunnels | Reach private services temporarily from your machine |
If the service is public, protect it. If the service is private, do not expose it just to make access convenient. Use a tunnel.
This is especially important for databases and admin tools. A private database plus HubTunnel is a healthier default than a public TCP endpoint with hope as the security model.
Deployment source culture
Choose the source type that matches how much control and repeatability you need.
| Source | Best for | Watch out for |
|---|---|---|
| Git | Apps built from source | Build commands, branch selection, env scopes, monorepos |
| Docker image | CI-built images and known runtimes | Registry credentials, tags, rollout hooks |
| Template | Fast known services | Review defaults before production |
| Compose | Multi-service systems | Avoid exposing internal services publicly |
| CLI deploy | Local workflows and scripted deploys | Keep build config repeatable |
| GPU template | Accelerated notebooks and AI workloads | Wallet balance, disk size, runtime reproducibility |
A good first Hubfly deploy is simple. A good production Hubfly deploy is explicit.
The recommended first production path
When starting a new app on Hubfly, follow this path:
- Create a project for the app or environment.
- Deploy the smallest useful version of the service.
- Confirm logs, runtime command, and health behavior.
- Add required environment variables.
- Attach persistent storage only where the service needs state.
- Expose only the user-facing port.
- Add a custom domain and SSL when the service is ready for users.
- Keep databases and internal tools private.
- Use HubTunnels for admin access.
- Add Firewall rules for public domains.
- Add scaling only after you understand the workload pressure.
- Document the deploy shape so the next person knows why each setting exists.
This sequence prevents the most common failure mode: configuring everything at once before proving the service actually runs.
Watch-outs when deploying
These are the things to check before you call a deployment production-ready.
| Area | Watch-out |
|---|---|
| Build | Does the app build reproducibly from the selected branch and working directory? |
| Runtime | Is the start command correct for production, not just local development? |
| Port | Is the app listening on the port Hubfly exposes? |
| Environment | Are secrets present at runtime and not committed to Git? |
| Storage | Is every stateful path backed by a volume? |
| Health | Can the service fail fast and restart cleanly? |
| Networking | Are private services private and public services intentionally exposed? |
| Domains | Are DNS, SSL, and redirects configured for the right endpoint? |
| Firewall | Are public apps protected without blocking legitimate users? |
| Scaling | Is the app stateless enough to replicate safely? |
| Cost | Are always-on services, volumes, and GPUs intentional? |
| Cleanup | Are unused endpoints, tunnels, old replicas, and test volumes removed? |
Watch-outs when using Compose
Compose deserves extra care because it can deploy a whole system at once.
Before deploying a Compose stack, ask:
- Which service is the public entry point?
- Which services are internal only?
- Which services need persistent volumes?
- Which services must start before others?
- Which environment variables are build-time vs runtime?
- Which ports from local Docker Compose should not become public in production?
- What happens if one service fails during deployment?
- What data must survive rollback or replacement?
- Which logs should I inspect first if the stack fails?
The best Compose stacks are boring in the right way: clear service names, explicit dependencies, private databases, one deliberate public entry point, and persistent volumes only where needed.
How Hubfly thinks about production
Production does not mean “large.” Production means the service has consequences.
A small internal tool can be production if a team depends on it. A customer API is production even at low traffic. A database is production the moment it stores data you cannot casually lose.
Hubfly’s production mindset is:
- Make deployment repeatable.
- Make exposure explicit.
- Make state durable.
- Make private access easy without public exposure.
- Make logs and runtime state visible.
- Make scaling a response to measured pressure.
- Make cleanup part of normal operations.
Real-world architecture patterns
Simple web app
Use Git or Docker image deployment. Expose one HTTP port. Add a custom domain and SSL. Keep storage ephemeral unless the app writes uploads or durable files.
Next steps: add Firewall, logs, CI/CD deploy hooks, and vertical auto-scale when needed.
Web app with database
Use Compose or separate containers in one project. Keep the database private. Attach a persistent volume to the database. Expose only the web/API service. Use HubTunnels for database administration.
Next steps: backup strategy, health checks, storage monitoring, and private env vars.
API with workers and queue
Use Compose when the API, queue, and workers are part of one system. Expose only the API. Keep the queue private. Scale workers manually when queue pressure grows.
Next steps: idempotent jobs, retry strategy, logs by service, and worker replica planning.
Public app with traffic growth
Start with one container. Add a custom domain and Firewall. When traffic grows, create manual replicas and route through a load balancer. Keep deployment and runtime config consistent across replicas.
Next steps: health checks, target weights, rollout discipline, and shared state review.
Internal dashboard
Deploy it without public ingress. Use HubTunnels for access. If it later needs stable team access, add a public endpoint only with strong authentication and Firewall controls.
Next steps: decide whether this should remain private or become a protected public service.
AI or GPU workflow
Use GPU Deployments for notebook or model workloads. Keep model artifacts and important files in durable storage. Bind the GPU to a project when it becomes part of a product workflow.
Next steps: wallet monitoring, disk sizing, reproducible runtime, and cleanup of unused GPU capacity.
How to choose the next step
If you are unsure what to do next, use this guide:
| Current situation | Next step |
|---|---|
| App is not deployed yet | Start with Git, Docker image, template, or Compose based on app shape |
| App deploys but does not run | Check command, port, env vars, logs, and health behavior |
| App runs but is not reachable | Check endpoint, domain, proxy route, SSL, and exposed port |
| App needs a database | Add a private database with a persistent volume |
| You need database access | Use HubTunnels, not a public database endpoint |
| App needs multiple services | Move to Compose or deploy related containers in one project |
| App has public traffic | Add custom domain, SSL, and Firewall |
| App needs more capacity | Identify CPU/RAM vs replica vs dependency pressure |
| App stores important data | Review volumes, backups, and storage growth |
| App becomes business-critical | Document runtime, rollback, access, scaling, and incident steps |
What Hubfly intentionally keeps visible
Hubfly could hide many more choices, but some choices should stay visible because they are operationally important:
- Which port is public
- Which services are private
- Which data is persistent
- Which commands run at build and runtime
- Which domains route to which targets
- Which replicas receive traffic
- Which tunnel reaches which container
- Which GPU is global or project-bound
- Which storage mode is being paid for
This visibility is part of the architecture. It helps teams understand their systems instead of inheriting a black box.
Limitations and tradeoffs
Hubfly abstracts infrastructure, but it does not remove engineering responsibility.
You still need to:
- Understand your app’s runtime requirements.
- Keep secrets safe.
- Design stateful services carefully.
- Choose appropriate storage.
- Avoid exposing private systems publicly.
- Test build and deploy behavior before production changes.
- Monitor cost for always-on services, volumes, replicas, and GPUs.
- Use application-level auth even when networking is private.
The platform gives you better defaults and fewer manual steps, but production still rewards clear thinking.
FAQ
Is Hubfly a PaaS or a container platform?
Hubfly Space behaves like a practical container deployment platform with PaaS-style workflows. You deploy apps from Git, images, templates, Compose, CLI, or GPU templates, while Hubfly handles the surrounding build, runtime, networking, proxy, storage, and access flows.
Do I need to understand Hubcell?
No. Hubcell is the containerization foundation under Hubfly. It is useful context, but you use Hubfly through projects, containers, volumes, endpoints, Compose stacks, tunnels, and GPU workflows.
Should I always use Compose?
No. Use Compose when the app is naturally multi-service. A single web app or worker is usually better as a single container until the system actually needs coordinated services.
Should databases be public?
Usually no. Keep databases private, let application containers connect over the project network, and use HubTunnels for administrative access.
Should I start with scaling?
No. Start by making the service correct and observable. Add scaling after you know whether the pressure is CPU, memory, request concurrency, queue depth, storage, or a dependency bottleneck.
Why does Hubfly separate deploy and expose?
Because running a service and exposing a service are different operational decisions. This reduces accidental public access and makes production networking easier to reason about.