-
Notifications
You must be signed in to change notification settings - Fork 47
DOCS-2930: Add first_run flow for Docker modules #4187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
dff049f
bb29e83
2ee751b
3776863
a4a501c
1c4fc85
fb370cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,7 @@ tags: | |
"components", | ||
"services", | ||
] | ||
description: "Some usage may require you to define new APIs or deploy custom components using a server on a remote part" | ||
description: "Some usage may require you to define new APIs or deploy custom components in non-standard ways." | ||
aliases: | ||
- /program/extend/ | ||
- /modular-resources/advanced/ | ||
|
@@ -46,6 +46,74 @@ Running {{< glossary_tooltip term_id="modular-resource" text="modular resources" | |
|
||
However, if you are unable to use modular resources because you need to host `viam-server` on a non-Linux system or have an issue with compilation, you may need to [implement a custom component and register it on a server configured as a remote](/operate/reference/advanced-modules/custom-components-remotes/) on your machine. | ||
|
||
## Package and deploy using Docker | ||
|
||
In rare cases, you may need to package and deploy a module using Docker. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Be aware that we are not providing complete info here. We're showing how to pull and run a container. We will likely need to look into how to package a module with Docker. So far this really only covers the deploy aspect. Please file a follow up ticket to cover this. A full example for reference is really what I think we need here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
Use cases for this include: | ||
|
||
- Your module has complex system dependencies that cannot be easily installed on a machine. | ||
- You have a large bundle and want to use layer caching to reduce the size of the download. | ||
JessamyT marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- You have specific security requirements that are difficult to meet with the default module deployment. | ||
|
||
If you choose to deploy your module using Docker, we recommend creating a "first run" script or binary to run any necessary setup steps. | ||
|
||
{{% expand "Click for first run script instructions" %}} | ||
|
||
1. Create a tarball that contains: | ||
|
||
- The module's entrypoint script or binary | ||
- A <file>meta.json</file> | ||
- A first run script or binary that will be executed during the setup phase, for example: | ||
|
||
```sh {id="terminal-prompt" class="command-line" data-prompt="$"} | ||
#!/usr/bin/env bash | ||
|
||
if [[ -n "$VIAM_TEST_FAIL_RUN_FIRST" ]]; then | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not familiar with this env var. Is it supposed to be in all first_run scripts? What does it do? Maybe I should add it to mine... 😳 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great question--just pulled this in from the setup phase guide on confluence which in turn links to https://github.com/viam-labs/wifi-sensor/blob/7823b6ad3edcbbbf20b06c34b3181453f5f3f078/first_run.sh There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also am unclear on what this is for here. Can you add an explanation in? Does this get set to true if a previous run failed? Or is this jsut for testing? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the RDK, this env var is mentioned in 2 places: a test and an example first_run.sh. I have cloned about 60 Viam-related repos locally, and it's not mentioned in any of the others. I've searched Github for it, and can only find copies of those 2 locations. I wonder if there was some plan to add this in, but it never happened and these are just the vestiges of a feature that never was. I think we should remove this paragraph from the example. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for looking around. Will remove. |
||
echo "Sorry, I've failed you." | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this error indicate an issue with the module? Maybe better to change to something that indicates where the error is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure where it is. Since this is an edge case documented within a hidden page, I figured it made sense to act quickly and use the existing example provided by Maxim. Sounds like I'll remove the whole paragraph anyway. |
||
exit 1 | ||
fi | ||
|
||
docker pull mongo:6 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this pulls the image but then how does the container get run? I think we probably want to link to an example of that. Also And should this run with https://github.com/viam-soleng/viam-docker-manager or is this entirely separate? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this example is right: in first_run.sh, you pull the image, and then in your module's main executable, you run the image, and that second part should be obvious for anyone developing with docker. We could add in such an example, but it's trivial: #!/bin/bash
set -euxo pipefail
# This example module runs inside the docker image you should have downloaded in first_run.sh
SOCKET_DIR=`dirname $1`
VIAM_DIR=`realpath ~/.viam`
exec docker run \
--rm \
--runtime=nvidia --gpus=all \
-v /etc/passwd:/etc/passwd \
-v /etc/group:/etc/group \
-v $SOCKET_DIR:$SOCKET_DIR \
-v $VIAM_DIR:$VIAM_DIR \
ghcr.io/viam-modules/viam-mlmodelservice-triton/jetpack6:0.9.0 \
LD_PRELOAD=libjemalloc.so.2 VIAM_MODULE_DATA="$VIAM_MODULE_DATA" /opt/viam/bin/viam_mlmodelservice_triton "$@" 2>&1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (that example is from the Triton module, and although there are lots of options specified for the It's really just #!/bin/bash
exec docker run <whatever-the-module-author-intended-to-put-here> There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's probably clear to someone who would immediately know that there's an executable that gets called and where to edit it. I don't think it'll hurt us to add this two liner and where to put it here as the entry point script. @JessamyT you can use the https://hub.docker.com/_/hello-world image to test that this works There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, added above. Tested using the hello-world image, though it of course doesn't behave exactly like a real module that would continue to run. Did confirm that it ran the first_run and made a marker file. |
||
|
||
cat << EOF | ||
------------------------------------- | ||
Congratulations! | ||
The setup script ran successfully! | ||
This message is obnoxiously large for | ||
testing purposes. | ||
Sincerely, | ||
First Run Script | ||
JessamyT marked this conversation as resolved.
Show resolved
Hide resolved
|
||
------------------------------------- | ||
EOF | ||
|
||
exit 0 | ||
``` | ||
|
||
[This example Makefile on GitHub](https://github.com/viam-labs/wifi-sensor/blob/7823b6ad3edcbbbf20b06c34b3181453f5f3f078/Makefile) builds a module binary and bundles it along with a <file>meta.json</file> and first run script.<br><br> | ||
|
||
1. Edit the <file>meta.json</file> to include a `first_run` field that points to the first run script or binary. | ||
|
||
```json | ||
{ | ||
... | ||
"first_run": "first_run.sh" | ||
} | ||
``` | ||
|
||
1. Configure your module on your machine in the same way as you would for a regular module. | ||
The first run script will execute once when `viam-server` receives a new configuration. | ||
It will only execute once per module or per version of the module. | ||
|
||
1. (Optional) After a first run script runs successfully, Viam adds a marker file with a `.first_run_succeeded` suffix in the module’s data directory on disk. | ||
It has the location and form: `/root/.viam/packages/data/module/<MODULE_ID>-<VERSION>-<ARCH>.first_run_succeeded`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suspect there should be a slash before There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm also from Maxim's guide--not sure if there's a reasonably practical way to check for sure There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😳 I went to one of my machines with a module with a first_run script to check, and got surprised that instead of having such a file anywhere, I have a Thanks for pointing me towards this bug! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Eep! I don't have any Docker modules to test this on... @cheukt since it looks like you've been maintaining the confluence instructions, can you confirm? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it is |
||
If you want to force a first run script to run again without changing the configured module or module version, you can do so by deleting this file. | ||
|
||
1. (Optional) By default, a first run script will timeout after 1 hour. | ||
This can be adjusted by adding a `first_run_timeout` to the module’s configuration. | ||
For example, `"first_run_timeout": "5m"` will lower the script timeout to 5 minutes. | ||
|
||
{{% /expand %}} | ||
|
||
## Design a custom ML model | ||
|
||
When working with the [ML model service](/dev/reference/apis/services/ml/), you can deploy an [existing model](/data-ai/ai/deploy/) or [train your own model](/data-ai/ai/train/). | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For both Custom APIs and components as remote parts, we have subpages. I think we should do the same here.