|
| 1 | +--- |
| 2 | +title: "Deploy a module using Docker" |
| 3 | +linkTitle: "Docker Modules" |
| 4 | +weight: 300 |
| 5 | +type: "docs" |
| 6 | +tags: ["extending viam", "modular resources"] |
| 7 | +description: "Deploy a module using Docker." |
| 8 | +no_list: true |
| 9 | +date: "2025-04-10" |
| 10 | +# updated: "" # When the content was last entirely checked |
| 11 | +--- |
| 12 | + |
| 13 | +In rare cases, you may need to package and deploy a module using Docker. |
| 14 | +Use cases for this include: |
| 15 | + |
| 16 | +- Your module has complex system dependencies that cannot be easily installed on a machine. |
| 17 | +- You use a large container image and some layers are already used by your machine which means layer caching can reduce the size of the download. |
| 18 | +- You have specific security requirements that are difficult to meet with the default module deployment. |
| 19 | + |
| 20 | +If you choose to deploy your module using Docker, we recommend creating a "first run" script or binary to run any necessary setup steps. |
| 21 | +Note this is _not_ recommended for modules that do not use Docker, as it adds unnecessary complexity. |
| 22 | + |
| 23 | +## Use a `first_run` script or binary |
| 24 | + |
| 25 | +1. Create a tarball that contains: |
| 26 | + |
| 27 | + - The module's entrypoint script or binary, for example: |
| 28 | + |
| 29 | + ```sh {id="terminal-prompt" class="command-line" data-prompt="$"} |
| 30 | + #!/bin/bash |
| 31 | + exec docker run <YOUR_CONTAINER_IMAGE> <YOUR_CONTAINER_OPTIONS> |
| 32 | + ``` |
| 33 | + |
| 34 | + - A <file>meta.json</file> |
| 35 | + - A first run script or binary that will be executed during the setup phase, for example: |
| 36 | + |
| 37 | + ```sh {id="terminal-prompt" class="command-line" data-prompt="$"} |
| 38 | + #!/usr/bin/env bash |
| 39 | +
|
| 40 | + docker pull mongo:6 |
| 41 | +
|
| 42 | + cat << EOF |
| 43 | + ------------------------------------- |
| 44 | + The setup script ran successfully! |
| 45 | + ------------------------------------- |
| 46 | + EOF |
| 47 | +
|
| 48 | + exit 0 |
| 49 | + ``` |
| 50 | +
|
| 51 | + [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> |
| 52 | +
|
| 53 | +1. Edit the <file>meta.json</file> to include a `first_run` field that points to the first run script or binary. |
| 54 | +
|
| 55 | + ```json |
| 56 | + { |
| 57 | + ... |
| 58 | + "first_run": "first_run.sh" |
| 59 | + } |
| 60 | + ``` |
| 61 | +
|
| 62 | +1. Configure your module on your machine in the same way you would configure a regular module. |
| 63 | + The first run script will execute once when `viam-server` receives a new configuration. |
| 64 | + It will only execute once per module or per version of the module.<br><br> |
| 65 | +
|
| 66 | +1. (Optional) After a first run script runs successfully, Viam adds a marker file in the module's data directory. |
| 67 | + The marker file path format is of the form `unpackedModDir + FirstRunSuccessSuffix`. |
| 68 | + For example, `.viam/packages/data/module/abcd1234-abcd-abcd-abcd-abcd12345678-viam-rtsp-0_1_0-linux-amd64/bin.first_run_succeeded`. |
| 69 | +
|
| 70 | + 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.<br><br> |
| 71 | +
|
| 72 | +1. (Optional) By default, a first run script will timeout after 1 hour. |
| 73 | + This can be adjusted by adding a `first_run_timeout` to the module's configuration. |
| 74 | + For example, `"first_run_timeout": "5m"` will lower the script timeout to 5 minutes. |
0 commit comments