Examples and Tutorials

This section provides hands-on examples for using Voltis in real-world scenarios. Each tutorial builds on the Usage Guide and Workloads concepts. We’ll cover deploying common edge setups like Docker, k3s, and a full GitOps stack with Gitea and Flux.

Prerequisites: Installed CLI and a test node with Voltis daemon running (sudo voltis daemon).

Example 1: Deploying Docker on an Edge Node

Docker is a foundational service for containerized workloads. This example creates a minimal workload to install Docker CE.

Step 1: Create Workload Directory

mkdir docker-workload
cd docker-workload

Step 2: voltis.toml

Create voltis.toml:

version = "1"
workload = "edge-docker"

installOrder = ["docker"]
uninstallOrder = ["docker"]

[services.docker]
state = "active"
systemdUnitName = "docker"

Step 3: Taskfile (docker.voltis.taskfile.yml)

Create the taskfile with Ubuntu/Debian install steps:

version: "3"

tasks:
  action.install:
    desc: "Install Docker CE"
    status:
      - which docker
    cmds:
      - apt-get update
      - apt-get install -y ca-certificates curl
      - install -m 0755 -d /etc/apt/keyrings
      - curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
      - chmod a+r /etc/apt/keyrings/docker.asc
      - echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
      - apt-get update
      - apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

  action.uninstall:
    desc: "Uninstall Docker"
    status:
      - "! which docker"
    cmds:
      - apt-get remove -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
      - apt-get autoremove -y
      - rm -rf /etc/apt/keyrings/docker.asc /etc/apt/sources.list.d/docker.list

  state.active:
    desc: "Enable and start Docker"
    preconditions:
      - which docker
    cmds:
      - systemctl enable docker
      - systemctl start docker

  state.inactive:
    desc: "Stop Docker"
    preconditions:
      - which docker
    cmds:
      - systemctl stop docker
      - systemctl disable docker

Step 4: Build and Deploy

From the CLI machine:

# Build
voltis workload buildfile ./docker-workload --output docker.voltis.tar.gz

# Push and activate (replace <node-ip> with target)
export VOLTIS_API_ADDRESS=http://<node-ip>:4650
voltis workload push docker.voltis.tar.gz --name edge-docker --status active

Step 5: Verify

voltis workload list  # Should show "edge-docker" as active
voltis service list   # Docker: current=running, desired=active, installed=*
docker --version      # On node: Docker version 27.x

Cleanup

voltis workload reset

Example 2: Full GitOps Stack (Gitea + Flux)

Deploy a self-hosted Git server (Gitea) with Flux for GitOps on k3s.

Step 1: Create Workload Directory

mkdir gitops-stack
cd gitops-stack

Step 2: voltis.toml

version = "1"
workload = "gitops-stack"

installOrder = ["docker", "k3s", "flux", "gitea"]
uninstallOrder = ["gitea", "flux", "k3s", "docker"]

[services.docker]
state = "active"
systemdUnitName = "docker"

[services.k3s]
state = "active"
systemdUnitName = "k3s"

[packages.flux]

[services.gitea]
state = "active"
systemdUnitName = "gitea"

Step 3: Docker Taskfile (docker.voltis.taskfile.yml)

version: "3"

tasks:
  action.install:
    desc: Install Docker
    status:
      - which docker
    cmds:
      - echo "Installing Docker"
      - apt-get update
      - apt-get install -y apt-transport-https ca-certificates curl software-properties-common
      - install -m 0755 -d /etc/apt/keyrings
      - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --yes --no-tty --dearmor -o /etc/apt/keyrings/docker.gpg
      - chmod a+r /etc/apt/keyrings/docker.gpg
      - echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
      - apt-get update
      - apt-get install -y docker-ce docker-ce-cli containerd.io
      - usermod -aG docker $USER
  action.uninstall:
    desc: Uninstall Docker
    status:
      - "! which docker"
    cmds:
      - echo "Uninstalling Docker"
      - systemctl stop docker
      - apt-get purge -y docker-ce docker-ce-cli containerd.io
      - rm -rf /var/lib/docker
      - rm -rf /var/lib/containerd
      - apt-get autoremove -y
      - apt-get autoclean
  state.active:
    precondition:
      - which docker
    cmds:
      - systemctl start docker
  state.inactive:
    precondition:
      - which docker
    cmds:
      - systemctl stop docker

Step 4: k3s Taskfile (k3s.voltis.taskfile.yml)

version: "3"

tasks:
  action.install:
    status:
      - which k3s
    cmds:
      - echo "installing k3s"
      - 'curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server --disable traefik --tls-san localhost" sh -s -'
  action.uninstall:
    status:
      - "! which k3s"
    precondition:
      - test -f /usr/local/bin/k3s-uninstall.sh
    cmds:
      - echo "uninstalling k3s"
      - /usr/local/bin/k3s-uninstall.sh
  state.active:
    precondition:
      - which k3s
    cmds:
      - systemctl start k3s
  state.inactive:
    precondition:
      - which k3s
    cmds:
      - systemctl stop k3s

Step 5: Flux Taskfile (flux.voltis.taskfile.yml)

version: "3"
tasks:
  action.install:
    status:
      - which flux
    cmds:
      - echo "installing flux"
      - curl -s https://fluxcd.io/install.sh | bash
  action.uninstall:
    status:
      - "! which flux"
    precondition:
      - test -f /usr/local/bin/flux
    cmds:
      - echo "uninstalling flux"
      - rm -f /usr/local/bin/flux

Step 6: Gitea Taskfile (gitea.voltis.taskfile.yml)

version: "3"
tasks:
  action.install:
    status:
      - which gitea
    cmds:
      - echo "installing gitea"
      - wget -O /usr/local/bin/gitea https://dl.gitea.com/gitea/1.24.5/gitea-1.24.5-linux-amd64
      - chmod +x /usr/local/bin/gitea
      - adduser --system --shell /bin/bash --gecos 'Git Version Control' --group --disabled-password --home /home/git git
      - mkdir -p /var/lib/gitea/{custom,data,log}
      - chown -R git:git /var/lib/gitea/
      - chmod -R 750 /var/lib/gitea/
      - mkdir /etc/gitea
      - chown root:git /etc/gitea
      - chmod 770 /etc/gitea
      - cp /var/lib/voltis/workload/extras/gitea.service /etc/systemd/system/gitea.service
      - systemctl daemon-reload
      - systemctl restart gitea

  action.uninstall:
    status:
      - "! which gitea"
    precondition:
      - test -f /usr/local/bin/gitea
    cmds:
      - echo "uninstalling gitea"
      - cmd: systemctl stop gitea
        ignore_error: true
      - rm -f /usr/local/bin/gitea
      - userdel -r git
      - rm -rf /var/lib/gitea
      - rm -rf /etc/gitea
      - rm -f /etc/systemd/system/gitea.service
      - systemctl daemon-reload
  state.active:
    precondition:
      - which gitea
    cmds:
      - systemctl start gitea
  state.inactive:
    precondition:
      - which gitea
    cmds:
      - systemctl stop gitea

Include extras/gitea.service (see Workloads guide).

Step 7: Deploy Stack

voltis workload buildfile ./gitops-workload --output gitops.voltis.tar.gz
voltis workload push gitops.voltis.tar.gz --name gitops-stack --status active

Step 5: Verify

  • Gitea: Access http://:3000; create repo.
  • Flux: kubectl get pods -n flux-system; check bootstrap status.
  • GitOps: Push manifests to Gitea repo; Flux reconciles to k3s.

Example 3: Using Builtin Workloads

Voltis ships with ready-to-use workloads in builtin_tasks/.

Deploy Ollama (Local AI)

# From repo root
voltis workload buildfile builtin_tasks/ollama --output ollama.voltis.tar.gz
voltis workload push ollama.voltis.tar.gz --name ai-ollama --status active

This installs Ollama service; pull models via ollama pull llama2.

Cluster Setup with Beam

Builtin cluster/ workloads include apt, beam, docker, flux, gitea, k3s. Beam is a tool that builds images on remote hosts and injects them into containerd. Beam

Example full cluster node:

voltis workload buildfile builtin_tasks/cluster --output cluster.voltis.tar.gz
voltis workload push cluster.voltis.tar.gz --name cluster --status active

Customize by editing builtin taskfiles.

Best Practices for Examples

  • Version Pinning: Use specific versions in taskfiles (e.g., apt install docker-ce=5:20.10.21~3-0~ubuntu-focal).
  • Install Action in Tasks: Use offical processes from the provider to ensure stability during installation.
  • Uninstall Action in Tasks: Ensure entire component is uninstalled and the unit is removed from systemd.
  • Service Unit Names: Provide a service name that can be recognized easily in systemd.
  • Packages: Use packages if you are using executables that need to remain on the system; not persistent services.
  • Jobs: Use jobs when you are creating a task that runs one or more times; if you need persistence create a service.

For more, explore builtin_tasks/ source.

Next: User Guide