Env placeholders
Features can use placeholders in their .env files that get resolved automatically during product:env --merge. This keeps features generic and decoupled from any specific product.
Table of contents
__PRODUCT__
Replaced with the active product name (SPLENT_APP).
Use case
A feature that needs to reference a product-specific Docker service name. For example, an nginx reverse proxy that must point to the product’s web container:
# Feature .env.example
NGINX_UPSTREAM_HOST=__PRODUCT___web
After product:env --merge in a product named my_first_app:
NGINX_UPSTREAM_HOST=my_first_app_web
Rules
- The replacement happens during
product:env --merge, after feature.envfiles are loaded but before the final merged.envis written. - It applies to values only, not keys.
- It works in combination with port offset — ports are adjusted first, then placeholders are resolved.
- If the product
.envalready defines the variable, the feature value (and its placeholder) is ignored — product values always take precedence.
Merge output
The CLI reports resolved placeholders:
product resolved __PRODUCT__ in 1 variable(s) → my_first_app
ports adjusted 4 feature port(s) (+591)
merged 4 feature .env file(s) into product .env
__FEATURE_HOST_DIR__
Replaced with the host-side absolute path to the feature’s root directory.
Why it exists
Docker Compose runs inside the CLI container where paths start with /workspace/.... But the Docker daemon runs on the host, so volume mounts need host paths. __FEATURE_HOST_DIR__ bridges this gap and resolves correctly for both editable features (workspace root) and pinned features (.splent_cache/).
Use case
A feature that needs to mount local files into its Docker container. For example, nginx mounting its config templates:
# Feature .env.example
NGINX_FEATURE_HOST_DIR=__FEATURE_HOST_DIR__
After product:env --merge:
# Editable feature
NGINX_FEATURE_HOST_DIR=/Users/dev/splent_workspace/splent_feature_nginx
# Pinned feature
NGINX_FEATURE_HOST_DIR=/Users/dev/splent_workspace/.splent_cache/features/splent_io/splent_feature_nginx@v1.0.0
Then in docker-compose.yml:
volumes:
- ${NGINX_FEATURE_HOST_DIR}/docker/nginx/templates/default.dev.conf.template:/etc/nginx/templates/default.conf.template:ro
Rules
- Resolved per feature during merge — each feature’s
.envgets its own correct path. The placeholder is replaced directly in the feature’sdocker/.envfile (not just the merged output) so thatdocker composecan read it when launching the feature’s containers. - Uses
SPLENT_HOST_PROJECT_DIRto convert container paths to host paths. - If
SPLENT_HOST_PROJECT_DIRis not set, falls back to the workspace path (works when running outside Docker).
Dev vs Prod
- Dev (
product:env --merge): resolved to the host-side feature path. Used for bind mounts so you can edit config templates live. - Prod (
product:build): variables containingFEATURE_HOST_DIRare removed from.env.deploy.example. In production, config files are baked into Docker images (viaDockerfile.prod), so bind mounts and host paths are not needed.
Related
product:env --merge— the CLI command that resolves placeholders- Port offset — the other automatic adjustment during merge