Skip to content

Configuration

Context variables

Configure your infrastructure in the default context:

#[AsContext(default: true)]
function default_context(): Context
{
    return new Context([
        'root_domain' => 'myproject.test',    // Root domain for all services
        'registry' => 'ghcr.io/org/project',  // Docker registry used for build caching
    ]);
}
Variable Role
root_domain Root domain used by the services exposing a UI (redis.{root_domain}, mailpit.{root_domain}, …)
registry Registry the build cache is pushed to and pulled from
project_name Compose project name — wins over the name: of compose.yaml, see running two checkouts side by side
user_id UID the containers run as, defaults to your own
twig_dockerfile_frontend Overrides the pinned twig-dockerfile frontend
build_args Build arguments castor docker:build passes to every service, also readable as Twig variables
resolve_domains_via_host Whether the containers resolve the project's own public domains, true by default — see below
docker_profiles The compose profiles every task activates by default, ['default'] otherwise
router_autostart Whether docker:up starts the global router and docker:stop stops it, true by default — see below

Resolving your own domains from a container

Every container gets an extra_hosts entry for each domain routed in the project, pointing at the host gateway where the router answers — so https://api.myproject.test works from inside a container as well as from your browser. Set resolve_domains_via_host to false to stop generating them; see router and HTTPS.

Starting and stopping the router with your projects

docker:up starts the global router when the project routes a domain, and docker:stop stops it once no routed container is left running on the machine. Set router_autostart to false to manage it yourself with docker:router:enable and docker:router:disable:

return new Context([
    'router_autostart' => false,
]);

CASTOR_DOCKER_ROUTER_AUTOSTART overrides it for a single command — see router and HTTPS.

Running two checkouts side by side

A git worktree, or a second clone, shares compose.yaml with the first — name: included. Overriding the project name in the context is what keeps the two apart, and everything else follows from it: the containers, the network, the named volumes, the TCP forwarders and the ${PROJECT_NAME}-<service> images a shared builder is referenced by.

#[AsContext(default: true)]
function default_context(): Context
{
    return new Context([
        'project_name' => 'myproject-wt2',
        'root_domain' => 'wt2.myproject.test',
    ]);
}

Two lines, and the second checkout runs beside the first with its own containers and its own domains.

The context wins over the name: of compose.yaml, and the plugin exports COMPOSE_PROJECT_NAME so docker compose uses the same one — otherwise compose would build in one project while the plugin looked for containers, networks and images in another.

Default profiles

docker:up, docker:build and the rest activate the default profile unless you pass --profiles. A project organising its containers differently sets the list once:

return new Context([
    'docker_profiles' => ['default', 'observability'],
]);

Generated files

The plugin generates and manages these files next to your castor.php:

compose.yaml

The entry point, created once and yours to edit. It includes the two files below:

# This is your docker-compose file. It has been generated by Castor, but you can edit it if needed.
name: castor-docker-demo
include:
   - path:
         - compose.generated.yaml # This file is generated you should not remove or edit this line / file.
         - compose.override.yaml # This file is for your local overrides of existing services.

# Here you can also add your own services.

compose.generated.yaml

Regenerated from your castor.php on every Castor run. Never edit it, your changes would be lost.

compose.override.yaml

Never touched by the plugin: put your local customisations here.

# This file is for your local overrides. It is not generated by Castor.
services:
    app:
        environment:
            - CUSTOM_ENV_VAR=value

.home/

The shared home directory, mounted as /home/app in the containers that need it. It holds the caches shared across services — Composer, Cargo.

The mkcert CA is not stored there: the router is global, and keeps it in ~/.castor/docker/router/certs/.

Environment variables

The plugin sets these in the containers it generates:

Variable Value
PHP_VERSION PHP version in use
COMPOSE_PROJECT_NAME Compose project name, so docker compose agrees with the plugin
PROJECT_NAME Compose project name
PROJECT_ROOT_DOMAIN Root domain of the project
REGISTRY Docker registry URL
DATABASE_URL Connection string, when the service is linked to a database
MAILER_DSN Mailpit DSN, when the service is linked to a mailer

And it reads these from your own environment:

Variable Role
CASTOR_DOCKER_ROUTER_AUTOSTART Turns the router autostart on or off for a single command, over the router_autostart context variable
DOCKER_SOCKET_PATH The Docker socket the router watches, before DOCKER_HOST and /var/run/docker.sock — see the socket it watches