| eyebrow | Docs · Building | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| lede | A self-contained executable that runs on hosts with no PHP installed. Built by combining the PHAR with phpmicro from static-php-cli. ~20-25 MB. Linux, macOS, Windows. | |||||||||||||||||
| see_also |
|
|||||||||||||||||
| prev |
|
|||||||||||||||||
| next |
|
A static binary bundles the CLI's PHAR with a statically linked
PHP interpreter (phpmicro). The result is one file you can ship
to a Linux server, a Windows workstation, or a maintenance
laptop — no PHP install required on the target.
Built by static-php-cli (SPC). Expect ~20-25 MB depending on extension set.
| Requirement | Note |
|---|---|
| Everything from the PHAR build | The static binary needs the PHAR as input |
| A C toolchain | gcc or clang, make, autoconf, bison, re2c, libtool |
| ~2 GB free disk | SPC compiles PHP + OpenSSL + libxml2 + libzip from source |
| ~2 GB RAM during build | Compiler memory footprint |
First build is 20-40 minutes. Subsequent builds with a warm SPC cache are 3-5 minutes.
SPC's doctor --auto-fix installs the missing native
dependencies on Debian / Ubuntu / Fedora / Arch automatically.
-
Build the PHAR first. See PHAR build. The output
build/opcua-cli.pharis the input to the next steps. -
Install static-php-cli.
git clone --depth=1 https://github.com/crazywhalecc/static-php-cli.git spc-src cd spc-src composer install --no-dev --prefer-dist cd .. ./spc-src/bin/spc doctor --auto-fix
-
Download PHP + extension sources.
export SPC_EXTENSIONS="openssl,simplexml,dom,phar,posix,mbstring,tokenizer,sockets,ctype,fileinfo,filter,pcre,xml,xmlwriter,xmlreader,libxml" ./spc-src/bin/spc download \ --with-php=8.4 \ --for-extensions="$SPC_EXTENSIONS"
The extension list matches the official release builds. Trim for a smaller binary (see Customising).
-
Compile the
phpmicroSAPI../spc-src/bin/spc build "$SPC_EXTENSIONS" --build-microOutput:
spc-src/buildroot/bin/micro.sfx— a self-extracting PHP runtime with the chosen extensions baked in. -
Combine PHAR + micro SAPI.
./spc-src/bin/spc micro:combine build/opcua-cli.phar --output=opcua-cli chmod +x opcua-cli ./opcua-cli --version
Result:
opcua-cli(single file, 20-25 MB, no external runtime dependencies).
Default target. The official release pipeline uses
ubuntu-latest runners; reproduce locally on any glibc-based
Linux with PHP 8.2+ available.
Two strategies, ranked:
- Native build on an aarch64 host — same commands as
x86_64, on a Raspberry Pi 4/5, AWS Graviton, or
ubuntu-24.04-armrunner. Reliable and fast. - Cross-compile from x86_64 — pass
--arch=aarch64tospc build. SPC fetches a cross-toolchain on first use; the first build is ~40 minutes.
The official CI builds aarch64 natively; expect the same to be the smoother path.
| Host | Produces |
|---|---|
| Apple Silicon (M1/M2/M3/M4) | macos-arm64 |
| Intel | macos-x86_64 (Rosetta 2 won't run an arm64 binary on Intel) |
xcode-select --install covers the toolchain. spc doctor --auto-fix handles the rest.
Code signing: SPC does not sign. If you ship to non-technical
macOS users, sign with codesign + notarytool yourself —
otherwise Gatekeeper blocks the first launch.
For container images (FROM alpine, FROM scratch):
./spc-src/bin/spc build "$SPC_EXTENSIONS" --build-micro --with-libc=muslThe musl binary is ~15-18 MB (slightly smaller than glibc) and runs unchanged on Alpine, minimal containers, and any glibc system.
Experimental but wired into CI (continue-on-error: true on the
release workflow). Requires the MSYS2 + mingw-w64 toolchain. See
the
SPC Windows build guide.
The CLI itself runs fine on Windows — posix_isatty is guarded
by function_exists() in ConsoleOutput.php, with a TERM
env-var fallback.
Pass --with-php=8.5 (or 8.3, 8.2) to the download step. The
combine step uses whatever PHP version was built most recently.
The runtime minimum is shorter than the official build's set:
openssl,simplexml,dom,phar,mbstring,ctype,pcre,xml,xmlwriter,libxml
| Extension | Status | Effect of removing |
|---|---|---|
posix |
Optional | TTY detection falls back to TERM env var |
sockets |
Transitive pin | Not used directly by the CLI |
fileinfo |
Defensive | Some Composer packages probe for it |
tokenizer |
Defensive | Same |
filter |
Defensive | Same |
xmlreader |
Defensive | Same |
Dropping the optional / defensive set trims ~3 MB. Update
SPC_EXTENSIONS and re-run download + build (the cache is
per-extension-set).
Edit box.json.dist at the project root. See PHAR build ·
Configuration.
| Where | How |
|---|---|
| GitHub Releases | Attach per-platform binaries to a tagged release |
| Internal artefact server | Same — upload binaries as build artefacts |
Docker FROM scratch |
COPY opcua-cli /opcua-cli, ENTRYPOINT ["/opcua-cli"] — ~22 MB image |
| Operator USB sticks | Single file, works without install |
For container images, the musl variant produces a ~20 MB image
including the opcua-cli binary. With FROM scratch, the
image is the binary plus its dependencies — minimal attack
surface.
./opcua-cli --version
# → opcua-cli 4.4.0
./opcua-cli --help
# Should print the command catalogue
# End-to-end smoke test:
./opcua-cli endpoints opc.tcp://localhost:4840If --help works but endpoints fails, the issue is likely
networking, not the binary. If --version fails outright, the
binary is broken — review the build logs.
The repo's .github/workflows/release-binaries.yml runs this
flow on tag push, producing binaries for:
linux-x86_64linux-aarch64macos-arm64linux-musl(Alpine-compatible)windows-x86_64(best-effort,continue-on-error: true)
The artefacts are attached to the GitHub Release matching the tag. Most users download from there rather than building.
| Aspect | PHAR | Static binary |
|---|---|---|
| Requires PHP on host | Yes (8.2+) | No |
| Size | ~650 KB | ~22 MB |
| Build time | Seconds | 20-40 min first build |
| Architecture-portable | Yes | Per-architecture |
| Startup cost | ~50 ms | ~10 ms |
| Best for | Dev workstations | Servers, appliances, USB sticks |
For deployments where you control the host (you can install PHP), the PHAR is the right pick. The static binary is for hosts where PHP is not allowed or available.
| Symptom | Likely cause |
|---|---|
spc doctor reports missing tools |
Install via distro package manager |
spc download hits GitHub rate limit |
Set GITHUB_TOKEN |
| Build OOMs on a small VM | Need ≥ 2 GB RAM; rent a beefier build host |
| Binary runs but exits with library error | Missing extension in SPC_EXTENSIONS — rebuild with the full set |
| Binary too large | Trim extensions; switch to musl |
For deeper diagnostics see Troubleshooting.