Skip to content

build: make UPX packing opt-in via COMPRESS env var#2429

Merged
dunglas merged 3 commits into
mainfrom
feat/upx-opt-in
May 16, 2026
Merged

build: make UPX packing opt-in via COMPRESS env var#2429
dunglas merged 3 commits into
mainfrom
feat/upx-opt-in

Conversation

@dunglas
Copy link
Copy Markdown
Member

@dunglas dunglas commented May 16, 2026

Summary

UPX is now disabled by default for the static build. To pack the binary with UPX (Linux only), set COMPRESS=1 at build time. The previous NO_COMPRESS flag is removed; CI invocations and the static-builder-{musl,gnu} Dockerfiles were updated accordingly. Docs (all locales) were refreshed.

Why drop UPX from the default?

  • AV false positives. UPX-packed binaries get flagged routinely on Windows and macOS, generating recurring support friction for end users.
  • Permanent memory cost. UPX decompresses the whole binary into anonymous memory at launch, so the OS can no longer share read-only text pages across processes or demand-page from disk. For a long-running server with workers, the savings on disk are paid back continuously in RAM.
  • Startup latency. ~100–300 ms added per launch — noticeable for container cold starts and test runs.
  • Tooling friction. Complicates debugging, core dumps, SBOM/attestation, and trips up some security scanners.
  • Modest upside. ~60% size reduction is nice, but FrankenPHP is mostly distributed via Docker layers (cached) or downloaded once per host. If artifact size is the concern, xz-compressing the release asset gives similar savings without any of the runtime downsides.

Users who still want a packed binary can opt in explicitly with COMPRESS=1.

UPX is now disabled by default. Set COMPRESS=1 at build time to
restore the previous behavior on Linux.
Copilot AI review requested due to automatic review settings May 16, 2026 10:43
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR changes the static build pipeline so UPX packing is disabled by default and becomes opt-in via a new COMPRESS environment variable, with CI and documentation updates to match.

Changes:

  • Replace NO_COMPRESS with COMPRESS and make UPX packing opt-in in build-static.sh.
  • Update static-builder Dockerfiles and GitHub Actions workflows to stop relying on NO_COMPRESS.
  • Refresh static-build documentation across locales to describe COMPRESS.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
static-builder-musl.Dockerfile Replaces NO_COMPRESS build arg with COMPRESS for static musl builder.
static-builder-gnu.Dockerfile Replaces NO_COMPRESS build arg with COMPRESS for static GNU builder.
build-static.sh Switches UPX packing logic from default-on (unless NO_COMPRESS) to opt-in (COMPRESS).
.github/workflows/static.yaml Removes NO_COMPRESS usage from static release workflow invocations.
.github/workflows/docker.yaml Removes NO_COMPRESS bake arg injection for Docker image builds.
docs/static.md Documents COMPRESS instead of NO_COMPRESS for static builds.
docs/embed.md Updates embed docs to say UPX packing is optional via COMPRESS=1.
docs/tr/embed.md Same embed doc update (TR).
docs/ru/static.md Documents COMPRESS instead of NO_COMPRESS (RU).
docs/ru/embed.md Updates embed docs to optional UPX packing via COMPRESS=1 (RU).
docs/pt-br/static.md Documents COMPRESS instead of NO_COMPRESS (PT-BR).
docs/pt-br/embed.md Updates embed docs to optional UPX packing via COMPRESS=1 (PT-BR).
docs/ja/static.md Documents COMPRESS instead of NO_COMPRESS (JA).
docs/ja/embed.md Updates embed docs to optional UPX packing via COMPRESS=1 (JA).
docs/fr/static.md Documents COMPRESS instead of NO_COMPRESS (FR).
docs/fr/embed.md Updates embed docs to optional UPX packing via COMPRESS=1 (FR).
docs/es/static.md Documents COMPRESS instead of NO_COMPRESS (ES).
docs/es/embed.md Updates embed docs to optional UPX packing via COMPRESS=1 (ES).
docs/cn/static.md Documents COMPRESS instead of NO_COMPRESS (CN).
docs/cn/embed.md Updates embed docs to optional UPX packing via COMPRESS=1 (CN).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread build-static.sh
Comment thread .github/workflows/docker.yaml
Comment thread docs/static.md Outdated
Comment thread docs/es/static.md Outdated
Comment thread docs/fr/static.md Outdated
Comment thread docs/pt-br/static.md Outdated
Comment thread docs/ja/static.md Outdated
Comment thread docs/cn/static.md Outdated
Comment thread docs/ru/static.md Outdated
dunglas added 2 commits May 16, 2026 14:00
- alpine.Dockerfile: switch the dynamic build to the new COMPRESS
  semantics; it still defaulted to UPX-packing because it had its
  own NO_COMPRESS check that the PR missed.
- build-static.sh: document COMPRESS in the supported-variables
  header and note that DEBUG_SYMBOLS takes precedence.
- docs/*: clarify that COMPRESS is read as "set to 1" and is
  ignored when DEBUG_SYMBOLS is set.
caddytest's default 5s http.Client.Timeout covers the whole roundtrip,
including body reads. On emulated armv7 the SSE chain
(WriteFile -> e-dant/watcher -> mercure -> client) doesn't fit in 5s
and the test dies with "Client.Timeout or context cancellation while
reading body".

Bump to 30s — generous enough for the slow runners (~5-6s actual)
while keeping a bounded failure mode if the marker never arrives.
Same fix is in #2431; carrying it here so this PR's CI does not
trip on the unrelated flake.
Copilot AI review requested due to automatic review settings May 16, 2026 14:42
@dunglas
Copy link
Copy Markdown
Member Author

dunglas commented May 16, 2026

Added a cherry-pick of the hotreload test timeout fix from #2431 so this PR's CI does not trip on that unrelated armv7 flake. The commit will be a no-op once #2431 lands and this branch is rebased (git detects the duplicate via patch-id).

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 2 comments.

Comment thread build-static.sh
Comment thread alpine.Dockerfile
@dunglas dunglas merged commit 1a03bc2 into main May 16, 2026
95 of 99 checks passed
@dunglas dunglas deleted the feat/upx-opt-in branch May 16, 2026 16:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants