The default runner image (catthehacker/ubuntu:act-latest) has the
podman socket mounted at /var/run/docker.sock but no Docker CLI.
Install docker.io to provide the CLI. The socket is accessible as
root, so sudo -E docker build works.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add debug step to understand docker socket state in runner container.
Restore sudo -E for docker/skopeo commands and remove container block
(runner already mounts podman socket by default).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bun's bundler can't read directory symlinks (EISDIR). Copy the stub
files directly into node_modules instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
shamefully-hoist still creates symlinks to .pnpm store which bun
can't follow (EISDIR errors). node-linker=hoisted creates actual
copies in a flat node_modules layout, like npm.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bun's bundler can't follow pnpm's nested symlink layout to resolve
transitive dependencies of workspace packages (e.g. ink's yoga-layout,
react-reconciler). Adding shamefully-hoist=true creates a flat
node_modules layout that bun can resolve from, matching the behavior
of the local dev environment.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The runner container doesn't have access to the Docker socket by
default. Mount /var/run/docker.sock via container.volumes so docker
build and skopeo can access the host's podman API. Removed sudo since
the container user is root.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The local build-rpm.sh successfully uses pnpm's node_modules with bun
compile. The CI was unnecessarily replacing node_modules with bun install,
which broke transitive workspace dependency resolution. Match the working
local approach instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
sudo resets the environment by default, so DOCKER_API_VERSION=1.43
wasn't reaching the docker CLI. Use -E to preserve it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Docker CLI v1.52 is too new for the host's podman daemon (max 1.43).
Set DOCKER_API_VERSION to force the older API.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
bun install on top of pnpm's nested node_modules fails to resolve
workspace transitive deps (Ink, inquirer, etc). Remove node_modules
first so bun creates a proper flat layout from scratch.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
docker build works via podman socket (builds don't need registry access).
skopeo pushes directly over HTTP with --dest-tls-verify=false, bypassing
the daemon's registry config entirely. No login/daemon config needed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The host uses podman (not Docker) — the socket mounted in job containers
is /run/podman/podman.sock. Podman reads /etc/containers/registries.conf
for insecure registry config, which takes effect immediately without any
daemon restart.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
No build tool works in the default unprivileged runner container (no
Docker socket, no procfs, no FUSE). Run the docker job privileged with
the host Docker socket mounted, then use standard docker build/push.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Runner container has no /proc/self/uid_map (no user namespace support).
Chroot isolation doesn't need namespaces, only filesystem access.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The runner container lacks FUSE device access needed for overlay mounts.
VFS storage driver works without special privileges.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Act Runner job containers have no Docker socket access. Replace
docker build/push + skopeo with buildah which builds OCI images
without needing a daemon, and pushes with --tls-verify=false for HTTP.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
docker login/push require daemon.json insecure-registries config which
needs a dockerd restart (impossible in the Act Runner container).
Use skopeo copy with --dest-tls-verify=false to push over HTTP directly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There's no bun.lockb in the repo, so --frozen-lockfile fails
intermittently when pnpm cache is unavailable. Use plain bun install.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Buildx docker-container driver needs socket perms the runner lacks.
The host Docker daemon should already trust its local registry, so
skip insecure registry config and use plain docker build/push.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Gitea Act Runner can't restart dockerd to add insecure registries.
Switch to buildx with a BuildKit config that allows HTTP registries,
and write Docker credentials directly instead of using docker login.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Gitea Act Runner container has no systemd, service, or init.d.
Kill dockerd by PID and relaunch it directly after writing daemon.json.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Gitea Act Runner containers don't use systemd. Fall back to
service/init.d for restarting dockerd after configuring insecure registry.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
upload-artifact@v4 and download-artifact@v4 require GitHub.com's
artifact backend and are not supported on Gitea Actions (GHES).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
bun can't resolve transitive deps through pnpm's symlinked node_modules.
Running bun install creates a flat layout bun can resolve from.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove explicit version from pnpm/action-setup — it reads from
packageManager in package.json automatically.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces the minimal CI workflow with a complete build/release pipeline:
- lint, typecheck, test (parallel, every push/PR)
- build: TS + completions + bun binaries + RPM packaging
- docker: build & push all 4 images (mcpd, node-runner, python-runner, docmost-mcp)
- publish-rpm: upload RPM to Gitea packages
- deploy: update Portainer stack
Also adds scripts/link-package.sh shared helper to auto-link packages
to the repository (Gitea 1.24+ API with graceful fallback), called from
all build/publish scripts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Check via Gitea API whether the uploaded package is linked to the
repository and warn with manual linking URL if not (Gitea 1.22 has
no API for automated linking).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Gitea's auto-generated .repo file contains internal IPs. Use a manual
repo file with the public mysources.co.uk baseurl instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite the Plugin System section to make the extends/inheritance
mechanism clear — show that default extends gate + content-pipeline,
explain hook inheritance and conflict resolution rules.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Section 4 now uses --from-template instead of manual --docker-image
- Declarative YAML example uses fromTemplate + envFrom secretRef
- Backup section updated to git-based commands (was old JSON bundle)
- Consistent server naming (my-grafana from template, not bare grafana)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the repo directory already existed from a previous init (e.g.
local-only init without remote), the origin remote was missing. Now
initRepo() verifies and sets/updates the remote on every startup.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move backup SSH keys and repo URL from MCPD_BACKUP_REPO env var to a
"backup-ssh" secret in the database. Keys are auto-generated on first
init and stored back into the secret. Also fix ERR_HTTP_HEADERS_SENT
crash caused by reply.send() without return in routes when onSend hook
is registered.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Exempt /healthz and /health from rate limiter
- Increase rate limit from 500 to 2000 req/min
- Register backup routes even when disabled (status shows disabled)
- Guard restore endpoints with 503 when backup not configured
- Add retry with backoff on 429 in audit smoke tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two bugs: (1) empty string env var treated as enabled (use || instead of ??),
(2) health routes missing return reply causing double-send with onSend hook.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DB is source of truth with git as downstream replica. SSH key generated
on first start, all resource mutations committed as apply-compatible YAML.
Supports manual commit import, conflict resolution (DB wins), disaster
recovery (empty DB restores from git), and timeline branches on restore.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Persistent file cache in ~/.mcpctl/cache/proxymodel/ with LRU eviction
- Pause queue for temporarily holding MCP traffic
- Hot-reload watcher for custom stages and proxymodel definitions
- CLI: mcpctl cache list/clear/stats commands
- HTTP endpoints for cache and pause management
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>