next is mergeable into main at any time; everything on it is reviewed. main already carries the 1.0.0 milestone (#118); this is what landed since.
On the branch:
Four settings the README documented but pixa did not know (access_control_allow_origin, upstream_fetch_timeout, upstream_max_response_size, downstream_timeout) now exist, with PIXA_ variables and the old fixed values as defaults; before, following the README aborted startup (#61).
The pixad user in the image has a fixed uid and gid, 65532, instead of the first free uid (1000), so on first deploy the data directory is no longer handed to the host's first login account (#151).
README.md no longer tells operators to set trusted_proxies to the proxy's own address (for a proxy on the Docker host that put every user behind one login limit); it says how to read the right address from the request log. It also says signatures keep their base64url padding, with real example values (#150).
The Dockerfile installs its build dependencies through script/bootstrap instead of its own copies, and builds with -trimpath -s -w (#95).
The database migrations moved to internal/db/migrations/ as 000_migration.sql and 001_schema.sql, contents unchanged; an existing database runs nothing again (#96).
The cache statistics report what is actually cached, fetched and transcoded; they read tables nothing wrote and two counters never moved (#56).
Cache-Controlmax-age never outlives an expiring signed or encrypted image URL: the whole seconds left until expiry, at most one year; a URL with no expiry keeps one year (#63).
To know before merging: the host directory for /var/lib/pixa is now owned by 65532:65532 after the first start; README.md "Running under upaas" says so. With this merged, the two fixes the first deploy (#147) waits for are on main.
Model: opus-5-5
`next` is mergeable into `main` at any time; everything on it is reviewed. `main` already carries the 1.0.0 milestone (https://git.eeqj.de/sneak/pixa/pulls/118); this is what landed since.
On the branch:
- Four settings the README documented but pixa did not know (`access_control_allow_origin`, `upstream_fetch_timeout`, `upstream_max_response_size`, `downstream_timeout`) now exist, with `PIXA_` variables and the old fixed values as defaults; before, following the README aborted startup (https://git.eeqj.de/sneak/pixa/issues/61).
- The `pixad` user in the image has a fixed uid and gid, 65532, instead of the first free uid (1000), so on first deploy the data directory is no longer handed to the host's first login account (https://git.eeqj.de/sneak/pixa/issues/151).
- `README.md` no longer tells operators to set `trusted_proxies` to the proxy's own address (for a proxy on the Docker host that put every user behind one login limit); it says how to read the right address from the request log. It also says signatures keep their base64url padding, with real example values (https://git.eeqj.de/sneak/pixa/issues/150).
- The `Dockerfile` installs its build dependencies through `script/bootstrap` instead of its own copies, and builds with `-trimpath -s -w` (https://git.eeqj.de/sneak/pixa/issues/95).
- The database migrations moved to `internal/db/migrations/` as `000_migration.sql` and `001_schema.sql`, contents unchanged; an existing database runs nothing again (https://git.eeqj.de/sneak/pixa/issues/96).
- The cache statistics report what is actually cached, fetched and transcoded; they read tables nothing wrote and two counters never moved (https://git.eeqj.de/sneak/pixa/issues/56).
- `Cache-Control` `max-age` never outlives an expiring signed or encrypted image URL: the whole seconds left until expiry, at most one year; a URL with no expiry keeps one year (https://git.eeqj.de/sneak/pixa/issues/63).
To know before merging: the host directory for `/var/lib/pixa` is now owned by 65532:65532 after the first start; `README.md` "Running under upaas" says so. With this merged, the two fixes the first deploy (https://git.eeqj.de/sneak/pixa/pulls/147) waits for are on `main`.
Model: opus-5-5
clawbot
self-assigned this 2026-09-29 03:52:11 +02:00
Both image routes sent Cache-Control: public, max-age=31536000,
immutable unconditionally, so a browser or proxy could keep serving an
image for a year after its signed or encrypted URL had expired. max-age
is now the whole seconds left until the URL expires, never negative and
at most one year; a URL with no expiry keeps one year. The 304 answer
uses the same value. An encrypted URL's expiry now reaches
ImageRequest.Expires through ToImageRequest. immutable stays: freshness
now ends no later than the URL's expiry. README.md documents the header.
Model: opus-5-5
adduser took the first free uid, 1000, and the entrypoint gives a
bind-mounted /var/lib/pixa to pixad, so on the host a person's login
account ended up owning pixa's database and cache. The image now creates
the pixad group with gid 65532 and the pixad user with uid 65532, which
host login and system accounts do not use. The first-run step of
"Running under upaas" in README.md names the uid and gid.
Model: opus-5-5
Cache.Stats read request_cache and output_content, which nothing
writes, so TotalItems and TotalSizeBytes were always 0. They now count
source_content plus variant_content and use UsageBytes; a disabled disk
cache reports 0 for both. The upstream fetch count and bytes and the
transform count never moved: Get now passes the bytes it fetched
(including those read before a failed body read) and counts each
successful transcode. Hits, misses and these counters are written with
context.WithoutCancel, so a client disconnect or the request timeout no
longer loses them. The unused tables stay; metaCache is #70.
Model: opus-5-5
The README told operators to set trusted_proxies to the proxy's own
address. A proxy on the Docker host that connects over 127.0.0.1 reaches
pixa from the Docker network's gateway, so that advice made pixa count
every user as one client for the login limit. The login-limit paragraph,
the trusted_proxies entry and config.example.yml now say to use the
address pixa sees for requests through the proxy, that a proxy connecting
through another host address is seen with that address, and how to read
it from the request log.
The signature section now says sig is base64url with the = padding
kept, since pixa compares it exactly, and shows the example's sig for a
stated key, computed with pixa's signer.
Model: opus-5-5
REPO_POLICIES.md puts migrations in internal/db/migrations/ as
000_migration.sql and 001_schema.sql. The two files move there with
their contents unchanged. go:embed cannot reach outside its own
package, so internal/db/migrations has a small package that embeds
them, and internal/database reads them through its FS(). The database
package stays where CONVENTIONS.md puts it; moving it would change
existing test files in other packages.
The version still comes from the filename prefix, so a database that
has recorded versions 0 and 1 runs neither again. A new test applies
the migrations twice to one database file and checks that the second
run applies nothing.
Model: opus-5-5
README.md documented access_control_allow_origin,
upstream_fetch_timeout, upstream_max_response_size and
downstream_timeout, but pixa did not know them, so a config following
the README aborted startup. Each is now a setting with its PIXA_
variable, defaulting to the value that was fixed in the code: *, 30s,
50 MiB and 60s. Durations are Go duration strings and must be positive;
the size is whole bytes, at most 1 GiB. The origin is * or one http or
https origin written exactly as a browser sends it; anything else
aborts startup. downstream_timeout sets both the server's write timeout
and the per-request timeout. The owner approved the edits to existing
tests.
Model: opus-5-5
The Dockerfile lint and build stages and Dockerfile.lint each carried
their own apk add list, a copy of what script/bootstrap installs. They
now copy script/, go.mod and go.sum and run script/bootstrap, so that
layer is reused until one of those changes. script/bootstrap gains a C
compiler check: the golang image has none, and cgo needs one.
The build adds -trimpath and -s -w; CGO_ENABLED=1 stays, as govips
links libvips. ARG VERSION moves to just above the build, so a new
version reruns neither script/bootstrap nor the tests.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
nextis mergeable intomainat any time; everything on it is reviewed.mainalready carries the 1.0.0 milestone (#118); this is what landed since.On the branch:
access_control_allow_origin,upstream_fetch_timeout,upstream_max_response_size,downstream_timeout) now exist, withPIXA_variables and the old fixed values as defaults; before, following the README aborted startup (#61).pixaduser in the image has a fixed uid and gid, 65532, instead of the first free uid (1000), so on first deploy the data directory is no longer handed to the host's first login account (#151).README.mdno longer tells operators to settrusted_proxiesto the proxy's own address (for a proxy on the Docker host that put every user behind one login limit); it says how to read the right address from the request log. It also says signatures keep their base64url padding, with real example values (#150).Dockerfileinstalls its build dependencies throughscript/bootstrapinstead of its own copies, and builds with-trimpath -s -w(#95).internal/db/migrations/as000_migration.sqland001_schema.sql, contents unchanged; an existing database runs nothing again (#96).Cache-Controlmax-agenever outlives an expiring signed or encrypted image URL: the whole seconds left until expiry, at most one year; a URL with no expiry keeps one year (#63).To know before merging: the host directory for
/var/lib/pixais now owned by 65532:65532 after the first start;README.md"Running under upaas" says so. With this merged, the two fixes the first deploy (#147) waits for are onmain.Model: opus-5-5
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.