Summary
outpost mirror run executes commands on a minimal remote host (Docker + Outpost bootstrap only). Projects that expect local dev tooling (make, go, node, etc.) fail with errors like make: command not found or go: command not found.
Mirror should recognize the project environment and lazily install the required tooling on the remote host when needed.
Problem
Today Outpost only auto-provisions:
- Host level: Docker, Compose, inspection tools (
bootstrap.Ensure)
- Feature level: k3d/kind/kubectl, tmux, Incus (lazy
Ensure* on first use)
- Project level: Python venv only (
mirror setup-python + venv rewrite on mirror run)
There is no equivalent for Go, Make, Node, or other common build tools. Users must SSH in and apt install manually, or avoid Make entirely.
Example failure:
outpost mirror run --no-sync -- make docker-build-prebuilt IMG=myapp:dev
# make: go: No such file or directory
# bash: go: command not found
Proposed solution
1. Detection
Merge two sources:
Explicit config in .outpost/project.yaml:
toolchain:
packages: [make, git] # apt/yum system packages
go: "1.22.5" # optional pinned runtime
node: "20" # optional
auto: true # install on mirror run (default true)
Auto-detect from repo markers after sync:
| Marker |
Infer |
go.mod |
Go (from go / toolchain directive) |
Makefile |
make |
package.json |
Node |
requirements.txt |
Python (existing setup-python path) |
Explicit config overrides auto-detect.
2. Ensure (lazy install)
Follow existing patterns (EnsureTmux, EnsureKubernetesTools):
- System packages (
make, git): apt/yum via passwordless sudo
- Versioned runtimes (
go, node): install under /var/lib/outpost/toolchains/<name>/<version>/ from official tarballs; prepend to PATH for the command — avoid distro packages with stale versions
- Do not run arbitrary install scripts from the repo
3. Hook in mirror run
sync (if needed)
→ EnsureToolchain (NEW)
→ EnsureTmux (if detached)
→ RewritePythonCommand (existing)
→ run command with augmented PATH
Cache installed state (e.g. remote .outpost/toolchain.json or sync-state) to avoid re-checking every run. Re-plan when go.mod or project.yaml toolchain section changes.
4. CLI
outpost mirror run -- make build # auto-ensure when auto: true
outpost mirror setup-toolchain # explicit one-time setup (like setup-python)
outpost mirror toolchain plan # dry-run: show what would be installed
Design constraints
- Keep host bootstrap (Docker, k3d) separate from project toolchain (make, go)
- Prefer Docker-first when Makefile only needs
docker build — detect/nudge where possible
- Only allowlisted packages/runtimes; no
curl | bash from project files
- Idempotent installs; safe on shared hosts
MVP scope
toolchain section in project.yaml (packages, go, auto)
- Auto-detect
go.mod + Makefile → make + Go version
EnsurePackages (apt/yum) + EnsureGo (tarball to /var/lib/outpost/toolchains/)
- Call from
mirror run when auto: true
mirror setup-toolchain command
References
- Existing patterns:
internal/mirror/python.go, internal/mirror/bootstrap.go (EnsureTmux), internal/bootstrap/bootstrap.go (EnsureKubernetesTools)
- Python project config:
Project.Python in internal/config/config.go
Out of scope (follow-ups)
- Universal runtime manager (mise/asdf) on host
- Running mirror commands inside a dev container with docker socket mount
- Parsing Makefile targets to skip compiler install when only
docker build is needed
Summary
outpost mirror runexecutes commands on a minimal remote host (Docker + Outpost bootstrap only). Projects that expect local dev tooling (make,go,node, etc.) fail with errors likemake: command not foundorgo: command not found.Mirror should recognize the project environment and lazily install the required tooling on the remote host when needed.
Problem
Today Outpost only auto-provisions:
bootstrap.Ensure)Ensure*on first use)mirror setup-python+ venv rewrite onmirror run)There is no equivalent for Go, Make, Node, or other common build tools. Users must SSH in and
apt installmanually, or avoid Make entirely.Example failure:
Proposed solution
1. Detection
Merge two sources:
Explicit config in
.outpost/project.yaml:Auto-detect from repo markers after sync:
go.modgo/toolchaindirective)Makefilemakepackage.jsonrequirements.txtsetup-pythonpath)Explicit config overrides auto-detect.
2. Ensure (lazy install)
Follow existing patterns (
EnsureTmux,EnsureKubernetesTools):make,git):apt/yumvia passwordless sudogo,node): install under/var/lib/outpost/toolchains/<name>/<version>/from official tarballs; prepend toPATHfor the command — avoid distro packages with stale versions3. Hook in
mirror runCache installed state (e.g. remote
.outpost/toolchain.jsonor sync-state) to avoid re-checking every run. Re-plan whengo.modorproject.yamltoolchain section changes.4. CLI
Design constraints
docker build— detect/nudge where possiblecurl | bashfrom project filesMVP scope
toolchainsection inproject.yaml(packages,go,auto)go.mod+Makefile→make+ Go versionEnsurePackages(apt/yum) +EnsureGo(tarball to/var/lib/outpost/toolchains/)mirror runwhenauto: truemirror setup-toolchaincommandReferences
internal/mirror/python.go,internal/mirror/bootstrap.go(EnsureTmux),internal/bootstrap/bootstrap.go(EnsureKubernetesTools)Project.Pythonininternal/config/config.goOut of scope (follow-ups)
docker buildis needed