Run a solution with Docker Compose#

SAF solutions can run as containerized services using Docker Compose. Every SAF solution generated via saf new includes pre-configured Compose files in the deployments/ directory:

deployments/
├── standalone/
│   └── compose.yaml           # Solution only
├── standalone-with-hps/
│   └── compose.yaml           # Solution + HPS
└── distributed-deployment-template/
    └── compose.yaml           # Solution + HPS + Web Portal

Container deployment prerequisites#

Prerequisite

Description

WSL (Windows only)

WSL

Virtualization

Docker Desktop (requires a license) or Docker Engine (open-source)

Environment variables

Set MACHINE_IP with the IP address of your machine if you use Docker Desktop or the IP address of your WSL if you use WSL.

Standalone deployment#

Purpose:

Development and testing environment for the solution in isolation.

Description:

The standalone deployment is designed for developers to verify that the solution works properly in containerized mode. It starts only the core services of the solution without external dependencies.

Services included:

  • PostgreSQL database

  • Solution REST API (SAF GLOW)

  • Solution UI (Dash framework, if configured)

  • OpenTelemetry dashboard for observability

Usage:

This deployment is not meant for production but is ideal for:

  • Developing and testing solutions locally

  • Verifying solution functionality in containers

  • Debugging solution-specific issues

Run the solution#

  1. Navigate to the solution root directory.

  2. Start the services (wait for all services to start):

    docker compose -f deployments/standalone/compose.yaml up --build
    
  3. Open a web page and reach the GLOW API Swagger UI: http://localhost:8000/docs

  4. Create a project using the Create Project POST request.

  5. Copy the project name from the response. It should look like: projects/<project-id>

  6. Open the Solution UI: http://localhost:8001/projects/<project-id>

Now you can walk through the solution workflow.

Shut down the solution#

To shut down the solution:

  1. Press CTRL+C in the terminal where you executed the previous Docker command, or

  2. Turn the Docker containers down:

    docker compose -f deployments/standalone/compose.yaml down
    

Standalone deployment with HPS#

Purpose:

Development environment that includes HPS (HPC Platform Services) integration.

Description:

This deployment extends the standalone setup by adding HPS components to the landscape. It helps developers debug the connection between HPS and SAF.

Services included:

  • All services from standalone deployment

  • Integration with external HPS network

  • Traefik labels for external routing

Prerequisites:

  • HPS must be started first and running.

  • EXT_NETWORK_NAME environment variable must be set to match the HPS external network.

Usage:

This deployment is not meant for production but is ideal for:

  • Testing HPS integration

  • Debugging communication between SAF and HPS

  • Validating solution behavior with HPS services

Run the solution#

  1. Ensure that HPS is running.

  2. Set the external network name:

    export EXT_NETWORK_NAME=<hps-network-name>
    
  3. Navigate to the solution root directory.

  4. Start the services (wait for all services to start):

    docker compose -f deployments/standalone-with-hps/compose.yaml up --build
    
  5. Access the solution API and UI as described in the Standalone deployment instructions (points 3 to 6).

Shut down the solution#

  1. Press CTRL+C in the terminal where you executed the previous Docker command, or

  2. Turn the Docker containers down:

    docker compose -f deployments/standalone-with-hps/compose.yaml down
    

Platform-specific dependencies configuration#

The deployments/Dockerfile supports platform-specific dependencies using Poetry extras and build arguments.

How to use:

  • By default, the Dockerfile installs only the base dependencies.

  • To install platform-specific dependencies (for example: HPS, Minerva, Dash), pass the EXTRAS build argument when building the container, separated by commas.

Examples:

docker compose build --build-arg EXTRAS="hps,pim,minerva"
solution-api:
  build:
    context: ../../
    dockerfile: deployments/Docker/Dockerfile
    args:
      EXTRAS: "hps,pim,minerva"

Development workflow#

All Compose files support Docker Compose watch mode for hot-reloading during development:

docker compose up --build --watch

This automatically syncs and restarts containers when you modify source files in the solution/ or ui/ directories.

Stop services#

To stop and remove all containers:

docker compose down

To also remove persistent volumes (database data, project files):

docker compose down -v

Release a new solution version#

When you release a new version of an existing solution, two files must be updated — no changes to the Compose files themselves are required.

  1. Update pyproject.toml:

    Bump the version field in your solution’s pyproject.toml to the new release version:

    [tool.poetry]
    name    = "my-solution"
    version = "1.1.0"   # <-- update this
    
  2. Update the .env file for each deployment template:

    Each deployment template has its own .env file, as shown in the following table. Update APP_NAME in every .env file you intend to use.

    Deployment template

    Path to the .env file

    Standalone

    deployments/standalone/.env

    Standalone with HPS

    deployments/standalone-with-hps/.env

    Distributed deployment

    deployments/distributed-deployment-template/.env

    Note

    The APP_NAME should follow the same pattern as the value generated by saf new:

    <solution-package-name>_<version-with-dashes>. The version is taken from pyproject.toml, with dots replaced by dashes (for example, 1.1.0 becomes 1-1-0).

    In each of those files, update APP_NAME to reflect the new version:

    # Docker resource name (derived from the pyproject.toml version; replace dots with dashes)
    APP_NAME=my-solution_1-1-0
    

    Note

    The APP_NAME environment variable is used to name all Docker resources (networks, volumes, and images such as ${APP_NAME}-api and ${APP_NAME}-ui). Embedding the version in APP_NAME ensures that each release produces uniquely tagged artefacts and avoids conflicts with previously deployed containers.

  3. Rebuild and restart the services:

    After saving both files, rebuild the images and restart the services:

    docker compose -f deployments/<template>/compose.yaml up --build