Skip to main content
A GeoEngine worker is a Python or R script packaged into a Docker container, described by a geoengine.yaml config and a pixi.toml dependency file. Once applied, the worker is registered locally and — if enabled — appears as a native tool in your GIS software. If you’d prefer to let an AI coder handle the setup for you, see Create & Modify a Worker Using AI Coder.

Step 1: Navigate to Your Script Directory

Open a terminal and change into the folder that contains the script you want to convert:
cd /path/to/your/script/directory
All GeoEngine commands run relative to this directory. The directory name is used as the default worker name if you don’t specify one.

Step 2: Initialise the Worker

Run geoengine init to generate a geoengine.yaml and a pixi.toml template in the current directory:
# Python worker (default)
geoengine init --name my-worker

# R worker
geoengine init --name my-worker --env r
  • --name sets the worker name. If omitted, the current directory name is used.
  • --env r generates an R-flavoured pixi.toml template instead of the default Python one.
After running this, you will have two new files to edit:
  • geoengine.yaml — worker metadata, inputs, and plugin settings
  • pixi.toml — conda and PyPI dependencies

Step 3: Add CLI Argument Parsing to Your Script

GeoEngine passes inputs to your script as --KEY VALUE flags on the command line. Your script must be able to accept these arguments. For example, if your geoengine.yaml declares an input named input-file, GeoEngine will call:
python main.py --input-file /inputs/input-file/image.tif
If your script does not already have an argument parser, add one using Python’s argparse or R’s optparse. The AI agent skill write-argparse can do this for you automatically — see Create & Modify a Worker Using AI Coder.

Step 4: Edit geoengine.yaml

Open geoengine.yaml and configure your worker. Here is a fully annotated example:
name: land-cover-classifier          # Worker name (used for registration and image tagging)
version: "1.0.0"                     # Semantic version (MAJOR.MINOR.PATCH)
description: "Classifies land cover from satellite imagery"

command:
  program: python                    # Interpreter: python or Rscript
  script: main.py                    # Path to your script (relative to this directory)
  inputs:
    - name: input-file               # Passed as --input-file to your script
      type: file                     # Input types: file | folder | string | number | boolean | enum | datetime
      required: true
      readonly: true                 # true = existing input, false = writable output path
      filetypes:                     # Accepted file extensions (omit for any)
        - .tif
        - .tiff
      description: "Input satellite image"

    - name: output-folder
      type: folder
      required: true
      readonly: false                # false = GeoEngine creates this as a writable output mount

    - name: model
      type: enum
      required: false
      default: "resnet50"
      enum_values:
        - resnet50
        - efficientnet
        - unet
      description: "Classification model to use"

    - name: confidence
      type: number
      required: false
      default: 0.75

    - name: verbose
      type: boolean
      required: false
      default: false

local_dir_mounts:                    # Static host paths to mount into the container
  - host_path: ./models              # Must be an absolute path or start with ./
    container_path: /models
    readonly: true

plugins:
  arcgis: false                      # Set true to register in ArcGIS Pro toolbox
  qgis: true                         # Set true to register in QGIS Processing panel

Input Types at a Glance

TypeHow it reaches your script
fileMounted at /inputs/<name>/<filename>; arg is the container path
folderMounted at /mnt/input_<name>/; arg is the container path
stringPassed through as a plain string argument
numberPassed through as a string argument
booleanPassed through as a string argument
enumPassed through as a string argument
datetimePassed through as a string argument

Output Paths

Declare output folders or files with readonly: false. GeoEngine creates a writable mount at the container path and maps the output back to your host after the run.

Step 5: Edit pixi.toml

Open pixi.toml and declare the packages your script depends on. GeoEngine uses this file to generate the Dockerfile and build a reproducible conda/PyPI environment inside the container.
[project]
name = "land-cover-classifier"
channels = ["conda-forge"]
platforms = ["linux-64"]

[dependencies]
python = ">=3.11"
gdal = "*"
pytorch = ">=2.0"

[pypi-dependencies]
rasterio = "*"
Refer to the Pixi manifest documentation for the full schema. The AI agent skill write-pixi-toml can populate this file automatically based on your script’s imports.

Step 6: Apply the Worker

Once your files are ready, run geoengine apply to build and register the worker:
# Production apply — enforces semantic versioning
geoengine apply

# Dev apply — skips version check, tags image as latest only
geoengine apply --dev
geoengine apply does all of the following in one step:
  1. Validates geoengine.yaml
  2. Generates a Dockerfile from your pixi.toml (if one doesn’t already exist)
  3. Builds the Docker image
  4. Registers the worker and saves a config snapshot
  5. Installs or updates GIS plugins (prompting on first install)
If nothing has changed since the last apply, the process is skipped automatically. Use --no-cache to force a full rebuild:
geoengine apply --no-cache
Refer to the Versioning documentation for more information on versioning your workers, and the differences of using the --dev flag.

Running Your Worker

Once applied, run the worker from the CLI:
geoengine run my-worker --input input-file=/path/to/image.tif --input model=resnet50
To run a specific previously-built version:
geoengine run my-worker --ver 1.0.0 --input input-file=/path/to/image.tif

Next Steps