Skip to main content

Custom Runtime Image

Professional Package

Custom Runtime Images are available exclusively with the Professional package. Contact us to learn more about upgrading your subscription.

Overview

StackGuardian provides a base variant of the Terraform/OpenTofu runtime image that you can extend with your own tools and dependencies.

Prerequisites:

  • Docker 20.10+
  • Access to the StackGuardian container registry

Base Image

StackGuardian provides a base runtime image that you can use as your parent image. It includes:

  • Pre-cached OpenTofu and Terraform binaries with on-demand version resolution
  • OPA, Infracost, and Terragrunt
  • Python 3.12 runtime and the StackGuardian workflow application
  • A non-root stackguardian user (UID 911)

The base image URL is available in your Organization Settings → Runner Groups in the StackGuardian platform. In the examples below, it is referred to as <BASE_IMAGE>.

note

The base image has a fully functional Alpine package manager (apk) and pip and is the supported starting point for installing additional system or Python dependencies.

Writing your Dockerfile

FROM <BASE_IMAGE>

# Switch to root to install packages
USER root

# Install system packages
RUN apk add --no-cache \
aws-cli \
azure-cli \
jq \
bash

# Install Python packages
RUN pip install --no-cache-dir \
boto3 \
requests

# Switch back to the application user
USER stackguardian

Key rules:

  • Switch to USER root before installing packages.
  • Switch back to USER stackguardian when done.
  • Do not override ENTRYPOINT or CMD -- the application entrypoint is already configured.
  • Do not modify files under /usr/local/bin/ -- these are the cached IaC tool binaries.

Examples

AWS CLI + 1Password CLI

FROM <BASE_IMAGE>

USER root

RUN apk add --no-cache aws-cli

RUN wget -q -O /tmp/op.zip \
https://cache.agilebits.com/dist/1P/op2/pkg/v2.24.0/op_linux_amd64_v2.24.0.zip && \
unzip /tmp/op.zip -d /usr/local/bin/ && \
rm /tmp/op.zip && \
chmod +x /usr/local/bin/op

USER stackguardian

Custom Python Libraries

FROM <BASE_IMAGE>

USER root

RUN pip install --no-cache-dir \
checkov \
pyyaml

USER stackguardian

Azure CLI with Extensions

FROM <BASE_IMAGE>

USER root

RUN apk add --no-cache \
py3-pip \
gcc \
musl-dev \
python3-dev \
libffi-dev

RUN pip install --no-cache-dir azure-cli

USER stackguardian

Security hardening (Optional)

The base image ships a hardening script at /usr/local/bin/harden.sh. This script strips the image down for production use by:

  • Removing unnecessary system accounts
  • Removing SUID/SGID binaries and dangerous commands
  • Removing admin commands from /sbin and /usr/sbin (except apk)
  • Disabling interactive login shells
  • Locking down file permissions

apk and pip remain available after hardening so that downstream images can still install packages if needed.

To apply hardening after installing your packages:

FROM <BASE_IMAGE>

USER root

RUN apk add --no-cache aws-cli
RUN pip install --no-cache-dir boto3

# Apply security hardening (must be the last RUN step as root)
RUN /usr/local/bin/harden.sh stackguardian

USER stackguardian
important

Run harden.sh as the last root step in your Dockerfile. Most admin tools and system commands will be removed after hardening — only apk and pip are preserved for package management.

Build and test

# Build your custom image
docker build -t my-custom-runtime:latest .

# Verify your tools are available
docker run --rm my-custom-runtime:latest aws --version
docker run --rm my-custom-runtime:latest pip list

# Verify the application still starts
docker run --rm my-custom-runtime:latest

Working directory

The application working directory is /opt/stackguardian. Avoid writing to this directory as it contains the application code. Use /tmp or /mnt for temporary files.

Troubleshooting

ProblemCauseFix
apk add fails with permission deniedNot running as rootAdd USER root before install commands
apk add fails with "not found"Using the hardened image instead of baseUse the base image provided in your Organization Settings
Application fails to startCMD or ENTRYPOINT was overriddenRemove any CMD/ENTRYPOINT from your Dockerfile
Binary not found at runtimeInstalled to wrong pathEnsure binaries are in /usr/local/bin/ or on $PATH