product:build

Build deployment artifacts (.env.deploy.example and docker-compose.deploy.yml) by merging the product and its features.


Usage

splent product:build [--no-image]

Options

Option Description
--no-image Skip building the Docker image. Only generate the compose and env files.

Pre-flight checks

Before generating any artifacts, product:build runs a 4-phase pre-flight sequence:

Phase Name What it validates Runs when
0 pyproject sanity Duplicate features across features/features_dev/features_prod, inconsistent namespaces (splent_io vs splent-io), and SPL existence ([tool.splent].spl or legacy [tool.splent.uvl]). Always
1 SAT The feature selection is satisfiable under the UVL variability model. Always
2 Contracts No ERROR-level conflicts between the contracts of the declared features (route or blueprint name collisions). Always
3 PyPI All prod features are versioned and published on PyPI. Editable (non-versioned) features trigger a warning since they cannot be installed from PyPI during the Docker build. Build mode only

Phase 0 aborts early if it fails – later phases are skipped. If any other phase fails, the build is also aborted. Use --skip-preflight (internal flag, used by product:derive to avoid double-checking) to bypass.


Description

This command generates two deployment-oriented files inside the product docker/ directory:

  1. .env.deploy.example
    Merges environment variables from:
    • the product (.env.prod.example preferred, otherwise .env.example)
    • all feature docker directories (.env.prod.example preferred, otherwise .env.example)

    When merging, later values override earlier ones (features can override product keys).

    Additional processing:

    • Removes FEATURE_HOST_DIR variables — these reference host paths that do not exist in production (templates are baked into images or copied into docker/features/).
    • Forces SPLENT_ENV=prod in the output.
    • Resolves __PRODUCT__ placeholders to the actual product name.
    • Applies port offset to feature port variables (same logic as product:env --merge).
  2. docker-compose.deploy.yml Merges Compose definitions from:
    • the product (docker-compose.prod.yml preferred, otherwise docker-compose.yml)
    • all feature docker directories (docker-compose.prod.yml preferred, otherwise docker-compose.yml)

    When merging:

    • services: product overrides same-named feature services. A warning is shown when a feature service name collides with an existing one.
    • networks and volumes: dictionaries are merged
    • Port conflicts: the command warns if two services expose the same host port in the merged compose file.

Feature Dockerfiles and supporting assets

Before merging compose files, product:build processes each feature’s docker/ directory:

  1. Copies Dockerfiles — for features with build: directives, the Dockerfile (and any supporting files in the feature’s docker/ directory, excluding compose and .env files) is copied to <product>/docker/features/<service>/.
  2. Copies supporting assets — for all features with a docker/ directory (even those without a custom Dockerfile), supporting files such as config templates and scripts are copied to docker/features/<service>/. This ensures files needed by bind mounts (e.g., nginx templates) are available in the deploy artifact.
  3. Rewrites bind mounts — volume mounts that reference ${*FEATURE_HOST_DIR} are rewritten to use host-side absolute paths pointing to the product’s docker/features/ directory.
  4. Rewrites build: directives — the build context is updated to point to the copied location in docker/features/.
  5. Injects .env.deploy volume mount — the web service ({product}_web) receives a read-only bind mount for .env.deploy so the entrypoint can sync deploy variables.

The result is a single deploy-ready compose file and a single deploy-ready env template.


Output files

Created under:

<product>/docker/

Files:

  • .env.deploy.example
  • docker-compose.deploy.yml

Requirements

  • A product must be selected (SPLENT_APP set).
  • The product must include a docker/ directory.
  • Features are read from pyproject.toml (not from filesystem glob). Only features declared in [tool.splent].features are included in the build.

Back to top

splent. Distributed by an LGPL license v3. Contact us: drorganvidez@us.es