Isolation
How Alaf Server keeps deployments and projects apart — separate containers, per-project networks and volumes, and enforced resource limits.
Think of your Alaf Server server like an apartment building. Every app you deploy gets its own unit: its own front door, its own electricity meter, its own mailbox. Neighbors can't wander into your unit, and one noisy tenant can't drain the whole building's power. This page explains the walls Alaf Server puts up between your apps — what each one is, and how strong it is on each runtime.
Scoping comes first
Before anything runs, access is decided by organization (a workspace that owns projects) and project. Every API request passes through one permission check, and an organization id from the client is only trusted if you're actually a member. So one team can never list, deploy, or tear down another team's projects. That control-plane boundary is covered in the permission model; the rest of this page is about the walls between apps at runtime, once a deploy is live.
Everything Alaf Server creates on a host is stamped with the project and deployment it belongs to, using Docker labels (key/value tags attached to a container):
alaf server.project— which project owns it.alaf server.deployment— which specific deploy created it.alaf server.service— which service, for multi-service (compose) projects.alaf server.build— which build session produced a build image, so half-finished build artifacts can be reclaimed too.
These labels are how Alaf Server reliably finds and cleans up only its own resources — for example, reclaiming a leftover container from a deploy that failed halfway, without touching anything else on the machine.
One container per deployment
On the Docker runtime, each deployment runs inside its own container — a sandboxed box with its own filesystem, processes, and network view, isolated from the host and from other containers by the Linux kernel. Containers are named predictably so two never collide:
| What | Name pattern |
|---|---|
| Single-app deployment | alaf server-<project>-<deployment> |
| A service in a compose project | alaf server-<slug>-<service> |
| Project network | alaf server-<slug> |
| Project-scoped named volume | alaf server-<slug>-<name> |
A single-app container publishes on a random host port, and Alaf Server's built-in router (OpenResty, an nginx-based reverse proxy) forwards traffic to it — so nothing is exposed on a predictable port that another app could clash with.
Per-project networks
For a project with multiple services (say a web app plus a database), Alaf Server creates one private bridge network — a virtual LAN that only the containers attached to it can use — named alaf server-<slug>. Every service in that project joins it and can reach the others by service name, like http://database:5432.
Because each project gets its own network, a service in one project cannot address a service in another by name. And a service only opens a port to the outside world if it explicitly asks to — otherwise it's reachable only by its siblings inside the project network.
Names are project-private
Two different projects can both have a service called api or db without any conflict — each name resolves only inside its own project's network.
Per-project volumes
A named volume is a managed disk that Docker keeps around between restarts (databases use them so data survives a redeploy). The catch: if two projects both ask for a volume literally named postgres_data, plain Docker hands them the same disk — silent cross-project data mixing.
Alaf Server prevents this by prefixing every named volume with the project: alaf server-<slug>-<name>. Two projects that both declare postgres_data get two separate disks that can never touch. Bind mounts (a specific host path you chose) and anonymous volumes are left exactly as written.
Older services and name clashes
Services created before volume-scoping keep their original bare volume names. To protect them, Alaf Server refuses to deploy a new project whose volume name is already in use by another project's container, and tells you to rename it — so no deploy can quietly adopt another project's data.
Resource limits
Each deployment is given a budget so one app can't starve the others. A budget has three parts:
- CPU (
cpuCores) — fractional cores, e.g.0.5,1,2. - Memory (
memoryMb) — a hard ceiling in megabytes. - Disk (
diskMb) — writable disk in megabytes.
Defaults for a running app are 1 core, 512 MB memory, and 5 GB disk. Builds get a bigger budget (up to 4 cores and 8 GB) because bundlers are memory-hungry, then the running app drops back to its production size. You can change a project's budget from its settings, within these ranges: CPU 0.25–4, memory 128–8192 MB, disk 64–204800 MB.
Screenshot
How strictly the budget is enforced depends on the runtime. On Docker, memory is a hard cap — cross it and the container is killed and restarted — while CPU is a relative weight: under contention a 2-core app gets roughly twice the CPU time of a 1-core one, but an idle machine lets either use what's free.
How the runtimes compare
Alaf Server can run your app three ways, and the isolation strength differs. Pick the tab that matches where you deploy.
The strongest isolation. Every deployment is its own container with:
- kernel-level separation from the host and other apps,
- a hard memory cap and a CPU weight, and
- a random published port fronted by the router — never a fixed port another app could grab.
Multi-service (compose) projects add a private per-project network and project-scoped named volumes on top of that. This is the recommended runtime whenever Docker is available.
For hosts without Docker, Alaf Server runs your app directly as a process on the machine, supervised by systemd (Linux) or a lightweight nohup fallback (macOS). Each deployment gets its own release directory and its own supervised process (on Linux, a dedicated systemd unit named alaf server-<deployment>.service).
This is lighter, but the walls are thinner: processes share the host's filesystem, network, and users, and this mode does not enforce CPU or memory caps. systemd additionally gives you automatic restart-on-crash and reboot survival; the nohup fallback does not.
Weaker isolation without Docker
Because bare processes share the host and aren't resource-capped, run only apps you trust on a shared bare host, and prefer the Docker runtime for anything multi-tenant.
On Alaf Server Cloud, each deployment runs in its own isolated cloud workspace — a separate instance, not a shared box. You choose a size tier that maps to concrete CPU / memory / disk:
| Tier | CPU | Memory | Disk |
|---|---|---|---|
| micro | 0.25 | 256 MB | 4 GB |
| low | 0.5 | 512 MB | 8 GB |
| medium | 1 | 1 GB | 16 GB |
| high | 2 | 2 GB | 32 GB |
A custom tier lets you set exact values. See the local ↔ cloud boundary for how cloud and self-hosted stay separated.
What next?
Permissions & roles
How Alaf Server decides who can do what — organizations, the four roles, and per-resource grants, all enforced by one permission plane.
Cloud boundary
How a self-hosted instance talks to Alaf Server Cloud without leaking local identity — proxied requests carry the owner's cloud session and nothing else.