You are viewing Nextmv legacy docs. ⚡️ Go to latest docs ⚡️

Deployment

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.

knapsack-cli
├── Dockerfile
├── data
│   └── input-11items.json
├── knapsack-cli
├── go.mod
├── go.sum
└── main.go
Copy

Dockerfile

Create a Dockerfile in the project root that contains the following code.

FROM gcr.io/distroless/static:nonroot
ENV HOP_RUNNER_OUTPUT_SOLUTIONS last
ENV HOP_SOLVER_LIMITS_DURATION 1s
COPY knapsack-cli /
ENTRYPOINT ["/knapsack-cli"]
Copy

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.

package main

import (
    "github.com/nextmv-io/code/hop/run/cli"
    "github.com/nextmv-io/code/engines/pack/knapsack"
)

func main() {
    cli.Run(knapsack.DefaultSolver)
}
Copy

data/input-11items.json

We also need some test data. Put this JSON file in your data directory.

{
  "items": [
    {"item_id": "cat",    "value": 100, "weight": 20},
    {"item_id": "dog",    "value":  20, "weight": 45},
    {"item_id": "water",  "value":  40, "weight":  2},
    {"item_id": "phone",  "value":   6, "weight":  1},
    {"item_id": "book",   "value":  63, "weight": 10},
    {"item_id": "rx",     "value":  81, "weight":  1},
    {"item_id": "tablet", "value":  28, "weight":  8},
    {"item_id": "coat",   "value":  44, "weight":  9},
    {"item_id": "laptop", "value":  51, "weight": 13},
    {"item_id": "keys",   "value":  92, "weight":  1},
    {"item_id": "nuts",   "value":  18, "weight":  4}
  ],
  "capacity": 50
}
Copy

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.

go mod init knapsack-cli
go get ./...
Copy

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:

CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -o knapsack-cli
Copy

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.

docker build -t example-nextmv/knapsack-cli .
Copy

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.

cat data/input-11items.json | docker run -i --rm example-nextmv/knapsack-cli
Copy

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.

docker run --rm -v $PWD/data:/data example-nextmv/knapsack-cli \
    -hop.runner.input.path /data/input-11items.json \
    -hop.runner.output.path /data/output-11items.json
Copy

The Hop model will write an output file to the data/ folder on our local machine.

Page last updated

Go to on-page nav menu