Skip to content

Build the image on Debian trixie for libvips 8.16 - #69

Open
Joker666 wants to merge 1 commit into
feat/delivery-layerfrom
chore/libvips-8.16-image
Open

Build the image on Debian trixie for libvips 8.16#69
Joker666 wants to merge 1 commit into
feat/delivery-layerfrom
chore/libvips-8.16-image

Conversation

@Joker666

@Joker666 Joker666 commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Stack (merge bottom-up)

  1. Restructure processing and service, and close the geometry compatibility gaps #66 Restructure processing and service, and close the geometry compatibility gaps
  2. Process animated sources frame by frame #67 Process animated sources frame by frame
  3. Add the imgproxy delivery layer #68 Add the imgproxy delivery layer
  4. Build the image on Debian trixie for libvips 8.16 #69 Build the image on Debian trixie for libvips 8.16
  5. Correct quality precedence and cache-hit header consistency #70 Correct quality precedence and cache-hit header consistency
  6. Bring the remaining docs up to date #71 Bring the remaining docs up to date
  7. Let width and height fill in a resize the type created #72 Let width and height fill in a resize the type created
  8. Close the roadmap's remaining known gaps #73 Close the roadmap's remaining known gaps
  9. Implement the Pro options that were only ever cheap #74 Implement the Pro options that were only ever cheap
  10. Run the pipeline in imgproxy's stage order #75 Run the pipeline in imgproxy's stage order

Each PR targets the one before it, so its diff shows only its own change. Together they make up the 0.18.0 release.

Stacked on #68.

Ubuntu 24.04 ships libvips 8.15.1, which is why HEIF output failed at encode time with Unsupported compression and why preserve_hdr had nothing to attach its gain map to. Trixie ships 8.16.1.

What the build surfaced

Getting AVIF and HEIF actually working took one more step. Debian packages libheif's codecs as plugins that libvips only Recommends, so a --no-install-recommends image registers savers for both formats and then cannot encode with either — exactly the failure the startup probe now reports as an unsupported format rather than a 500. libheif-plugin-aomenc and libheif-plugin-x265 are named explicitly, with dav1d and libde265 for decoding AVIF and HEIF sources.

A .dockerignore was missing. COPY . . was shipping the local target/ directory into the build context; with a couple of gigabytes of debug artefacts in it, the build ran the builder out of disk. This was pre-existing, just never large enough to fail before.

Also here

  • A dependency-only build layer, so editing imgforge's sources no longer recompiles every crate.
  • A non-root user. An image proxy decodes whatever the internet hands it, which is the last place to be running as root.
  • A HEALTHCHECK pointing at the new /health endpoint.

Verified by encoding all seven output formats through a running container.

Validation

cargo fmt -- --check
cargo clippy --all-targets -- -D warnings
cargo test --all -- --test-threads=1

Plus a real image build, and a container serving every output format, Accept negotiation, the caching headers, and an animated GIF resize.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 095397d06a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .dockerignore Outdated

# Local tooling and editor state.
.agents/
.cargo/

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve Cargo metric-name configuration in Docker builds

Ignoring .cargo/ drops the checked-in config.toml from every Docker build, even though that file sets the compile-time AXUM_HTTP_* names consumed by axum-prometheus. Consequently the published binary exports the crate's default metric names rather than the http_requests_duration_seconds and related names used by the repository's dashboards and monitoring documentation, silently breaking those queries; retain this config in the build context or set the same variables in the builder.

Useful? React with 👍 / 👎.

Comment thread Dockerfile Outdated
# Matches IMGFORGE_HEALTH_CHECK_PATH's default. A deployment that renames it
# should override this too.
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl --fail --silent http://127.0.0.1:3000/health || exit 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Probe the configured listener and route

When a container sets IMGFORGE_BIND to another port, IMGFORGE_PATH_PREFIX, or IMGFORGE_HEALTH_CHECK_PATH, server.rs moves the health endpoint but this probe continues requesting the fixed 127.0.0.1:3000/health. curl --help all defines --fail as failing on HTTP errors, so the resulting connection error or 404 marks a healthy customized container unhealthy; construct the probe from the runtime settings or use an invariant endpoint.

Useful? React with 👍 / 👎.

Comment thread doc/3_configuration.md
| `RUST_LOG` | Equivalent to `IMGFORGE_LOG_LEVEL`. Pick one and use it consistently. |
| `HTTP_PROXY` / `HTTPS_PROXY` | Honoured by `reqwest` for outbound source fetches. |

Boolean variables accept `1`, `t`, `true`, `yes`, and `on`, case-insensitively; anything else is false.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Do not advertise unsupported security booleans

This blanket statement is false for IMGFORGE_ALLOW_UNSIGNED, IMGFORGE_ALLOW_SECURITY_OPTIONS, and IMGFORGE_ONLY_PRESETS: Config::from_env still enables each only when the lowercased value equals "true". In particular, an operator following this documentation and setting IMGFORGE_ONLY_PRESETS=1 believes arbitrary transformations are blocked while the restriction is actually disabled, so either route these settings through bool_var or document their narrower syntax.

AGENTS.md reference: AGENTS.md:L27-L27

Useful? React with 👍 / 👎.

@Joker666

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0bec0b1e8b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Dockerfile
COPY --from=builder /usr/src/imgforge/target/release/imgforge .
COPY --from=builder /usr/src/imgforge/target/release/imgforge /usr/local/bin/imgforge

USER imgforge

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Provision writable cache storage before dropping privileges

When the documented disk or hybrid cache configuration is used, switching to USER imgforge leaves the cache mount unwritable: a fresh named volume at /var/cache/imgforge is root-owned, while deployment/deploy.sh chowns its bind-mounted directory to the host user rather than the container user's UID. FsDeviceBuilder must create its storage files there, so these supported container configurations fail during cache initialization and the server never starts. Create and chown the intended mountpoint to a stable container UID and update the deployment permissions before dropping privileges.

Useful? React with 👍 / 👎.

Comment thread Dockerfile Outdated
# server no longer answers on and reported unhealthy while working perfectly.
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl --fail --silent \
"http://127.0.0.1:${IMGFORGE_BIND##*:}${IMGFORGE_PATH_PREFIX}${IMGFORGE_HEALTH_CHECK_PATH}" || exit 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Normalize health-check paths before concatenation

When operators use the documented normalized forms, such as IMGFORGE_PATH_PREFIX=imgforge/ or IMGFORGE_HEALTH_CHECK_PATH=health, the application adds the leading slash and removes trailing slashes, but this probe concatenates the raw environment strings. The first example therefore produces http://127.0.0.1:3000imgforge//health while the live route is /imgforge/health, marking the container unhealthy. Fresh evidence after the earlier hard-coded-probe fix is that the replacement still bypasses normalize_path_prefix and normalize_health_check_path; mirror that normalization in the shell command or probe an invariant route.

Useful? React with 👍 / 👎.

@Joker666
Joker666 force-pushed the chore/libvips-8.16-image branch from 0bec0b1 to 912ed54 Compare August 17, 2026 05:05
@Joker666

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 912ed54e3a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Dockerfile Outdated
health="${health#/}"; health="${health%/}"; \
health="${health:-health}"; \
curl --fail --silent \
"http://127.0.0.1:${IMGFORGE_BIND##*:}${prefix:+/$prefix}/${health}" || exit 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor the address portion of IMGFORGE_BIND

When IMGFORGE_BIND selects a valid non-default interface, such as 127.0.0.2:3000 or a container-interface address, the server listens only there while this probe still connects to 127.0.0.1, so Docker reports the working container as unhealthy. Fresh evidence after the earlier configurable-probe fix is that the replacement extracts only ${IMGFORGE_BIND##*:} and continues to hard-code the host; derive a probe address from the configured bind value, translating wildcard addresses to an appropriate loopback address.

Useful? React with 👍 / 👎.

@Joker666
Joker666 force-pushed the chore/libvips-8.16-image branch from 912ed54 to e7f2b4b Compare August 21, 2026 03:53
@Joker666

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e7f2b4b551

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Dockerfile Outdated
Comment on lines +129 to +131
prefix="${prefix#/}"; prefix="${prefix%/}"; \
health="${IMGFORGE_HEALTH_CHECK_PATH:-health}"; \
health="${health#/}"; health="${health%/}"; \

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Match the server's full path normalization

When either path variable contains whitespace or repeated surrounding slashes, such as IMGFORGE_PATH_PREFIX=' //imgforge// ', the server accepts it as /imgforge because normalize_path_prefix and normalize_health_check_path use trim().trim_matches('/'), but this probe removes only one slash from each end and never trims whitespace. It therefore requests a malformed or different route and marks the healthy container unhealthy. Fresh evidence after the earlier normalization fix is that the replacement still implements weaker normalization than the configuration helpers it claims to mirror.

Useful? React with 👍 / 👎.

@Joker666
Joker666 force-pushed the chore/libvips-8.16-image branch from e7f2b4b to a28a3d6 Compare August 21, 2026 06:26
@Joker666
Joker666 force-pushed the chore/libvips-8.16-image branch from a28a3d6 to 2b28a99 Compare August 21, 2026 19:03
@Joker666

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2b28a99865

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Dockerfile Outdated
Comment on lines +121 to +122
CMD bind="${IMGFORGE_BIND:-3000}"; \
port="${bind##*:}"; \

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Trim the bind value before constructing the probe

When IMGFORGE_BIND contains surrounding whitespace, the server accepts it because normalize_bind_address trims the value, but the health check retains that whitespace. For example, IMGFORGE_BIND=' 3000 ' binds the server to 0.0.0.0:3000 while producing a curl URL whose port contains spaces, so Docker marks the healthy container unhealthy; trim bind with the same semantics before splitting it.

Useful? React with 👍 / 👎.

Comment thread Dockerfile Outdated
Comment on lines +139 to +140
curl --fail --silent \
"http://${host}:${port}${prefix:+/$prefix}/${health}" || exit 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Bypass outbound proxies for the local health probe

When the container has lowercase http_proxy or ALL_PROXY configured for source fetching and the health-check target is absent from NO_PROXY, curl sends this local probe through the outbound proxy, which commonly cannot reach the container listener and therefore reports it unhealthy. curl --manual documents that proxy environment variables are equivalent to --proxy and that NO_PROXY controls bypasses; force this probe to remain local with --noproxy '*'.

Useful? React with 👍 / 👎.

@Joker666
Joker666 force-pushed the chore/libvips-8.16-image branch from 2b28a99 to 4e4dedd Compare August 21, 2026 21:13
@Joker666
Joker666 force-pushed the chore/libvips-8.16-image branch 2 times, most recently from a1e0209 to f7f2be9 Compare August 21, 2026 23:44
@Joker666
Joker666 force-pushed the chore/libvips-8.16-image branch from f7f2be9 to 2c30b01 Compare August 21, 2026 23:53
@Joker666
Joker666 force-pushed the chore/libvips-8.16-image branch 8 times, most recently from 99105a4 to 67bda1b Compare August 22, 2026 01:12
Ubuntu 24.04 ships libvips 8.15.1, which is why HEIF output failed at
encode time with "Unsupported compression" and why preserve_hdr had
nothing to attach its gain map to. Trixie ships 8.16.1.

Getting AVIF and HEIF actually working took one more step: Debian
packages libheif's codecs as plugins that libvips only Recommends, so a
--no-install-recommends image registers savers for both formats and then
cannot encode with either. Verified by encoding all seven output formats
through a running container, along with Accept negotiation, the caching
headers, and an animated GIF surviving a resize with its four frames.

Also here because the build surfaced them: a .dockerignore, without which
COPY . . shipped the local target directory into the build context and
ran the builder out of disk; a dependency-only build layer; a non-root
user; and a HEALTHCHECK pointing at the new /health endpoint.
@Joker666
Joker666 force-pushed the chore/libvips-8.16-image branch from 67bda1b to 2d8047c Compare August 22, 2026 01:23
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.

1 participant