- add README for hero-git Docker image usage (local + CI) - explain Dockerfile/entrypoint behavior and horus_full_install workflow - describe new release process using hero-git image and horus_full_install.vsh
7.7 KiB
hero-git Docker Image
This directory contains a reusable Docker image and entrypoint script used to build Hero / Horus binaries via the V-based herolib installers.
It is designed for two main use cases:
- Local development / testing – run the herolib CLI (
hero) and Horus installers in a clean, reproducible environment. - CI / Release builds – build Horus binaries inside this image (using
horus_full_install.vsh) and export them as release artifacts.
Files
Dockerfile
The Dockerfile builds an Ubuntu-based image with all dependencies needed for herolib and its installers.
Key points:
-
Base:
ubuntu:24.04 -
Installs system tooling:
ssh,wget,curl,unzip,build-essential,git,git-lfsredis-server,libsqlite3-dev,libpq-dev,autoconf,libtool,net-tools,iputils-ping,rsync,mc,tmux,ufw,xz-utils
-
Installs V compiler:
- Downloads
v_linux.zipfrom the official V GitHub releases - Unzips it and runs
./v symlinksovis on thePATH
- Downloads
-
Installs Bun (used for the docusaurus docs template):
curl -fsSL https://bun.sh/install | bash
-
Clones:
https://github.com/Incubaid/herolibinto/opt/herolibhttps://github.com/incubaid/docusaurus_templateinto/root/code/github/incubaid/docusaurus_template
-
Warms Bun dependencies for the docusaurus template (for faster re-use):
cd /root/code/github/incubaid/docusaurus_template/template && bun install
-
Prepares directories:
/root/.vmodules/incubaid– used by V module resolution/root/ssh– optional mount point for SSH keys
-
Copies
entrypoint.shinto the image and marks it executable.
The container’s entrypoint is set to the custom script /bin/entrypoint.sh.
entrypoint.sh
The entrypoint script is responsible for:
- Starting Redis in the background.
- Optionally configuring SSH (if keys are provided).
- Selecting the correct
herolibsource (mounted or cloned). - Checking out the desired
herolibbranch. - Building the
heroCLI with V and making it available as/bin/hero. - Finally, executing any command passed to
docker run.
Behavior in detail
#!/bin/bash
set -euo pipefail
# Start Redis in the background
redis-server --daemonize yes
# Optional SSH setup: only if /root/ssh has keys
if [ -d /root/ssh ] && compgen -G "/root/ssh/*" > /dev/null; then
mkdir -p /root/.ssh
cp -r /root/ssh/* /root/.ssh/
chmod 600 /root/.ssh/*
eval "$(ssh-agent)"
ssh-add /root/.ssh/*
fi
# Support optionally bind-mounting a local herolib into the container.
# If /opt/herolib_mount exists, we use that; otherwise we use the cloned /opt/herolib
rm -f /root/.vmodules/freeflowuniverse/herolib
if [ -d "/opt/herolib_mount" ]; then
ln -s /opt/herolib_mount/lib /root/.vmodules/incubaid/herolib
cd /opt/herolib_mount
else
ln -s /opt/herolib/lib /root/.vmodules/incubaid/herolib
cd /opt/herolib
git fetch
git checkout "${HEROLIB_REF:-development}"
git pull
fi
cd cli
echo "Building hero..."
v -enable-globals hero.v > build.log 2>&1 || (cat build.log && exit 1)
ln -s "$(realpath hero)" /bin/hero
cd /root
# If a command was provided to `docker run`, execute it as-is.
# Example: docker run hero-git:latest bash -lc 'cd /opt/herolib && ./examples/installers/horus/horus_full_install.vsh'
if [ "$#" -gt 0 ]; then
exec "$@"
else
# No command passed → give an interactive shell
exec bash
fi
Important environment variables
-
HEROLIB_REF- Git ref (branch, tag, or commit) used when checking out
/opt/herolib. - Default:
development. - Example for CI:
HEROLIB_REF=development_nile_installers.
- Git ref (branch, tag, or commit) used when checking out
Optional mounts
-
/opt/herolib_mount- If you bind-mount your local
herolibrepo here, the container will use it instead of the cloned/opt/herolib. - Useful for local development when you want to test uncommitted changes.
- If you bind-mount your local
-
/root/ssh- Optional directory containing SSH keys (e.g.
id_ed25519) if you need to access private repositories. - If present and non-empty, keys are copied to
/root/.sshand added to an SSH agent.
- Optional directory containing SSH keys (e.g.
What this image is used for
1. Local development / experimentation
You can drop into the container and manually run installers or commands against herolib:
# Interactive shell with default branch
docker run -it --rm hero-git:latest
# Use a specific herolib ref
docker run -it --rm -e HEROLIB_REF=development_nile_installers hero-git:latest
# Mount a local herolib repo and use that instead of the cloned one
docker run -it --rm \
-v "$PWD/herolib:/opt/herolib_mount" \
hero-git:latest
Inside the container you can then run:
cd /opt/herolib
./examples/installers/horus/horus_full_install.vsh
2. CI / Release builds for Horus
In CI (e.g. the release.yml workflow), this image is used to build Horus binaries via the V-based installer script:
-
The workflow:
- Ensures
hero-git:latestis available on the self-hosted runner. - Creates a local directory (e.g.
hero-bin/) on the runner. - Runs the container, mounting
hero-bin/into/root/hero/bin. - Inside the container, executes
./examples/installers/horus/horus_full_install.vshfrom/opt/herolib. - The installer writes the compiled Horus binaries into
/root/hero/bin, which appear on the host insidehero-bin/. - The workflow then packages those binaries into
.tar.gzarchives and uploads them as release artifacts.
- Ensures
Example CI step:
- name: Run horus_full_install installer in container
run: |
set -euxo pipefail
docker run --rm \
-v "$PWD/hero-bin:/root/hero/bin" \
-e HEROLIB_REF=development_nile_installers \
hero-git:latest \
bash -lc '
set -euxo pipefail
cd /opt/herolib
./examples/installers/horus/horus_full_install.vsh
echo "===== AFTER INSTALL, ls -R /root/hero ====="
ls -R /root/hero || true
'
After this step, hero-bin/ on the host should contain binaries like:
supervisorcoordinatorhorusosirisherorunnerrunner_osirisrunner_sal
These are then packaged and attached to the Gitea release.
How to build the image
From the directory containing the Dockerfile and entrypoint.sh:
# Build the image (force a clean rebuild)
docker build --no-cache -t hero-git:latest .
# Verify entrypoint contents
docker run --rm --entrypoint cat hero-git:latest /bin/entrypoint.sh | tail -n 20
You should see the exec "$@" block at the end of the script, which ensures that commands passed to docker run are executed as-is inside the container.
How to run the image (examples)
Basic interactive usage
# Default branch (HEROLIB_REF=development)
docker run -it --rm hero-git:latest
# Specific herolib ref
export HEROLIB_REF=development_nile_installers
docker run -it --rm \
-e HEROLIB_REF=$HEROLIB_REF \
hero-git:latest
Build Horus binaries into a host directory
mkdir -p hero-bin
docker run --rm \
-v "$PWD/hero-bin:/root/hero/bin" \
-e HEROLIB_REF=development_nile_installers \
hero-git:latest \
bash -lc '
set -euxo pipefail
cd /opt/herolib
./examples/installers/horus/horus_full_install.vsh
ls -al /root/hero/bin
'
ls -al hero-bin
You should now see the built Horus binaries on the host in hero-bin/.
Summary
-
The
hero-git:latestimage encapsulates all dependencies required to build Horus viaherolib. -
entrypoint.sh:- Starts Redis
- Optionally configures SSH
- Selects and updates the
herolibcheckout - Builds the
heroCLI once - Runs any command passed to the container (e.g. Horus installers)
-
CI uses this image to run
horus_full_install.vshand collect Horus binaries from/root/hero/binfor releases.