About images
Images
Lunar supports running collectors, policies, and catalogers inside Docker containers. This provides isolation, reproducibility, and simplifies dependency management. Default images can be configured at multiple levels, with more specific settings overriding more general ones.
Image Resolution Order
The image used to run a script is determined in the following order (first match wins):
Script-level
image- Set directly on the collector, policy, or catalogerPlugin-level default - Set in
lunar-collector.yml,lunar-policy.yml, orlunar-cataloger.ymlGlobal default - Set in
lunar-config.ymlImplicit default -
native(no container)
Global Default Images
Configure default images in lunar-config.yml:
version: 0
default_image: my-custom-image:alpine-1.2.3
default_image_ci_collectors: native
default_image_non_ci_collectors: my-image:v1.0
default_image_policies: another-image:latest
default_image_catalogers: yet-another-image:v2.0
# ... rest of configurationdefault_image
default_imagelunar-config.yml -> default_imageType:
stringOptional
Default:
native
The global default image to use for all collectors, policies, and catalogers. This is overridden by the more specific default_image_* settings.
default_image_ci_collectors
default_image_ci_collectorslunar-config.yml -> default_image_ci_collectorsType:
stringOptional
Default: value of
default_image
The default image for CI collectors (collectors with hooks of type ci-before-command, ci-after-command, ci-before-job, ci-after-job). It is common to set this to native since CI collectors often need direct access to the CI environment.
default_image_non_ci_collectors
default_image_non_ci_collectorslunar-config.yml -> default_image_non_ci_collectorsType:
stringOptional
Default: value of
default_image
The default image for non-CI collectors (collectors with hooks of type code, cron).
default_image_policies
default_image_policieslunar-config.yml -> default_image_policiesType:
stringOptional
Default: value of
default_image
The default image for all policies.
default_image_catalogers
default_image_catalogerslunar-config.yml -> default_image_catalogersType:
stringOptional
Default: value of
default_image
The default image for all catalogers.
Plugin-Level Default Images
Plugins can define their own default images that override the global settings. This is useful when a plugin requires specific dependencies that are pre-installed in a custom image.
In lunar-collector.yml, lunar-policy.yml, or lunar-cataloger.yml:
The same settings are available as at the global level. Plugin-level defaults override global defaults but are overridden by script-level image settings.
Script-Level Image
Each individual collector, policy, or cataloger can specify its own image to override all defaults:
The native Value
native ValueThe special value native explicitly opts out of containerized execution. When image: native is set, the script runs directly on the host system using the native runtime (Python, Bash, etc.).
This is useful when:
A default image has been configured, but a specific script needs to run natively
CI collectors need direct access to the CI environment
The script needs access to host-specific resources
Common Configuration Pattern
A common configuration is to use containers for most scripts but run CI collectors natively:
This configuration:
Runs all policies in containers
Runs all catalogers in containers
Runs non-CI collectors (code, cron, repo hooks) in containers
Runs CI collectors natively for direct access to CI environment variables and tools
Official Image: earthly/lunar-scripts
earthly/lunar-scriptsLunar provides an official Docker image earthly/lunar-scripts that includes:
Alpine Linux (or
-debianvariant for tools requiring glibc)Python 3 with venv
Bash
The
lunar-policyPython packageThe
lunarCLICommon tools:
jq,yq,curl,parallel,wget
Dependency Handling
The official earthly/lunar-scripts image automatically executes any requirements.txt and/or install.sh files it finds in the plugin directory as part of its entrypoint. This is a convenience feature to help you get up and running quickly during development.
For production use, we recommend baking all dependencies directly into your image. This approach provides:
Faster startup times (no runtime installation)
Reproducible builds
Better caching and smaller attack surface
Elimination of network dependencies at runtime
Recommended Approach: Custom Image Inheriting from Official
The recommended approach is to create a custom Dockerfile that inherits from the official earthly/lunar-scripts image and installs your dependencies at build time:
This pattern gives you all the benefits of the official image (Python, Bash, lunar CLI, lunar-policy package) while ensuring your dependencies are baked in for production use.
Image Entrypoint Contract
Lunar executes snippets by passing two arguments to the image's entrypoint:
$1
The snippet language
python, bash
$2
Absolute path to the main script file
/app/exec/main.py
The entrypoint is responsible for invoking the correct language runtime on the given script. The official earthly/lunar-scripts image ships an entrypoint at /app/entrypoint.sh that handles this automatically.
Requirements for Custom Images
If you build a custom image, it must meet these requirements:
Entrypoint at
/app/entrypoint.shthat accepts(language, script_path)as$1and$2. The simplest implementation:
Language runtime on
PATHβ the binary matching the snippet's language must be available:
Python
python
Bash
bash
Note: Many base images ship
python3without apythonsymlink. Ensurepythonresolves correctly (e.g.,RUN ln -sf /usr/bin/python3 /usr/bin/python). The officialearthly/lunar-scriptsimage handles this automatically.
The recommended approach is to inherit from the official image, which satisfies both requirements out of the box:
How Execution Works
Both the Docker engine (local development) and the Kubernetes operator use the same entrypoint contract. Lunar passes [language, script_path] as arguments to the container, and the image's entrypoint handles dispatching to the correct runtime.
This means a custom image tested locally via the Docker engine will behave identically when deployed to Kubernetes β the entrypoint runs in both environments with the same arguments.
Mount Points
The following directories are available inside the container in both Docker and Kubernetes execution modes:
/app/exec
Plugin directory β script and plugin files
/app/work
Working directory β the component's code (for collectors and some catalogers)
/app/lib
Library directory β bundle data for policies
The container's working directory is set to /app/work, so your scripts can access the component's files using relative paths. The LUNAR_PLUGIN_ROOT environment variable is set to /app/exec.
Private Registry Authentication
To pull images from private Docker registries, configure the following environment variables:
LUNAR_DOCKER_REGISTRY_USER- Username for Docker registry authenticationLUNAR_DOCKER_REGISTRY_PASS- Password or token for Docker registry authentication
Last updated
