Deployment Workflow

Complete guide to building application container images and deploying to Sol3 hardware.

Prerequisites

Overview

The deployment workflow creates containerized applications that run on Sol3 devices:

  1. Build Application Image - Create a Docker container with your application and dependencies

  2. Deploy to Device - Push the container image to the device

  3. Run Application - Start the containerized application on the device

Building Application Images

The SDK provides the sol3_build_app_image script to create deployable container images.

Build for Sol3 Hardware (ARM64)

# Build for Sol3 device
sol3_build_app_image my-app arm64 --cmake-preset arm64

# Build with custom tag
sol3_build_app_image my-app arm64 --cmake-preset arm64 --tag v1.0.0

Important

While there is a distinction between the “arch” (the architecture Docker uses to build the image) and “preset” (the CMake preset which configures the build for direct or cross-compilation), they are related. Builds must use a consistent arch/preset pair, otherwise the build will fail.

Build for Testing (x64)

Build x64 images for testing on your development machine:

# Build for x64 testing
sol3_build_app_image my-app x64 --cmake-preset x64

# Run locally to test (same mounts/privileged as on-device; see below)
docker run --rm \
  -v /run/sol3:/run/sol3 \
  -v /dev:/dev \
  --privileged \
  my-app-x64:latest

Tip

If possible, test your application in a container on x64 before deploying to ARM64 hardware. This catches build/containerization issues early.

Understanding the Multi-Stage Build

The sol3_build_app_image script uses your project’s Dockerfile, which inherits the SDK’s multi-stage build system:

  1. Base Stage - System dependencies and sysroot

  2. Build Stage - Build tools, CMake, vcpkg, compilation

  3. Runtime Stage - Application binary and runtime dependencies only

See the Dockerfile Architecture for details.

Image Naming Convention

Images are named following this pattern:

<app-name>-<preset>:<tag>

Examples:

  • my-app-arm64:latest - Latest ARM64 build

  • my-app-arm64:v1.0.0 - Versioned ARM64 release

  • my-app-x64-debug:latest - Latest x64 debug build for testing

Deploying to Sol3 Devices

Deploy Application

Use the sol3_deploy_app_image script to deploy images to the device. The script handles the entire deployment process automatically:

# Deploy application (basic usage)
sol3_deploy_app_image my-app-arm64:latest <USER@HDK_IP>

# Deploy specific version
sol3_deploy_app_image my-app-arm64:v1.0.0 <USER@HDK_IP>

# Custom registry port
sol3_deploy_app_image my-app-arm64:latest <USER@HDK_IP> --registry-port 5000

How Deployment Works

The sol3_deploy_app_image script automates the complete deployment workflow:

  1. Validates Local Image - Checks that the image exists locally

  2. Tests SSH Connectivity - Verifies SSH access to the device

  3. Manages Device Registry - Automatically starts the Docker registry on the device if not running

  4. Creates SSH Tunnel - Sets up secure port forwarding for image transfer

  5. Pushes Image - Transfers the image through the SSH tunnel to the device registry

  6. Pulls on Device - Ensures the image is available in the device’s Docker daemon

  7. Cleans Up - Removes temporary tags and closes the SSH tunnel

All of these steps are handled automatically. The script provides progress feedback and detailed error messages if any step fails.

Prerequisites

Before deploying, ensure:

  • SSH Access: Passwordless SSH access to the device (SSH keys configured)

  • Image Built: The application image exists locally

Deployment Output

Successful deployment shows:

Checking if image exists locally (my-app-arm64:latest)... ✓
Testing SSH connectivity to <USER@HDK_IP>... ✓
Checking if registry is running on <USER@HDK_IP>:5000... ✓
Setting up SSH tunnel (localhost:5001 -> remote:localhost:5000)... ✓
Tagging image for device registry... ✓
Pushing image to device registry via SSH tunnel... ✓
Pulling image on device... ✓
Cleaning up local registry tag... ✓
✅ Image deployed and pulled successfully!
   Source Image: my-app-arm64:latest
   Registry Image: localhost:5000/my-app-arm64:latest
   Device: <USER@HDK_IP>

To run on device:
   docker run -t -v /run/sol3:/run/sol3 -v /dev:/dev --privileged localhost:5000/my-app-arm64:latest [ARGS]

Run Application on Device

When running on the device via docker run, you must ensure that both the /run/sol3 and /dev directories are bind-mounted into the container, and it also must be run in --privileged mode. These ensure that ShmemExchange will work as expected. Other than those requirements, feel free to format the docker run command as needed to support your application:

ssh <USER@HDK_IP>
docker run --rm \
  -v /run/sol3:/run/sol3 \
  -v /dev:/dev \
  --privileged \
  localhost:5000/my-app-arm64:latest <ARGS>

Complete Deployment Example

# Build for ARM64
sol3_build_app_image my-app arm64 --cmake-preset arm64 --tag v1.0.0

# Deploy to device
sol3_deploy_app_image my-app-arm64:v1.0.0 <USER@HDK_IP>

# Run on device
ssh <USER@HDK_IP>
docker run --rm \
  -v /run/sol3:/run/sol3 \
  -v /dev:/dev \
  --privileged \
  --name my-app \
  localhost:5000/my-app-arm64:v1.0.0