Files
horus/docker/Readme.md
peternashaat aa30c54742 docs: document hero-git image and installer-based release pipeline
- 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
2025-11-20 12:06:41 +00:00

269 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# `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:
1. **Local development / testing** run the herolib CLI (`hero`) and Horus installers in a clean, reproducible environment.
2. **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-lfs`
* `redis-server`, `libsqlite3-dev`, `libpq-dev`, `autoconf`, `libtool`, `net-tools`, `iputils-ping`, `rsync`, `mc`, `tmux`, `ufw`, `xz-utils`
* Installs **V** compiler:
* Downloads `v_linux.zip` from the official V GitHub releases
* Unzips it and runs `./v symlink` so `v` is on the `PATH`
* Installs **Bun** (used for the docusaurus docs template):
* `curl -fsSL https://bun.sh/install | bash`
* Clones:
* `https://github.com/Incubaid/herolib` into `/opt/herolib`
* `https://github.com/incubaid/docusaurus_template` into `/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.sh` into the image and marks it executable.
The containers entrypoint is set to the custom script `/bin/entrypoint.sh`.
---
### `entrypoint.sh`
The entrypoint script is responsible for:
1. Starting **Redis** in the background.
2. Optionally configuring **SSH** (if keys are provided).
3. Selecting the correct `herolib` source (mounted or cloned).
4. Checking out the desired `herolib` branch.
5. Building the `hero` CLI with V and making it available as `/bin/hero`.
6. Finally, executing any command passed to `docker run`.
#### Behavior in detail
```bash
#!/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`.
#### Optional mounts
* `/opt/herolib_mount`
* If you bind-mount your local `herolib` repo here, the container will use it instead of the cloned `/opt/herolib`.
* Useful for local development when you want to test uncommitted changes.
* `/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/.ssh` and added to an SSH agent.
---
## What this image is used for
### 1. Local development / experimentation
You can drop into the container and manually run installers or commands against `herolib`:
```bash
# 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:
```bash
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:
1. Ensures `hero-git:latest` is available on the self-hosted runner.
2. Creates a local directory (e.g. `hero-bin/`) on the runner.
3. Runs the container, mounting `hero-bin/` into `/root/hero/bin`.
4. Inside the container, executes `./examples/installers/horus/horus_full_install.vsh` from `/opt/herolib`.
5. The installer writes the compiled Horus binaries into `/root/hero/bin`, which appear on the host inside `hero-bin/`.
6. The workflow then packages those binaries into `.tar.gz` archives and uploads them as release artifacts.
Example CI step:
```yaml
- 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:
* `supervisor`
* `coordinator`
* `horus`
* `osiris`
* `herorunner`
* `runner_osiris`
* `runner_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`:
```bash
# 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
```bash
# 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
```bash
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:latest` image encapsulates all dependencies required to build Horus via `herolib`.
* `entrypoint.sh`:
* Starts Redis
* Optionally configures SSH
* Selects and updates the `herolib` checkout
* Builds the `hero` CLI once
* Runs any command passed to the container (e.g. Horus installers)
* CI uses this image to run `horus_full_install.vsh` and collect Horus binaries from `/root/hero/bin` for releases.