FalcOps Documentation
FalcOps is a fast, focused DevOps control tool for developers: environment checks, projects, Docker, logs, and remote servers. It is CLI-first with an optional desktop app, and it is read-only by design — except for explicitly named single-container lifecycle actions and deployments you request.
Getting Started
FalcOps is in early development. The fastest way to try it today is from source. You need Node.js 20+ and pnpm. Docker and Git are optional and are probed at runtime.
git clone https://github.com/Hood117/FalcOps.git
cd FalcOps
pnpm install
pnpm falcops doctor
doctor checks the required tools and reports readiness. Most commands
accept --json for machine-readable output suited to automation, and
--help (for example falcops server --help) prints per-command
help.
Throughout these docs, commands are shown as falcops …. From source, prefix
them with pnpm (for example pnpm falcops status --json).
Installation
Windows app
The v0.2.0 release ships a single per-user NSIS installer
(FalcOps_0.2.0_x64-setup.exe) that needs no UAC prompt and uses the
WebView2 bootstrapper (the runtime downloads on demand). Builds are unsigned, so Windows
SmartScreen is expected to warn — verify the publisher before proceeding.
From source
git clone https://github.com/Hood117/FalcOps.git
cd FalcOps
pnpm install
pnpm build
pnpm falcops doctor
Requires Node.js 20+ and pnpm. Docker and Git are optional and are probed at runtime rather than at install time.
CLI Reference
Every command supports --json for automation. Exit codes follow a shared
convention documented per command below; in general 0 means success,
1 means a domain failure (such as an unavailable daemon or unreachable
server), and 2 means a CLI usage or internal error.
Environment and project
falcops doctor [--json] Check required tools and report readiness
falcops status [--json] Show working-tree status of the current repository
falcops project [--json] Show the detected surrounding project
falcops services [--json] Show services defined by the current project
falcops logs [<service>] [--lines <n>] [--json]
Show local logs for project services
falcops config [--json] Show the project's FalcOps configuration
-
doctorexits0when ready or degraded,1when blocked (a required tool is missing or failed). -
statusis read-only and exits0for clean and dirty trees alike,1outside a Git repository. -
projectexits0on success,1when detection fails. -
serviceslists services without starting anything and exits0even with zero services,1when project detection fails. -
logsperforms read-only tail reads of<working-directory>/logs/<service>.logand exits0on success (even with no logs),1for detection failures, unknown services, or unavailable logs. -
configexits0on success (even without configuration),1for detection failures or invalid configuration.
Local Docker
falcops docker [--json]
falcops docker services [--json]
falcops docker logs <container> [--lines <n>] [--json]
falcops docker start <container> [--json]
falcops docker stop <container> [--json]
falcops docker restart <container> [--json]
falcops docker images [--all] [--json]
falcops docker networks [--json]
falcops docker volumes [--json]
falcops docker inspect <container> [--json]
falcops docker stats [<container>...] [--json]
-
Inspection (daemon status, services, logs, images, networks, volumes, inspect, stats
snapshots) is read-only. Lifecycle commands (
start,stop,restart) act on exactly one explicitly named container — there are no bulk operations. -
docker statstakes read-only snapshots only: no streaming and no watch mode. Without identifiers it covers the running containers. -
Lifecycle commands exit
1when Docker is unavailable or the container is already in the requested state.
Remote servers
falcops server status <target> [--json]
falcops server exec <target> -- <command> [--json]
falcops server logs <target> -- <log-command> [--json]
falcops server docker <target> [--json]
falcops server docker services <target> [--all] [--json]
falcops server docker logs <target> <container> [--lines <n>] [--json]
falcops server docker stats <target> <container> [--json]
falcops server docker inspect <target> <container> [--json]
falcops server docker start|stop|restart <target> <container> [--json]
falcops server deploy <target> <artifact> [--json]
falcops server releases <target> [--json]
falcops server release verify <target> <release-id> [--json]
falcops server release rollback <target> <release-id> [--json]
-
Targets are
user@hostoruser@host:port(default port 22). IPv6 hosts must be bracketed (user@[::1],user@[::1]:2222). -
server execandserver logsrequire the--separator; everything after it is the remote command. Local options such as--jsonmust come before it. -
server execexits with the remote exit code when the command ran;server logsbehaves the same. Follow mode is rejected — remote log reads are single bounded batches. -
server deployships one packaged archive (.tar.gz,.tgz, or.zip) into a generated release directory under/opt/falcops/releases. Failed deployments may leave partial directories behind by design; they are reported as incomplete and never promoted automatically. -
server release verifychecks artifacts only — never application health.server release rollbackatomically switches the/opt/falcops/releases/currentlink to a verified release; it performs no restarts or health checks.
Docker
Local Docker Engine
FalcOps talks to the local daemon over the platform endpoint (named pipe on Windows,
socket on POSIX) using plain status queries. It uses no Docker SDK and no Docker CLI,
and TCP (DOCKER_HOST) is intentionally unsupported: local daemon only.
-
Read-only inspection: daemon status, container lists, logs (with
--linestail), images (--allincludes untagged), networks, volumes, single-containerinspect, andstatssnapshots. -
Explicit mutation only:
start,stop, andrestartact on exactly one named container at a time.
Remote Docker over SSH
Remote Docker answers run through fixed remote commands (docker info,
docker ps, docker logs --tail,
docker stats --no-stream, docker inspect,
docker start|stop|restart). There are no tunnels and no port forwarding.
-
serviceslists running containers by default (docker pssemantics);--allmaps todocker ps -a. - Container identifiers are validated locally before any SSH call.
- Lifecycle operates on one explicitly named container; unlike local lifecycle, already-in-state is not distinguished.
Remote Servers
Remote commands connect to one Linux/Unix server per invocation over SSH. Probes are
single read-only snapshots: server identity (hostname, OS, kernel, uptime), remote
Docker state, or one bounded log batch. Nothing is installed, written, or changed
remotely except by the explicit
deploy and release rollback flows.
Authentication
There is no credential storage, no config file, and no server profile. Credentials come from the environment only and are held in memory for the attempt:
| Variable | Meaning |
|---|---|
FALCOPS_SSH_PRIVATE_KEY |
PEM key content (wins over the others) |
FALCOPS_SSH_KEY_FILE |
Path to a PEM key file |
FALCOPS_SSH_PASSWORD |
Password authentication |
FALCOPS_SSH_PASSPHRASE |
Passphrase for an encrypted private key (optional) |
Without any of the first three, remote commands fail and tell you which variables to set. Values are never printed, logged, persisted, or embedded in errors.
Command semantics
-
server statusruns one SSH probe built from stock sources (uname,/etc/os-release,/proc/uptime). Missing uptime alone yields anulluptime, not a failure. -
server execis a transport: your command runs remotely and streams back unchanged. FalcOps adds nosudoand no shell wrapping. -
server logsnever invents a log command — you supply the remote command that fits the machine (for examplejournalctl -n 100 --no-pagerortail -n 100 /var/log/syslog).
Desktop App
The desktop app is an optional Tauri shell with a restrained native window. It mirrors the CLI's read-only behavior: arbitrary shell execution is never exposed, and the frontend reaches the backend only through a small typed command boundary.
- Projects: native folder selection plus read-only project detection and Git status.
- Overview: live environment diagnostics.
- Docker: daemon availability plus the container list. No lifecycle actions.
- Servers and Settings: static placeholders.
Exactly four backend commands exist: folder selection, project status, environment report, and Docker overview. Capabilities grant only folder picking — no shell, filesystem, sidecar, network, or cloud access.
Configuration
Project detection is pure filesystem inspection: it walks upward from the working directory, never executes anything, and never modifies files. The root is selected by marker priority (nearest directory wins within a priority):
falcops.json.gitpnpm-workspace.yaml/pnpm-workspace.ymlpackage.json- Compose file (
docker-compose.*/compose.*)
With no markers anywhere, the start directory itself is the root. The package manager is
inferred from root markers (pnpm > yarn >
npm > bun), and the project name resolves from
falcops.json name, then root package.json
name, then the directory name.
falcops.json is optional and intentionally minimal: only
name (a string) is read and unknown fields are ignored. Malformed JSON or a
non-string name is a structured configuration error.
falcops config prints the discovered configuration read-only; it exits
0 even without configuration and 1 for detection failures or
invalid configuration.
Service discovery
falcops services answers “what services exist?” from files only: root
package.json scripts, pnpm workspace member packages, and Compose
services: entries. Running state, health, ports, and all mutations are out
of scope.
Security
- Read-only by design. Inspection commands cannot start, stop, deploy, or modify anything. Mutation exists only where you name it explicitly: one container for lifecycle, one archive for deploy, one release for rollback.
- No credential storage. SSH credentials come from environment variables, live in process memory for one attempt, and are never printed, logged, persisted, or embedded in errors. Do not commit credentials.
- Local validation first. Deployment artifacts and remote container identifiers are validated locally — invalid input performs zero SSH calls.
-
Fixed remote commands. Remote Docker, status, deploy, and release
flows run fixed commands with no
sudo, no shell interpolation of your input, and no invented log commands. - Bounded reads. Log reads are single bounded batches; follow/streaming modes are rejected. Engine API responses are size-bounded.
- Safe errors. Failure messages are fixed per kind and presentation-safe: no hosts, credentials, paths, or raw remote output.
Troubleshooting
Exit codes
0— success (including ready-or-degraded for doctor).-
1— domain failure: blocked environment, unavailable Docker daemon, unreachable server, failed deployment, or unverifiable release. 2— CLI usage or internal error.
Common issues
- Doctor reports degraded: only an unresponsive Docker daemon is advisory. Everything else required is fail-closed — install the missing tool and re-run.
-
Remote command says credentials are missing: set one of
FALCOPS_SSH_PRIVATE_KEY,FALCOPS_SSH_KEY_FILE, orFALCOPS_SSH_PASSWORDin the environment. -
Deploy fails with “tar or unzip is not available”: the remote host
needs
tar(for.tar.gz/.tgz) orunzip(for.zip) installed. -
Server status shows no OS or uptime: OS detection needs
/etc/os-release(otherwise it falls back touname -s) and uptime needs/proc/uptime. - Windows SmartScreen warning: expected for unsigned builds — verify the publisher before proceeding.
-
Invalid artifact rejected before any connection:
deployments accept only existing non-empty
.tar.gz,.tgz, or.zipfiles with safe names — this is intentional local validation, not a server problem.
Run any command with --json to get a stable machine-readable result for
scripting around failures.