Deploy to Docker (CLI Runner)
Overview of deploying to docker with the CLI runner.
Nextmv engines and apps are capable of being deployed to Docker containers. The following recipe demonstrates building and deploying our Knapsack engine into a Docker container using the CLI runner.

Files

This recipe can be built in any directory. We use knapsack-cli as the top level folder. We will create the following files.
Bash
1
knapsack-cli
2
├── Dockerfile
3
├── data
4
│ └── input-11items.json
5
├── knapsack-cli
6
├── go.mod
7
├── go.sum
8
└── main.go
Copied!

Dockerfile

Create a Dockerfile in the project root that contains the following code.
Dockerfile
1
FROM gcr.io/distroless/static:nonroot
2
ENV HOP_RUNNER_OUTPUT_SOLUTIONS last
3
ENV HOP_SOLVER_LIMITS_DURATION 1s
4
COPY knapsack-cli /
5
ENTRYPOINT ["/knapsack-cli"]
Copied!
We use a "distroless" base Docker image. We set environment variables in the image to limit model runtime and to print only the last solution to standard out.
More configuration options can be found in the Environment Variables and CLI Options section of our docs. The COPY command copies the executable from our local machine to the Docker image. The ENTRYPOINT configures our container as an executable that accepts input parameters.

main.go

Within the model's main.go file, import the CLI runner and call it in the main() function.
Go
1
package main
2
3
import (
4
"github.com/nextmv-io/code/hop/run/cli"
5
"github.com/nextmv-io/code/engines/pack/knapsack"
6
)
7
8
func main() {
9
cli.Run(knapsack.DefaultSolver)
10
}
Copied!

data/input-11items.json

We also need some test data. Put this JSON file in your data directory.
JSON
1
{
2
"items": [
3
{"item_id": "cat", "value": 100, "weight": 20},
4
{"item_id": "dog", "value": 20, "weight": 45},
5
{"item_id": "water", "value": 40, "weight": 2},
6
{"item_id": "phone", "value": 6, "weight": 1},
7
{"item_id": "book", "value": 63, "weight": 10},
8
{"item_id": "rx", "value": 81, "weight": 1},
9
{"item_id": "tablet", "value": 28, "weight": 8},
10
{"item_id": "coat", "value": 44, "weight": 9},
11
{"item_id": "laptop", "value": 51, "weight": 13},
12
{"item_id": "keys", "value": 92, "weight": 1},
13
{"item_id": "nuts", "value": 18, "weight": 4}
14
],
15
"capacity": 50
16
}
Copied!

Docker

Now we'll build a Docker image with the knapsack solver and run it inside a Docker container.

Building a binary executable

To download and install the packages needed to build our binary we run the following commands at the root of the project.
Bash
1
go mod init knapsack-cli
2
go get ./...
Copied!
First, we create a go.mod file which defines the import path of the current Go module as well as other dependencies. This is done by running the command go mod init on the root of the project. Next, run go get ./.... You'll notice that a go.sum file is created on the project's root. This contains a list of hashes associated to each package to ensure the same files are used for each build.
To build our executable we then run the following commands:
Bash
1
CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -o knapsack-cli
Copied!
Here, we set environment variables so Go cross compiles the binary for a Linux operating system. The go build command builds an executable from the model's main.go file.

Building a Docker image

To build a Docker image, run the following command from the the root of the project.
Bash
1
docker build -t example-nextmv/knapsack-cli .
Copied!
docker build constructs a Docker image based on the contents of our Dockerfile. Note that the image is automatically tagged with latest. If we want to version the image, we add a tag to the build command.

Running a Docker container

At this point our Docker image is ready to run. Enter the following command in the terminal.
Bash
1
cat data/input-11items.json | docker run -i --rm example-nextmv/knapsack-cli
Copied!
Using the -i flag lets Docker read piped data from the host. The container prints output to standard out. The --rm flag cleans up the container after it finishes execution.

Mounting a volume

The following command mounts the data/ directory of our host machine to the /data/ directory in the Docker container. Using this flag allows the Docker container to access input and write output files on the host machine.
Bash
1
docker run --rm -v $PWD/data:/data example-nextmv/knapsack-cli \
2
-hop.runner.input.path /data/input-11items.json \
3
-hop.runner.output.path /data/output-11items.json
Copied!
The Hop model will write an output file to the data/ folder on our local machine.
Export as PDF
Copy link
Contents
Files
Docker