Guided installer
pyplines-installer reads an installation document, shows a plan, and installs its
named targets. A document can contain a server, multiple runners, the operator CLI,
and the Action development CLI. Include only what that workstation needs.
The installer is a tooling package. Server and runner versions belong to the separate platform release group. Use a tooling release that includes the YAML commands described here; older releases support the compatibility commands below.
Prepare the workstation
Install the installer with Python 3.12+ in a virtual environment or using pipx:
python3 -m venv ~/.venvs/pyplines-installer
~/.venvs/pyplines-installer/bin/python -m pip install "pyplines-installer==$TOOLING_VERSION"
The following commands assume pyplines-installer is on your PATH.
| Target | Additional prerequisites |
|---|---|
pyplines-server, pyplines-runner | Linux with rootful Docker Engine, or macOS with Docker Desktop; Linux amd64/arm64 daemon, Engine 26+, Compose 2.24+ |
pyplines-action | Linux/macOS amd64/arm64; HTTPS access to GitHub release assets |
pyplines-cli | Linux/macOS; Python with venv/pip support and access to its Python package index |
Installing CLI targets does not require Docker. Authoring Actions requires the additional tools in Build your first Action. The installer does not install Docker or change host firewall rules. Windows, remote Docker daemons, rootless engines, and alternative macOS VM providers are outside the supported service configuration.
Create and review a configuration
pyplines-installer init
pyplines-installer validate
pyplines-installer run --dry-run
pyplines-installer run
init begins with your goal: local development, a server, a runner, Action tools,
or a custom combination. It offers local, server, runner, action, and
custom presets. Local setup includes the operator CLI and optionally Action tools. It writes YAML and
never installs resources or overwrites an existing file. The server and runner
presets contain endpoint and TLS settings to review before running them.
For automation or a source checkout, specify the preset and published versions:
pyplines-installer init --preset local --output development.yml --platform-version "$PLATFORM_VERSION" --tooling-version "$TOOLING_VERSION"
Released installers default tooling targets to their own version. Development
installers require an explicit published tooling version. Service presets use the
packaged supported platform version unless overridden. The generated YAML records
explicit versions; running it does not select a mutable latest release.
Commands default to installation.yml in the current directory. An explicit file
path remains supported. run checks prerequisites, shows component destinations,
and collects known required credentials before creating resources. New administrator
passwords are confirmed. Progress identifies the current component and operation;
password prompts pause the live display. Completion prints trust/login commands
and any required PATH setup. Unattended --yes runs require credential references
and never wait for terminal input.
Local development on Linux or macOS
A local installation includes development TLS, a private service network, and one
or more runners enrolled in pool local:
apiVersion: pyplines.installer/v1
name: development
state_directory: ./development-state
profile: local
versions:
platform: 2026.10.1rc17
tooling: 2026.10.3rc2
credentials:
administrator_password:
env: PYPLINES_ADMIN_PASSWORD
targets:
server:
component: pyplines-server
api_port: 8443
nats_port: 4222
runner:
component: pyplines-runner
server:
target: server
operator:
component: pyplines-cli
directory: ~/.local/bin
Replace the example versions with the selected published releases. server,
runner, and operator are instance names; component selects their installer.
A second runner can use another name and reference the same server. Additional
local servers need distinct api_port and nats_port values.
The local profile generates a development CA and server certificate valid for one year. Its CA signing key is discarded after issuance. It publishes HTTPS and NATS on host loopback and connects containers using their own network addresses. It creates a short-lived single-use enrollment and approves only the runner identity retained by the selected target. Remote-server runner targets retain the separate operator approval flow.
Interactive run asks for confirmation and prompts for required credentials when
they are unavailable. Use the same administrator password when resuming setup.
Once bootstrap and local runner approval are complete, retries need no password.
For unattended operation, supply the referenced credential and use:
pyplines-installer run development.yml --yes
pyplines-installer status development.yml
pyplines-installer doctor development.yml
After installation, the result prints the exact operator executable, CA
configuration command, and login command. Enter the administrator password from
setup. For this example, trust configuration points to
development-state/tls/server/ca.crt. No system or browser trust store is changed.
A pre-existing PYPLINES_CA_FILE overrides the CLI's saved CA setting.
The operator CLI is installed into a private, versioned Python environment below
the state directory. Its executable link is placed in the requested directory;
an existing unmanaged pyplines command is not overwritten. Follow the printed
PATH instructions or use the displayed absolute executable path.
Readiness does not configure a registry or an Environment. Continue with
Verify the installation, selecting pool local for
this profile. Local host ports and container-only advertised NATS make this a
workstation deployment; use explicit endpoints for shared installations.
Install the Action development CLI
An Action-only document does not need a platform version or Docker prerequisite:
apiVersion: pyplines.installer/v1
name: action-development
state_directory: ./.action-installer
versions:
tooling: 2026.10.3rc2
targets:
action:
component: pyplines-action
directory: ~/.local/bin
pyplines-installer run action-tools.yml --dry-run
pyplines-installer run action-tools.yml
pyplines-action version
The installer downloads the native Linux/macOS binary and SHA256SUMS directly
using Python HTTPS. Neither GitHub CLI nor curl is required. It verifies the
checksum and reported version before atomic installation. Failed verification
preserves the previous executable. Destination symlinks are rejected so another
package manager's installation is not overwritten.
Public assets can be downloaded anonymously. For private assets, supply
PYPLINES_GITHUB_TOKEN or GITHUB_TOKEN through your environment, or configure a
github_token credential reference. The token needs repository access and
Contents: read for fine-grained tokens. Authorization is not forwarded to a
release asset host after a redirect. See the
GitHub release asset API.
A successful, unchanged target is verified and reused without another download. The result reports the installed path and any PATH setup needed. Shell startup files are not edited automatically.
Explicit server and runner installations
Omit profile or use profile: explicit to supply your own TLS and endpoints:
apiVersion: pyplines.installer/v1
name: operations
state_directory: ./operations-state
versions:
platform: 2026.10.1rc17
credentials:
administrator_password:
file: ./credentials/admin-password
targets:
server:
component: pyplines-server
server_url: https://pyplines.example.com:8443
nats_url: tls://pyplines.example.com:4222
certificate: ./tls/server.crt
private_key: ./tls/server.key
ca_file: ./tls/ca.crt
The server certificate must cover every endpoint hostname. On macOS, it must
include the serverAuth Extended Key Usage. Provision DNS, certificates, and
firewall access before running this configuration.
A runner on another host refers to the existing server URL:
apiVersion: pyplines.installer/v1
name: worker
state_directory: ./worker-state
versions:
platform: 2026.10.1rc17
credentials:
enrollment_token:
env: PYPLINES_ENROLLMENT_TOKEN
targets:
runner:
component: pyplines-runner
server:
url: https://pyplines.example.com:8443
ca_file: ./tls/ca.crt
max_concurrent: 1
Create the enrollment credential and approve the runner following Install a runner. Pending approval is reported separately from readiness; the installer preserves the registered identity. If registration never completed and the token expired, supply a new token and rerun the document.
Use server: {target: NAME} for a server in the same document. This adds a
required dependency. depends_on: [NAME] expresses additional ordering, including
when a target connects through an explicit URL to a service managed by the same
file. Deployment order follows dependencies, not the order of YAML entries.
Credentials, paths, and target selection
Credentials must be references: {env: VARIABLE_NAME} or {file: ./private-file}.
Literal passwords and tokens are rejected. File credentials must be private
(chmod 600), nonempty, and not symlinks. Root credentials are defaults; a target
can override its applicable credential. Values are resolved only when needed and
are never written into installation state or the displayed plan.
All relative paths resolve against the YAML file's directory. ~ expands to the
current user's home. YAML aliases and duplicate keys are rejected.
pyplines-installer run development.yml --target runner --dry-run
pyplines-installer run development.yml --target runner --yes
pyplines-installer status development.yml --target runner
Selection includes required dependencies and shows them in the plan. Repeat
--target to select multiple targets. Prerequisite checks are read-only. Container
mount probes and checks needing downloaded images are deferred until apply.
State, retries, and migration
Keep the private state directory and the named Docker volumes. The state directory
contains installation-state.json, per-target service files or Python environments,
and generated TLS files. Server data and runner identities live in named volumes.
An interrupted run preserves completed targets. Failed targets are reported; their dependents are blocked while independent targets can complete. Rerun the same configuration to resume. State records image digests, binary checksums, ownership, and the Docker identity for service targets.
Removing a target from YAML retains its state and resources; the plan reports it as retained. Changing a saved target's configuration or version is rejected in this release. Create a separate tool target with a distinct destination for a new tooling version. Service upgrades and automatic rollback remain unsupported; follow the upgrade guidance.
To bring an existing managed service installation under a new document, explicitly reference it:
pyplines-installer init --from-directory ./previous-installation --name imported --output imported.yml
pyplines-installer run imported.yml --dry-run
pyplines-installer run imported.yml
This writes existing_installation references and preserves the original
configuration, directories, versions, and resource ownership. Keep the original
directories, including TLS files. An existing local profile imports its server and
runner. Incomplete enrollment/approval follows the explicit runner flow after
import. No existing installation is silently adopted.
Remove an installation
Review the exact managed resources before cleanup:
pyplines-installer uninstall development.yml --dry-run
pyplines-installer uninstall development.yml
Ordinary uninstall removes containers, owned networks, and installed CLI tools while retaining the database and runner identity volumes, development certificates, and state. Run the original YAML again to reinstall using that retained data.
For a fresh start, purge all managed resources, including persistent data:
pyplines-installer uninstall development.yml --purge --dry-run
pyplines-installer uninstall development.yml --purge
Purge permanently deletes the selected server database and runner identities. The
interactive command requires typing the installation name. For automation, review
the plan first, then use --purge --yes with global --json as needed.
If the YAML is missing or edited, use the recorded state directly:
pyplines-installer uninstall --directory ./development-state --purge
Cleanup includes recorded targets removed from YAML. To limit cleanup, repeat
--target NAME; dependent runners must be included before removing their server.
Saved Docker ownership and daemon identity are checked. Already missing resources
are accepted, and an interrupted cleanup can be rerun using the same command.
Unknown files and replaced CLI executables are retained and reported; state remains
until cleanup is complete. Finish failed cleanup before attempting another install.
Supplied TLS/credential files, user-authored YAML, shared networks and image caches,
Docker, and the installer package are retained. User-created operator CLI settings
and sessions are also outside installer cleanup. Runner registrations on external
servers remain until an operator revokes them. Removing a complete local server
with --purge deletes its database, including those local registrations.
Docker Desktop details
The installer respects Docker context selection and records the context, Unix endpoint, daemon ID, and architecture. A different context or a Docker Desktop factory reset is rejected before operating on saved services. Restore the original selection and data instead of deleting state to bypass the check.
The macOS CLI socket, usually ~/.docker/run/docker.sock, is separate from the
runner's /var/run/docker.sock inside the Linux VM. No Mac socket symlink is
required. Service images follow daemon architecture; the native Action binary
follows host architecture, including Apple Silicon detected through Rosetta.
Keep host files in Docker Desktop's shared locations. container_mounts_unavailable
means a container could not read its mounted files or see its VM socket; check File
sharing and container socket restrictions. Spaces and normal macOS symlink ancestors
are supported, but managed service and state directories cannot themselves be symlinks.
Compatibility commands
install server, install runner, install action, local, and
status/doctor --directory DIR remain available during deprecation. They preserve
the original state layouts and share the component installation engines. They are
hidden from the primary help output; use YAML for new installations. Existing
pyplines.installation/v1 documents remain accepted by install --config FILE.
The compatibility Action command also uses direct HTTPS downloads.
See the installer CLI reference for command options, endpoint semantics, and exit codes.

