Part 4: Deploy a Module | Viam Documentation
Part 4: Deploy a Module
Goal: Deploy your inspector to run on the machine autonomously.
Skills: Module packaging, registry deployment, tabular data capture.
Time: ~10 min
What You’ll Do
In Part 3, you built inspection logic that runs from your laptop. That’s great for development, but in production the code needs to run on the machine itself—so it works even when your laptop is closed.
The module generator already created most of what you need:
cmd/module/main.go—module entry pointmeta.json—registry metadata- Model registration in
init()
You just need to build, package, and deploy.
4.1 Review the Generated Module Structure
The generator already created everything needed to run as a module. Let’s review what’s there.
cmd/module/main.go
func main() {
module.ModularMain(
resource.APIModel{API: generic.API, Model: inspectionmodule.Inspector},
)
}
This connects your module to viam-server and registers the inspector model. When you add this service to your machine configuration, viam-server uses this entry point to create and manage instances. You don’t need to modify it.
What is a model?
In Viam, a model is a specific implementation of an API—identified by a triplet like your-namespace:inspection-module:inspector. This can be confusing because we also refer to ML models as “models.” When you see “model” in the context of modules and resources, it means the implementation type, not a machine learning model.
module.go provides model registration in init():
var Inspector = resource.NewModel("your-namespace", "inspection-module", "inspector")
func init() {
resource.RegisterService(generic.API, Inspector,
resource.Registration[resource.Resource, *Config] {
Constructor: newInspectionModuleInspector,
},
)
}
Note the two uses of “inspector” here:
Inspector(capital I)—the Go variable name, exported somain.gocan reference it- "inspector" (lowercase, in quotes)—a string that becomes the third part of the model triplet
your-namespace:inspection-module:inspector
This init() function runs automatically when the module starts, telling viam-server how to create instances of your service.
meta.json Registry metadata:
{
"module_id": "your-namespace:inspection-module",
"visibility": "private",
"models": [
{
"api": "rdk:service:generic",
"model": "your-namespace:inspection-module:inspector"
}
],
"entrypoint": "bin/inspection-module"
}
This tells the registry what your module provides.
The key pattern
The generator created module infrastructure. You added business logic (detect) and exposed it through DoCommand. The same NewInspector constructor works for both CLI testing and module deployment.
4.2 Build and Upload Your Module
Update the module’s model list:
The module was already registered in the Viam registry when you ran viam module generate in Part 3 (you answered “Yes” to “Register module”). Now you need to update its model metadata. First, build a local binary:
make
Then run update-models to detect which models your module provides and update meta.json:
viam module update-models --binary /full/path/to/bin/inspection-module
Replace /full/path/to/ with the absolute path to your module directory.
Cross-compile for the target platform:
Your module will run inside a Linux container, not on your development machine. Even if your Mac and the container both use ARM processors, a macOS binary won’t run on Linux—you need to cross-compile. Cross-compilation also requires disabling CGO (Go’s C interop) and using the no_cgo build tag.
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -tags no_cgo -o bin/inspection-module ./cmd/module
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -tags no_cgo -o bin/inspection-module ./cmd/module
No cross-compilation needed—you’re already on Linux.
go build -o bin/inspection-module ./cmd/module
Package for upload:
tar czf module.tar.gz meta.json bin/
Upload to the registry:
viam module upload --version 0.0.1 --platform linux/arm64 --upload module.tar.gz
viam module upload --version 0.0.1 --platform linux/amd64 --upload module.tar.gz
4.3 Add the Module to Your Machine
Add the inspector service:
- In the Viam app, go to your machine’s Configure tab
- Click + next to your machine part
- Select Blocks
- Search for your model (for example,
your-namespace:inspection-module:inspector) - Name it
inspector-service - Click Add to machine
When you add a service from the registry, the module that provides it is added automatically.
Configure the service attributes:
{
"camera": "inspection-cam",
"vision": "vision-service"
}
Click Save.
Verify it started:
- Go to the Logs tab
- Look for startup messages from the inspector module
- You should see it initialize and connect to the camera and vision service
Test the inspector:
- In the CONFIGURE tab, click on
inspector-serviceto open its configuration panel - Expand the Test section at the bottom
- Expand DoCommand and enter
{"detect": true} - Click Execute
- You should see a response with
labelandconfidencevalues - Click Execute several more times to see different detections as cans pass beneath the inspection-cam
The module is now ready. You’ll configure automatic detection in the next section.
4.4 Configure Detection Data Capture
In Part 2, you captured images from the vision service. Those images are great for visual review, but they’re binary data—you can’t query them with SQL. Now you’ll configure tabular data capture on your inspector’s DoCommand, which will let you query detection results.
Add inspector-service as a data manager dependency:
- In the CONFIGURE tab, click JSON in the upper left
- Find the
data-serviceentry in theservicesarray - Add `