When an app is deployed, a runtime is provisioned for it. Runtimes are defined by Docker images. The runtime provides the environment in which the app runs.
These runtimes are provisioned on Linux ARM64 machines in Nextmv.
ghcr.io/nextmv-io/runtime/defaultghcr.io/nextmv-io/runtime/pythonghcr.io/nextmv-io/runtime/javaghcr.io/nextmv-io/runtime/pyomo
The cuopt runtime is provisioned on Linux AMD64 with an attached NVIDIA GPU. It is capable of running models using NVIDIA cuOpt.
You may also pull these images down and use them for local development, for example:
cat input.json | \
docker run --rm -i -v $(pwd):/app ghcr.io/nextmv-io/runtime/python:3.11 \
python main.py
If you need packages that are not already included in a runtime, please contact Nextmv support.
ghcr.io/nextmv-io/runtime/default
This runtime is used to run compiled applications such as Go binaries.
Versions:
ghcr.io/nextmv-io/runtime/default:latest
Languages:
- Go
Dockerfile:
FROM debian:trixie-slim # Set a default working directory. WORKDIR /app # Install certificates. RUN apt update && apt install -y ca-certificates
- Examples of
app.yamlmanifests in community apps that use this runtime:
- go-nextroute (YAML)
- go-highs-knapsack (YAML)
- go-highs-orderfulfillment (YAML)
- go-highs-shiftscheduling (YAML)
# This manifest holds the information the app needs to run on the Nextmv Cloud.
type: go
runtime: ghcr.io/nextmv-io/runtime/default:latest
# Directives to build a Go binary from the app.
build:
command: go build -o main .
environment:
GOOS: linux
GOARCH: arm64
# List all files/directories that should be included in the app. Globbing
# (e.g.: configs/*.json) is supported.
files:
- main
configuration:
options:
strict: false
validation:
enforce: all
items:
# Check options
- name: check.duration
option_type: string
description: "Maximum duration of the check (e.g.: '30s', '5m')"
ui:
control_type: input
display_name: Check Duration
- name: check.verbosity
option_type: string
description: "{off, low, medium, high} verbosity of the check"
additional_attributes:
values:
- "off"
- "low"
- "medium"
- "high"
ui:
control_type: select
display_name: Check Verbosity
# Format options
- name: format.disable.progression
option_type: bool
description: Disable the progression series
ui:
control_type: toggle
display_name: Disable Progression
hidden_from:
- viewer
- operator
# Model constraint disable options
- name: model.constraints.disable.attributes
option_type: bool
description: Ignore the compatibility attributes constraint
ui:
control_type: toggle
display_name: Disable Attributes Constraint
- name: model.constraints.disable.capacities
option_type: string
description: "Ignore the capacity constraint for the given resource names (e.g.: 'weight,volume')"
ui:
control_type: input
display_name: Disable Specific Capacities
- name: model.constraints.disable.capacity
option_type: bool
description: Ignore the capacity constraint for all resources
ui:
control_type: toggle
display_name: Disable All Capacity Constraints
- name: model.constraints.disable.distancelimit
option_type: bool
description: Ignore the distance limit constraint
ui:
control_type: toggle
display_name: Disable Distance Limit
- name: model.constraints.disable.groups
option_type: bool
description: Ignore the groups constraint
ui:
control_type: toggle
display_name: Disable Groups Constraint
- name: model.constraints.disable.maximumduration
option_type: bool
description: Ignore the maximum duration constraint
ui:
control_type: toggle
display_name: Disable Maximum Duration
- name: model.constraints.disable.maximumstops
option_type: bool
description: Ignore the maximum stops constraint
ui:
control_type: toggle
display_name: Disable Maximum Stops
- name: model.constraints.disable.maximumwaitstop
option_type: bool
description: Ignore the maximum stop wait constraint
ui:
control_type: toggle
display_name: Disable Maximum Wait Stop
- name: model.constraints.disable.maximumwaitvehicle
option_type: bool
description: Ignore the maximum vehicle wait constraint
ui:
control_type: toggle
display_name: Disable Maximum Wait Vehicle
- name: model.constraints.disable.mixingitems
option_type: bool
description: Ignore the do not mix items constraint
ui:
control_type: toggle
display_name: Disable Mixing Items
- name: model.constraints.disable.precedence
option_type: bool
description: Ignore the precedence (pickups & deliveries) constraint
ui:
control_type: toggle
display_name: Disable Precedence
- name: model.constraints.disable.starttimewindows
option_type: bool
description: Ignore the start time windows constraint
ui:
control_type: toggle
display_name: Disable Start Time Windows
- name: model.constraints.disable.vehicleendtime
option_type: bool
description: Ignore the vehicle end time constraint
ui:
control_type: toggle
display_name: Disable Vehicle End Time
- name: model.constraints.disable.vehiclestarttime
option_type: bool
description: Ignore the vehicle start time constraint
ui:
control_type: toggle
display_name: Disable Vehicle Start Time
# Model constraint enable options
- name: model.constraints.enable.cluster
option_type: bool
description: Enable the cluster constraint
ui:
control_type: toggle
display_name: Enable Cluster Constraint
# Model objectives
- name: model.objectives.capacities
option_type: string
description: "Capacity objective, provide triple for each resource 'name=default;factor=1.0;offset=0.0'"
ui:
control_type: input
display_name: Capacities Objective
- name: model.objectives.cluster
option_type: float
description: "Factor to weigh the cluster objective (e.g.: 2.0)"
ui:
control_type: input
display_name: Cluster Objective
- name: model.objectives.distance
option_type: float
description: "Factor to weigh the travel distance objective (e.g.: 2.0)"
ui:
control_type: input
display_name: Distance Objective
- name: model.objectives.earlyarrivalpenalty
option_type: float
description: "Factor to weigh the early arrival objective (e.g.: 2.0)"
ui:
control_type: input
display_name: Early Arrival Penalty
- name: model.objectives.latearrivalpenalty
option_type: float
description: "Factor to weigh the late arrival objective (e.g.: 2.0)"
ui:
control_type: input
display_name: Late Arrival Penalty
- name: model.objectives.minstops
option_type: float
description: "Factor to weigh the min stops objective (e.g.: 2.0)"
ui:
control_type: input
display_name: Min Stops Objective
- name: model.objectives.stopbalance
option_type: float
description: "Factor to weigh the stop balance objective (e.g.: 2.0)"
ui:
control_type: input
display_name: Stop Balance Objective
- name: model.objectives.travelduration
option_type: float
description: "Factor to weigh the travel duration objective (e.g.: 2.0)"
ui:
control_type: input
display_name: Travel Duration Objective
- name: model.objectives.unplannedpenalty
option_type: float
description: "Factor to weigh the unplanned objective (e.g.: 2.0)"
ui:
control_type: input
display_name: Unplanned Penalty
- name: model.objectives.vehicleactivationpenalty
option_type: float
description: "Factor to weigh the vehicle activation objective (e.g.: 2.0)"
ui:
control_type: input
display_name: Vehicle Activation Penalty
- name: model.objectives.vehiclesduration
option_type: float
description: "Factor to weigh the vehicles duration objective (e.g.: 2.0)"
ui:
control_type: input
display_name: Vehicles Duration Objective
# Model properties
- name: model.properties.disable.durationgroups
option_type: bool
description: Ignore the durations groups of stops
ui:
control_type: toggle
display_name: Disable Duration Groups
- name: model.properties.disable.durations
option_type: bool
description: Ignore the durations of stops
ui:
control_type: toggle
display_name: Disable Durations
- name: model.properties.disable.initialsolution
option_type: bool
description: Ignore the initial solution
ui:
control_type: toggle
display_name: Disable Initial Solution
- name: model.properties.disable.stopdurationmultipliers
option_type: bool
description: Ignore the stop duration multipliers defined on vehicles
ui:
control_type: toggle
display_name: Disable Stop Duration Multipliers
- name: model.properties.maximumtimehorizon
option_type: int
description: "Maximum time horizon for the model in seconds (e.g.: 604800)"
ui:
control_type: input
display_name: Maximum Time Horizon
hidden_from:
- viewer
- operator
# Model validation
- name: model.validate.disable.resources
option_type: bool
description: Disable the resources validation
ui:
control_type: toggle
display_name: Disable Resources Validation
hidden_from:
- viewer
- operator
- name: model.validate.disable.starttime
option_type: bool
description: Disable the start time validation
ui:
control_type: toggle
display_name: Disable Start Time Validation
hidden_from:
- viewer
- operator
- name: model.validate.enable.matrix
option_type: bool
description: Enable matrix validation
ui:
control_type: toggle
display_name: Enable Matrix Validation
hidden_from:
- viewer
- operator
- name: model.validate.enable.matrixasymmetrytolerance
option_type: int
description: "Percentage of acceptable matrix asymmetry, requires matrix validation enabled (e.g.: 10 - for 10%)"
ui:
control_type: input
display_name: Matrix Asymmetry Tolerance
hidden_from:
- viewer
- operator
# Runner options
- name: runner.input.path
option_type: string
description: The input file path
ui:
control_type: input
display_name: Input Path
hidden_from:
- viewer
- operator
- name: runner.output.path
option_type: string
description: The output file path
ui:
control_type: input
display_name: Output Path
hidden_from:
- viewer
- operator
- name: runner.output.solutions
option_type: string
description: "{all, last} specifies whether to output all solutions or only the last one"
additional_attributes:
values:
- "all"
- "last"
ui:
control_type: select
display_name: Output Solutions
hidden_from:
- viewer
- operator
- name: runner.profile.cpu
option_type: string
description: The CPU profile file path
ui:
control_type: input
display_name: CPU Profile Path
hidden_from:
- viewer
- operator
- name: runner.profile.memory
option_type: string
description: The memory profile file path
ui:
control_type: input
display_name: Memory Profile Path
hidden_from:
- viewer
- operator
# Solve options
- name: solve.duration
option_type: string
description: "Maximum duration of the solver (e.g.: '30s', '5m')"
ui:
control_type: input
display_name: Solve Duration
- name: solve.iterations
option_type: int
description: "Maximum number of iterations, -1 assumes no limit; iterations are counted after start solutions are generated (e.g.: 100000)"
ui:
control_type: input
display_name: Solve Iterations
hidden_from:
- viewer
- operator
- name: solve.parallelruns
option_type: int
description: "Maximum number of parallel runs, -1 results in using all available resources (e.g.: 4)"
ui:
control_type: input
display_name: Parallel Runs
hidden_from:
- viewer
- operator
- name: solve.plateau.absolutethreshold
option_type: float
description: "Absolute threshold for significant improvement (e.g.: 1000.0)"
ui:
control_type: input
display_name: Plateau Absolute Threshold
- name: solve.plateau.delay
option_type: string
description: "Delay before plateau detection starts (e.g.: '30s', '5m')"
ui:
control_type: input
display_name: Plateau Delay
- name: solve.plateau.duration
option_type: string
description: "Maximum duration without (significant) improvement before solver stops itself (e.g.: '30s', '5m')"
ui:
control_type: input
display_name: Plateau Duration
- name: solve.plateau.iterations
option_type: int
description: "Maximum number of iterations without (significant) improvement before solver stops itself (e.g.: 10000)"
ui:
control_type: input
display_name: Plateau Iterations
- name: solve.plateau.relativethreshold
option_type: float
description: "Relative threshold for significant improvement (e.g.: 0.01 for 1%)"
ui:
control_type: input
display_name: Plateau Relative Threshold
- name: solve.rundeterministically
option_type: bool
description: Run the parallel solver deterministically
ui:
control_type: toggle
display_name: Run Deterministically
hidden_from:
- viewer
- operator
- name: solve.solver.plangroupsize.delta
option_type: int
description: "Delta is the initial change in value after a number of iterations without improvement (e.g.: 0). This is used to adjust the group size of the plan operator during solving."
ui:
control_type: input
display_name: Plan Group Size Delta
hidden_from:
- viewer
- operator
- name: solve.solver.plangroupsize.deltaafteriterations
option_type: int
description: "Number of iterations without improvement after which the value is changed (e.g.: 1000000000). This is used to adjust the group size of the plan operator during solving."
ui:
control_type: input
display_name: Plan Group Size Delta After Iterations
hidden_from:
- viewer
- operator
- name: solve.solver.plangroupsize.maxvalue
option_type: int
description: "Maximum value for the group size (e.g.: 2). This is used to adjust the group size of the plan operator during solving."
ui:
control_type: input
display_name: Plan Group Size Max Value
hidden_from:
- viewer
- operator
- name: solve.solver.plangroupsize.minvalue
option_type: int
description: "Minimum value for the group size (e.g.: 2). This is used to adjust the group size of the plan operator during solving."
ui:
control_type: input
display_name: Plan Group Size Min Value
hidden_from:
- viewer
- operator
- name: solve.solver.plangroupsize.snapbackafterimprovement
option_type: bool
description: "Snap back to the start value after an improvement is found. This is used to adjust the group size of the plan operator during solving."
ui:
control_type: toggle
display_name: Plan Group Size Snap Back After Improvement
hidden_from:
- viewer
- operator
- name: solve.solver.plangroupsize.startvalue
option_type: int
description: "Starting value for the group size (e.g.: 2). This is used to adjust the group size of the plan operator during solving."
ui:
control_type: input
display_name: Plan Group Size Start Value
hidden_from:
- viewer
- operator
- name: solve.solver.plangroupsize.zigzag
option_type: bool
description: "Zigzag is a flag that indicates if the value should zigzag between the min and max value. This is used to adjust the group size of the plan operator during solving."
ui:
control_type: toggle
display_name: Plan Group Size Zigzag
hidden_from:
- viewer
- operator
- name: solve.solver.unplanunits.delta
option_type: int
description: "Delta is the initial change in value after a number of iterations without improvement (e.g.: 2). This is used to adjust the number of units for the unplan operator during solving."
ui:
control_type: input
display_name: Unplan Units Delta
hidden_from:
- viewer
- operator
- name: solve.solver.unplanunits.deltaafteriterations
option_type: int
description: "Number of iterations without improvement after which the value is changed (e.g.: 125). This is used to adjust the number of units for the unplan operator during solving."
ui:
control_type: input
display_name: Unplan Units Delta After Iterations
hidden_from:
- viewer
- operator
- name: solve.solver.unplanunits.maxvalue
option_type: int
description: "Maximum value for the number of units (e.g.: -1). This is used to adjust the number of units for the unplan operator during solving. -1 auto-configures to a fraction of the total number of stops."
ui:
control_type: input
display_name: Unplan Units Max Value
hidden_from:
- viewer
- operator
- name: solve.solver.unplanunits.minvalue
option_type: int
description: "Minimum value for the number of units (e.g.: 2). This is used to adjust the number of units for the unplan operator during solving."
ui:
control_type: input
display_name: Unplan Units Min Value
hidden_from:
- viewer
- operator
- name: solve.solver.unplanunits.snapbackafterimprovement
option_type: bool
description: "Snap back to the start value after an improvement is found. This is used to adjust the number of units for the unplan operator during solving."
ui:
control_type: toggle
display_name: Unplan Units Snap Back After Improvement
hidden_from:
- viewer
- operator
- name: solve.solver.unplanunits.startvalue
option_type: int
description: "Starting value for the number of units (e.g.: 2). This is used to adjust the number of units for the unplan operator during solving."
ui:
control_type: input
display_name: Unplan Units Start Value
hidden_from:
- viewer
- operator
- name: solve.solver.unplanunits.zigzag
option_type: bool
description: "Zigzag is a flag that indicates if the value should zigzag between the min and max value. This is used to adjust the number of units for the unplan operator during solving."
ui:
control_type: toggle
display_name: Unplan Units Zigzag
hidden_from:
- viewer
- operator
- name: solve.solver.unplanweights
option_type: string
description: "Comma separated list of weights for unplanning strategies (e.g.: 'Vehicle:3,Island:1,Location:300')"
ui:
control_type: input
display_name: Unplan Weights
hidden_from:
- viewer
- operator
- name: solve.startsolutions
option_type: int
description: "Number of solutions to generate on top of those passed in; one solution generated with sweep algorithm, the rest generated randomly (e.g.: 5)"
ui:
control_type: input
display_name: Start Solutions
hidden_from:
- viewer
- operator
# Specify the format the app reads and writes.
content:
format: "json" # Read JSON from stdin and write JSON to stdout.
ghcr.io/nextmv-io/runtime/python
This runtime is used as the basis for other Python runtimes.
Versions:
ghcr.io/nextmv-io/runtime/python:3.11
Languages:
- Python
Dockerfile:
- Examples of
app.yamlmanifests in community apps that use this runtime:
- python-hello-worldbasic (YAML)
- python-ampl-knapsack (YAML)
- python-gurobi-knapsack (YAML)
- python-ortools-knapsack (YAML)
# This manifest holds the information the app needs to run on the Nextmv Cloud.
type: python
runtime: ghcr.io/nextmv-io/runtime/python:3.11
python:
# All listed packages will get bundled with the app.
pip-requirements: requirements.txt
# List all files/directories that should be included in the app. Globbing
# (e.g.: configs/*.json) is supported.
files:
- main.py
- visuals.py
configuration:
# Specify the format the app reads and writes.
content:
format: "json" # Read JSON from stdin and write JSON to stdout.
ghcr.io/nextmv-io/runtime/java
This runtime is used to run Java applications.
Versions:
ghcr.io/nextmv-io/runtime/java:latest
Languages:
- Java
Dockerfile:
FROM eclipse-temurin:21-jdk-noble # Define some default paths for dynamic libraries ENV LD_LIBRARY_PATH=.:./lib # Define a default location for a gurobi license file ENV GRB_LICENSE_FILE=./gurobi.lic # Set a default working directory WORKDIR /app
- Examples of
app.yamlmanifests in community apps that use this runtime:
# This manifest holds the information the app needs to run on the Nextmv Cloud.
type: java
runtime: ghcr.io/nextmv-io/runtime/java:latest
# Directives to compile a binary from the app.
pre-push: mvn package
# List all files/directories that should be included in the app. Globbing
# (e.g.: configs/*.json) is supported.
files:
- main.jar
configuration:
# Specify the format the app reads and writes.
content:
format: "json" # Read JSON from stdin and write JSON to stdout.
ghcr.io/nextmv-io/runtime/pyomo
This runtime provisions Python packages to run Pyomo applications. It also installs solvers, such as GLPK and CBC.
Versions:
ghcr.io/nextmv-io/runtime/pyomo:latest
Languages:
- Python
Dockerfile:
FROM python:3.11-slim
# Set a default working directory.
WORKDIR /app
# Update the package list.
RUN apt-get update
# Install cbc solver.
RUN apt-get install -y \
coinor-cbc \
coinor-libcbc-dev
# Install glpk solver.
RUN apt-get install -y glpk-utils
# Install SCIP solver.
## Install requirements.
RUN apt-get install -y \
wget \
gcc \
g++ \
gfortran \
liblapack3 \
libtbb12 \
libcliquer1 \
libopenblas-dev \
libgsl28 \
patchelf \
cmake \
wget \
m4 \
xz-utils \
libgmp-dev \
unzip \
zlib1g-dev \
libboost-program-options-dev \
libboost-serialization-dev \
libboost-regex-dev \
libboost-iostreams-dev \
libtbb-dev \
libreadline-dev \
pkg-config \
git \
liblapack-dev \
libgsl-dev \
flex \
bison \
libcliquer-dev \
gfortran \
file \
dpkg-dev \
libopenblas-dev \
rpm
## Download the source code.
ENV SCIP_VERSION=9.1.1
ENV SCIP_DIR=scip-\${SCIP_VERSION}
ENV SCIP_TAR=\${SCIP_DIR}.tgz
RUN wget https://scipopt.org/download/release/\${SCIP_TAR}
## Install the SCIP solver (https://www.scipopt.org/doc/html/md_INSTALL.php).
RUN tar xvzf \${SCIP_TAR} && \
cd \${SCIP_DIR} && \
mkdir build && \
cd build && \
ls -lah && \
cmake .. -DAUTOBUILD=on -DCMAKE_INSTALL_PREFIX=/usr && \
make && \
make check && \
make install && \
cp -r bin/* /usr/bin && \
cp -r lib/* /usr/lib
# Install requirements.
COPY requirements.txt .
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
# Clean up.
RUN rm \${SCIP_TAR}
RUN rm -rf \${SCIP_DIR}
requirements.txtinstalled in the runtime:
- Examples of
app.yamlmanifests in community apps that use this runtime:
# This manifest holds the information the app needs to run on the Nextmv Cloud.
type: python
runtime: ghcr.io/nextmv-io/runtime/pyomo:latest
# List all files/directories that should be included in the app. Globbing
# (e.g.: configs/*.json) is supported.
files:
- main.py
python:
# Packages the app depends on need to be listed in a requirements.txt file
# that is referenced here. All listed packages will get bundled with the app.
pip-requirements: requirements.txt
configuration:
# Specify the format the app reads and writes.
content:
format: "json" # Read JSON from stdin and write JSON to stdout.
ghcr.io/nextmv-io/runtime/cuopt
This runtime is contains Python, CUDA libraries, and NVIDIA cuOpt.
Versions:
ghcr.io/nextmv-io/runtime/cuopt:latest
Languages:
- Python
Dockerfile:
FROM nvidia/cuopt:25.10.0a-cuda12.9-py3.12 # python3 should be python3.12, not python3.10 RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 312 # Set a default working directory WORKDIR /app
- Examples of
app.yamlmanifests in community apps that use this runtime:
# This manifest holds the information the app needs to run on the Nextmv Cloud.
type: python
runtime: ghcr.io/nextmv-io/runtime/cuopt:latest
python:
# All listed packages will get bundled with the app.
pip-requirements: requirements.txt
arch: amd64 # Nextmv Cloud runs cuOpt models on amd64 instances.
version: 3.12 # The cuOpt image uses Python 3.12.
# List all files/directories that should be included in the app. Globbing
# (e.g.: configs/*.json) is supported.
files:
- main.py
- visual.py
configuration:
# Specify the format the app reads and writes.
content:
format: "json" # Read JSON from stdin and write JSON to stdout.