Docker Compose apps from a git repository
You tell Falak that a repository is a Docker Compose app, point it at the compose file in the repository, and decide per service how it runs: inside the stack, public behind Falak’s edge, as a Falak-managed database, or as its own Falak site. Nothing is auto-detected. The repository stays the source of truth: Falak reads the compose files again on every deploy and never edits them.
This guide covers the repository flow. For the Compose runtime itself (rendering, the deploy flow, the security policy, inline files) see Deploy with Docker Compose.
Prerequisites
Section titled “Prerequisites”- A server of type app, web or worker with Docker installed.
- A builder that does Docker builds (a
builderserver), even if no service usesbuild:. Built images go to Falak’s built-in registry. - A git connection. Falak reads files through the provider’s API (GitHub, GitLab, Bitbucket). On a plain git server it can’t read them before a deploy: services are listed after the first deploy, and you add public services in Settings → Compose then.
Create the app
Section titled “Create the app”- + Create → Git repository, then pick the connection, repository and branch.
- Under App type, choose Docker Compose app (instead of One app).
- Compose file: the path in the repository, for example
compose.yamlordocker/compose.prod.yml. Compose files found in the repository are offered as suggestions; Falak never picks one for you. - Optionally Add override file: each one is merged over the files before it, like
docker compose -f a.yaml -f b.yaml. Profiles (comma-separated) choose which profiles run; services of other profiles don’t run. - Falak reads and merges the project like
docker compose config, then shows the Services, the Variables, the Falak adjustments, and any errors or policy violations. - Decide where each service runs (below), fill in the required variables, pick servers and Create. The first deploy starts.
Every choice stays editable afterwards in the service’s Settings → Compose (source, files, profiles, the same services table, variables and adjustments).
The services table
Section titled “The services table”One row per service, with what Falak found: the image or build context, ports and volumes. For each service, choose:
| Choice | What happens |
|---|---|
| In the stack (default) | Runs inside the Compose project, internal only. |
| In the stack, public | Runs in the stack and gets a domain through Falak’s edge. Pick the port (from the service’s ports), a domain (generated, test, custom or a Cloudflare name) and an optional health check path. |
| Falak PostgreSQL / MySQL / MariaDB database | Offered for postgres, mysql and mariadb images. The service leaves the stack and becomes a Falak database. |
| Falak Redis / Valkey | Offered for the official redis and valkey/valkey images. The service leaves the stack and becomes a Falak Redis or Valkey instance. |
| Own Falak service | The service leaves the stack and becomes its own Falak site from the same repository and branch. |
Public services
Section titled “Public services”Falak publishes each public service on 127.0.0.1:<allocated port> and routes its domains to it with HTTPS; other host
ports are not published. The first public service is the site itself (it gets the site’s domains). Every public service
has its own domains and edge settings; see Edge for every public service.
After each deploy Falak requests every public service through its own domains: the health check path you set, or
else the site’s health path for the first service and “any answer below 500” for the others. Public services without a
Docker healthcheck get a warning.
A Falak database
Section titled “A Falak database”Choose Falak PostgreSQL / MySQL / MariaDB database for a database service, and Falak:
- creates a database on the stack’s leader server, named after
POSTGRES_DB,MYSQL_DATABASEorMARIADB_DATABASE(else<slug>_<service>), or links an existing database of the same engine in the same environment; - places it on the canvas next to the stack as “<stack> <service>”, with backups and metrics like any Falak database;
- removes the service from the stack, drops
depends_onon it, and points the variables that used it at the database (see How references are rewritten).
The leader server needs that engine. An app server without one can get it later: see Install an engine on an existing server. The stack’s containers then reach the database through the Docker bridge (agent 0.4.5 or newer); see Containers and databases on the same server.
A Falak Redis or Valkey
Section titled “A Falak Redis or Valkey”Since v0.7.1, a service running the official redis image (also docker.io/library/redis) or valkey/valkey — any tag
or digest — can become a Falak-managed Redis or Valkey instance. Other images
(redis/redis-stack, bitnami/redis, other registries, services built with build:) stay containers. Choose
Falak Redis / Valkey for the service, and Falak:
- creates an instance named
<stack-slug>-<service>(then-2,-3if taken) on the stack’s leader server, with its own port (6380–6479) and password; - reads its settings from the service’s
command:line:--maxmemorybecomes the memory limit (whole MB, at least 16),--maxmemory-policythe eviction policy, and--appendonly yesturns onaofpersistence. The command may be a string or a list starting withredis-server/valkey-serveror with a flag; a shell command or a config file gives the defaults instead; - removes the service from the stack, drops
depends_onon it, and points the variables that used it at the instance (see How references are rewritten).
The stack’s containers then reach the instance through the Docker bridge; see Connecting from containers.
The leader server must already run the image’s engine. Otherwise the service stays in the stack with a warning: the server runs the other cache engine (one cache engine per server), it has none yet (install Redis or Valkey on it first, see Install an engine on an existing server), or Valkey isn’t offered for its OS.
Two cases are left for you to finish, and Falak warns about each:
- TLS URLs.
rediss://andvalkeys://values that point at the service are not rewritten (Falak instances don’t offer TLS), nor are the port and password keys next to them. They keep pointing at the old service name. - Healthchecks. A healthcheck of another service that names the extracted service as a host, such as
redis-cli -h cache ping, is not rewritten — host, port and password flags differ per tool. Update it to use the instance’sREDIS_*values. The same warning applies when a SQL database service is extracted.
Its own Falak site
Section titled “Its own Falak site”Choose Own Falak service, give it a name, and pick what it runs as: Docker (its Dockerfile), Laravel or Node.js. Falak creates a site from the same repository and branch with:
- the service’s build context as its root directory (relative to the compose file; contexts outside the repository and remote contexts are refused);
- the service’s
dockerfileand container port; - the service’s
environment:as variables (${VAR}and${VAR:-default}filled in from the stack’s variables); - the stack’s servers.
You then pick its domain like any site. References to it from the stack become https://<its primary domain> plus the
path.
Docker is the runtime that keeps it connected to the stack: the site joins the stack’s networks
(<stack-slug>_default, or the networks the service was on) on every server the stack runs on, under its service name
plus the aliases it declared. It still reaches postgres, redis and the other services by name, and the stack still
reaches it as before. A container joins at most 8 networks with Docker-safe names; others are left out with a warning.
Splitting a service out needs permission for what it creates: databases.manage for a database, sites.create for a
site. Without it the service stays in the stack, with a warning.
Deploy order for split-out services
Section titled “Deploy order for split-out services”- A split-out Docker site needs the stack’s networks, which exist once the stack has been deployed. Its deploy waits up to 60 seconds for them, then fails with deploy the compose stack it belongs to first, then redeploy this site. A missing network never removes the running container.
- The stack’s deploy stops while one of its split-out sites has never been deployed (an nginx proxying to it would fail to start): <service> now runs as its own Falak site, which hasn’t been deployed yet. Deploy that site first, then this stack.
So split services out of a stack that is already running: deploy the new site, then redeploy the stack.
How references are rewritten
Section titled “How references are rewritten”When a service moves to a Falak database or its own site, Falak finds the variables that pointed at it, in the services that stay and in the stack’s own variables, and rewrites them:
| Before | After |
|---|---|
DATABASE_URL=postgres://u:p@db:5432/app |
${{ <database>.DATABASE_URL }}-style references (resolved at deploy) |
DB_HOST=db, PGHOST=db, db:5432 |
The database’s host, and companion keys (…PORT, …USER, …PASSWORD, …DB / …NAME) |
REDIS_URL=redis://cache:6379/1 |
${{ <instance>.REDIS_URL }}-style reference; the path (/1) is kept, credentials are replaced |
REDIS_HOST=cache, cache:6379 |
The instance’s REDIS_HOST (and REDIS_HOST:REDIS_PORT), plus the …PORT and …PASSWORD keys of the same prefix (REDIS_QUEUE_PORT follows REDIS_QUEUE_HOST) |
API_URL=http://api:8000/v1 |
https://<the site's primary domain>/v1 |
Rewrites are kept per service, so DB_PASSWORD in two services can point at two databases. They follow renames and
domain changes. A driver name such as DB_CONNECTION=mysql is not treated as a host, nor is an image name such as
IMAGE=redis:7.
For Redis and Valkey, a REDIS_HOST that had no REDIS_PORT or REDIS_PASSWORD next to it gains them: clients
default to port 6379 and no password, while a Falak instance listens on its own port and requires its password.
redis:// and valkey:// URLs are rewritten wherever they appear in a value; rediss:// and valkeys:// are not (see
A Falak Redis or Valkey).
Variables
Section titled “Variables”The Variables section lists every ${VAR} the stack uses and every key of its env_files, with the default from
the files. Only ${VAR:?message} and ${VAR?message} are required: the create flow asks for a value before the
first deploy. The values are saved as the service’s variables (encrypted), and may use
references such as ${{ shop-db.DATABASE_URL }}.
Members with view access see the services and the variable names, but not the YAML or the env-file values.
Falak adjustments
Section titled “Falak adjustments”At render time Falak applies a few changes so the project runs well under Falak. Your repository is never changed; Settings → Compose → Falak adjustments lists them with Show the diff (“your project → what Falak runs”).
- Host ports are removed; public services are published on loopback ports.
container_nameis removed (names would clash between environments and during a rollback).restart: unless-stoppedis added where a service sets no restart policy, so the stack comes back after a server reboot. Since v0.7.1 this applies at every deploy to inline stacks too (including ones created through the API); before, inline stacks got no policy and stayedExitedafter a reboot.- Missing bind sources: a bind mount like
./data:/var/lib/datawhose source isn’t in the repository becomes a named volume<service>-<path>, kept across deploys. Tick the mount in the services table to keep an empty folder per release instead. - Repository files ship with each release. Files the project mounts or reads (bind sources,
env_file,configsandsecretswithfile:) are copied from the repository into the release, so./nginx.conf:/etc/nginx/nginx.confworks. This needs agent featurecompose.v2. - Falak’s
.envonly where needed. Anenv_filethe repository lacks is dropped, and only those services get Falak’s.env(every site variable) instead. Other services read site variables through${VAR}interpolation, so third-party images don’t receive unrelated secrets. Mounts and env files naming Falak’s own./.envand./compose.yamlkeep pointing at them. - Services run elsewhere (Falak databases, own sites) are removed with their
depends_on, and their references rewritten.
The security policy stays blocking unless an admin allows privileged compose.
Edge for every public service
Section titled “Edge for every public service”Every public service gets the same edge features as a site. In Settings → Networking, pick the service in the service picker:
- Domains: several per service — generated, test, custom or names under a managed Cloudflare zone — each with
automatic TLS and
wwwredirects. The domain chosen at creation becomes the service’s first domain. - Cloudflare: DNS records, proxy on or off, a cache mode per domain, purge after every deploy and rollback, rate limits per domain, and routing through a Cloudflare Tunnel with no extra setup.
- Routing rules: redirects, basic auth and headers apply to the whole site or to one service. IP lists per service: a service’s allow list replaces the site’s, its deny list adds to it.
- Path mounts: a function’s path can be mounted on one service,
for example
app.example.com/api/*.
When a public service is split into its own site, it takes its domains and rules along (and the site-wide basic auth, headers and IP lists are copied to it).
On the canvas
Section titled “On the canvas”A repository stack is drawn as a group: one card per service with its state, image, public URL and volumes, and
depends_on arrows. A database split out of it is placed next to it. The Services tab lists each service’s
health, image digest, ports, restarts, CPU and memory.
Limits
Section titled “Limits”- Repository files shipped with a release: at most 200 files / 2 MB per release. A compose file read from the repository is at most 1 MB.
- Paths may use any name except
.,..or empty segments, backslashes and control characters. The release’s repository files are written from scratch on every deploy, without following links. includeandextendswork with files from the repository only (no remote includes).- Previews check each referenced path with the provider (at most 100 lookups in 20 seconds).
- On a plain git server (no API), Falak can’t preview the project; services show up after the first deploy.
- Services built with
build:need a Docker builder; managed servers never build.