Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8375060
fix(release): name the local tags that differ from origin
peaklabs-dev Nov 2, 2026
38bbcf7
ci: upload the list of the manifests to delete in every run
peaklabs-dev Nov 2, 2026
387ba14
feat(scripts): sync the manifest cleanup with Coolify
peaklabs-dev Nov 9, 2026
7119216
ci: disable the manifest cleanup after a failed run
peaklabs-dev Nov 9, 2026
86ac273
docs(release): merge next into main only on the day of the release
peaklabs-dev Nov 9, 2026
a978c6f
feat(release): write the changelog from change files
peaklabs-dev Nov 9, 2026
3fdb677
fix(release): make an unsigned release commit when git cannot sign
peaklabs-dev Nov 9, 2026
2d3468d
refactor(release): name the upstream version upstream
peaklabs-dev Nov 9, 2026
363b91e
docs(release): simplify the push warning and PR versions
peaklabs-dev Nov 9, 2026
2b184bd
ci: bump GitHub Actions to the latest releases
peaklabs-dev Nov 9, 2026
901a7ec
chore(lint): bump jactionlint from v2.4.0 to v2.5.0
peaklabs-dev Nov 9, 2026
a447a3c
feat(image): move the home of nonroot to /home/nonroot
peaklabs-dev Nov 9, 2026
93c975f
fix(image): list a directory once in the SBOM document
peaklabs-dev Nov 9, 2026
59c264c
refactor(image): read the root of the SBOM document from ROOT_DIR
peaklabs-dev Nov 9, 2026
904b621
fix(image): make the SBOM document valid against its schema
peaklabs-dev Nov 9, 2026
55684ba
test: wait for locks the healthcheck holds briefly
peaklabs-dev Nov 9, 2026
5363312
chore: write the brand as PeakImages
peaklabs-dev Nov 11, 2026
9586317
fix(image): let scanners find the right packages and the OS
peaklabs-dev Nov 10, 2026
c034bf4
docs: add a trademark notice to README.md
peaklabs-dev Nov 10, 2026
1af0a8b
refactor(release): name upstream lines with a leading v
peaklabs-dev Nov 10, 2026
112250b
fix(release): add the refactored type to change files
peaklabs-dev Nov 11, 2026
b348d39
build(image): bump Alpine from v3.24.3 to v3.24.4
peaklabs-dev Nov 11, 2026
601e228
fix(image): check the health of databases without a lock
peaklabs-dev Nov 11, 2026
4f45cef
docs: describe the home of nonroot as a security change
peaklabs-dev Nov 11, 2026
41139dd
test: check what the image does, not how it is built
peaklabs-dev Nov 12, 2026
7e28ce5
feat(image): streamline image labels
peaklabs-dev Nov 12, 2026
9960454
style(image): remove comments that repeat the build steps
peaklabs-dev Nov 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .changes/alpine-in-the-build-stage-from.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
type: changed
---
Alpine in the build stage from 3.24.3 to 3.24.4
7 changes: 7 additions & 0 deletions .changes/health-check-failing-with-database-is.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
type: fixed
---
Health check failing with `database is locked` while an application writes, and making the writes of an application without a busy timeout fail

- The health check reads every database with `immutable=1`, which takes no lock
- When that read fails, it opens the database as before, with a busy timeout of 3 seconds
7 changes: 7 additions & 0 deletions .changes/home-of-nonroot-from-var-lib.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
type: security
---
Moved the home of `nonroot` from `/var/lib/sqlite` to `/home/nonroot`, `sqlite3` runs the `.sqliterc` of the home on every start, and every user can write `/var/lib/sqlite`

- `sqlite3` reads its startup file from `/home/nonroot/.sqliterc`, which only `nonroot` can write
- The working directory stays `/var/lib/sqlite`
9 changes: 9 additions & 0 deletions .changes/image-labels-to-one-set-that.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
type: changed
---
Image labels to one set that every image uses

- `dev.peakimages.image` gains `distro`, `variant`, `flavor`, `shell` and `package-manager`
- `dev.peakimages.image.upstream.version` replaces `dev.peakimages.sqlite.version`
- `dev.peakimages.sqlite.extensions`, `dev.peakimages.tini.version` and `dev.peakimages.busybox.version` are removed as these labels do not scale to bigger images
- `org.opencontainers.image.licenses` names the license of the image and of SQLite, and `base.name` is empty with an empty `base.digest` for an image built from `scratch`
10 changes: 10 additions & 0 deletions .changes/package-metadata-instead-of-the-sbom-document.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
type: fixed
---
Scanners listing the wrong packages and the wrong OS, `syft` found only `busybox 1.37.0`, `grype` reported two BusyBox CVEs Alpine has fixed and none of SQLite, and Trivy found nothing

- `sqlite3` carries a package note and the image the apk package database records of tini and BusyBox, `syft` and `grype` list all three, Trivy all but SQLite
- A scanner reports the image as Alpine, the release tini and BusyBox are taken from, instead of BusyBox or no OS, the same way Docker Hardened Images does
- The SBOM attestation lists the same three packages as before, it was already correct, but a scanner does not read it and makes its own list from the image
- The syft document in `/var/lib/db/sbom` that BuildKit made the SBOM attestation from is gone, BuildKit runs syft, which reads the package note and the apk package database natively
- `syft` no longer needs the `--select-catalogers +sbom-cataloger` flag to read the custom SBOM in the syft JSON file, as its default list is now correct too
4 changes: 4 additions & 0 deletions .changes/vendor-and-authors-labels-from-peakimages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
type: changed
---
Vendor and authors labels from `peakimages` to `PeakImages`, the name as it is written everywhere but in a URL or an image name
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*.md diff=markdown
CHANGELOG.md merge=union

/.changes export-ignore
/.github export-ignore
.editorconfig export-ignore
.gitattributes export-ignore
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/actions.lock
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ workflows:
'.github/workflows/pull-request.yaml':
- 'actions/checkout@v7.0.1'
- 'actions/download-artifact@v8.0.2'
- 'docker/login-action@v4.7.0'
- 'docker/login-action@v4.8.0'
'.github/workflows/release.yaml':
- 'actions/checkout@v7.0.1'
- 'actions/download-artifact@v8.0.2'
- 'docker/login-action@v4.7.0'
- 'docker/login-action@v4.8.0'
'.github/workflows/tests.yaml':
- 'actions/checkout@v7.0.1'
- 'actions/download-artifact@v8.0.2'
Expand All @@ -49,9 +49,9 @@ dependencies:
commit: 'sha1-c3c9e263c25d99ce0380d002d59b67737d91b0dc'
owner_id: 5429470
repo_id: 241092383
'docker/login-action@v4.7.0':
ref: 'v4.7.0'
commit: 'sha1-81c6f93d4bc991e510b342a00b419b3bb4efc5c6'
'docker/login-action@v4.8.0':
ref: 'v4.8.0'
commit: 'sha1-8aa5831fb8d48d8f76594c7ddde61ae58019f550'
owner_id: 5429470
repo_id: 287743349
'docker/setup-buildx-action@v4.4.1':
Expand Down
15 changes: 12 additions & 3 deletions .github/workflows/clean-manifests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
if: ${{ github.repository == 'peakimages/sqlite' }}
permissions:
contents: read
actions: write # disable this workflow after a failed run
environment:
name: cleanup
deployment: false
Expand All @@ -41,11 +42,19 @@ jobs:
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_CLEANUP_TOKEN }}
run: scripts/clean-manifests.sh --delete 200

- name: Upload the list of deleted manifests
- name: Upload the lists of manifests
if: ${{ always() }}
uses: actions/upload-artifact@v7.0.2
with:
name: deleted-manifests
path: scripts/deleted-manifests.tsv
name: manifests
path: |
scripts/manifests-to-delete.tsv
scripts/deleted-manifests.tsv
if-no-files-found: ignore
retention-days: 90

- name: Disable this workflow after a failure
if: ${{ failure() }}
env:
GH_TOKEN: ${{ github.token }}
run: gh workflow disable clean-manifests.yaml --repo "$GITHUB_REPOSITORY"
2 changes: 1 addition & 1 deletion .github/workflows/pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jobs:
path: ${{ runner.temp }}/images

- name: Log in to ghcr.io
uses: docker/login-action@v4.7.0
uses: docker/login-action@v4.8.0
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,14 @@ jobs:
path: ${{ runner.temp }}/images

- name: Log in to ghcr.io
uses: docker/login-action@v4.7.0
uses: docker/login-action@v4.8.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Log in to docker.io
uses: docker/login-action@v4.7.0
uses: docker/login-action@v4.8.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
Expand Down Expand Up @@ -164,14 +164,14 @@ jobs:
echo "tags=$tags" | tee -a "$GITHUB_OUTPUT"

- name: Log in to ghcr.io
uses: docker/login-action@v4.7.0
uses: docker/login-action@v4.8.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Log in to docker.io
uses: docker/login-action@v4.7.0
uses: docker/login-action@v4.8.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ jobs:
- name: Verify the action lockfile
env:
GH_TOKEN: ${{ github.token }}
# https://github.com/github/gh-actions-lock/releases/tag/v0.4.0
# https://github.com/github/gh-actions-lock/releases/tag/v0.4.1
run: |
gh extension install github/gh-actions-lock --pin v0.4.0
gh extension install github/gh-actions-lock --pin v0.4.1
gh actions-lock --verify

test:
Expand Down
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,36 @@ The defaults are set in the image, override them with `-e` or the `environment`
| `SQLITE_PAGE_SIZE` | `4096` | Page size of a new database, a power of two from `512` to `65536`. **Fixed once the database has content** |
| `SQLITE_TMPDIR` | unset | Directory for the temporary files of sorts and vacuums. Default `/tmp`, or the data directory when `/tmp` is not writable |

## Attestations

Every image carries an SBOM and a provenance attestation.

The SBOM lists the packages of the image:

```sh
docker buildx imagetools inspect peakimages/sqlite:latest --format '{{ json .SBOM }}'
```

The provenance records how the image was built:

```sh
docker buildx imagetools inspect peakimages/sqlite:latest --format '{{ json .Provenance }}'
```

A scanner lists the same packages, Trivy all but SQLite:

```sh
syft peakimages/sqlite:latest
grype peakimages/sqlite:latest
trivy image peakimages/sqlite:latest
```

## Releases

Every SQLite release becomes a new version of the image. A check for new SQLite versions runs twice a day.

The image version follows semantic versioning independently of SQLite. Changes to the image are listed in [CHANGELOG.md](CHANGELOG.md).

## Trademarks

This image is built and published by PeakImages. All third-party product names, logos and trademarks are the property of their respective owners and are used solely for identification. PeakImages claims no interest in those marks, and no affiliation, sponsorship or endorsement is implied.
38 changes: 32 additions & 6 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Every release is tagged `v<sqlite version>-v<image version>`, such as `v3.54.1-v1.4.0-beta.1`.

> [!IMPORTANT]
> A push that changes `release.json` or `src/upstream.json` publishes every release of it whose tag does not exist yet. Check what a push publishes with `scripts/plan-version.sh` first.
> A push that changes `release.json` or `src/upstream.json` releases the versions they set, unless they are released already. Run `scripts/plan-version.sh` first to see what a push releases.

## Rules

Expand All @@ -17,6 +17,7 @@ Every release is tagged `v<sqlite version>-v<image version>`, such as `v3.54.1-v
| `v1.2.x` | backports and hotfixes, cut from the newest tag of v1.2 | stable `1.2.x` versions |

- `main` takes fixes only. A new minor or major reaches it as a merge of `next` or a release branch
- Merge `next` or a release branch into `main` only right before you release it, on the same day. To freeze a minor for longer, publish an RC on `next` or cut `release/v1.4`
- `next` and the release branches publish prereleases only, their stable versions are released on `main`
- Name a branch after what it changes: `fix/<topic>`, `feat/<topic>`, and `fix/<topic>-v1.2.2` for a backport, after the version that releases it
- Squash merge pull requests from contributors and pull requests with a single change, such as SQLite updates
Expand All @@ -35,11 +36,12 @@ Every release is tagged `v<sqlite version>-v<image version>`, such as `v3.54.1-v
> [!NOTE]
> `next` publishes prereleases only. For its stable version, merge `next` into `main` with a merge commit and create the release on `main`.

1. Describe the changes under `## [Unreleased]` in `CHANGELOG.md`, they become the release notes
2. Check what the branch releases:
1. Describe the changes in change files with `scripts/change.sh`, they become the release notes, see [Change files](#change-files)
2. Check what the branch releases and the entries it lists:

```sh
scripts/plan-version.sh
scripts/change.sh --notes
```

3. Select the stage and the version, the script commits them and asks to push:
Expand All @@ -57,6 +59,27 @@ Every release is tagged `v<sqlite version>-v<image version>`, such as `v3.54.1-v
> scripts/undo-release.sh
> ```

## Change files

Every change to the image has a file in `.changes/`, `AGENTS.md` describes the types and the wording:

```text
---
type: fixed
commit: 1a2b3c4
---
Missing description and license on ghcr.io

- The release index carries the labels of the image as annotations
```

- `scripts/change.sh` writes a file, it asks for what its flags leave out, and `--notes` prints the entries of the next release
- `scripts/release.sh` preselects the version the files need and writes them into `CHANGELOG.md`, the release workflow reads its notes from there
- A prerelease writes the files under `## [Unreleased]`, keeps them and adds its version to the files that have none
- A stable release writes the files under `## [v1.4.0] - <date>` and removes them
- `scripts/undo-release.sh` brings the files back as they were
- A new SQLite version needs no file, the release workflow writes its notes

## Backport a fix

`main` is on 1.3, and 1.1 and 1.2 still get fixes. A fix reaches each of them through a patch branch and a pull request of its own:
Expand Down Expand Up @@ -90,11 +113,11 @@ Every release is tagged `v<sqlite version>-v<image version>`, such as `v3.54.1-v
1. Pin the line on a branch from `main`:

```sh
git switch -c feat/sqlite-3.53 origin/main && scripts/check-upstream.sh 3.53
git switch -c feat/sqlite-3.53 origin/main && scripts/check-upstream.sh v3.53
```

2. Squash merge a pull request as `feat(release): add the SQLite 3.53 line`, the push publishes `v3.53.4-v1.3.0`
3. To stop the line, remove `3.53` from `src/upstream.json`, its tags stay where they are
3. To stop the line, remove `v3.53` from `src/upstream.json`, its tags stay where they are

## Release a major version

Expand Down Expand Up @@ -130,8 +153,11 @@ Every release is tagged `v<sqlite version>-v<image version>`, such as `v3.54.1-v

## Pull requests

The pull request workflow builds every pull request and publishes the image of the line `latest` of one from a branch of this repository as `ghcr.io/peakimages/sqlite:pr-<number>`, versioned `<base>-pr.<number>`: pull request 1234 into `next` is `1.4.0-beta.1-pr.1234` after `1.4.0-beta.1` and `1.5.0-alpha.0-pr.1234` before the first alpha of 1.5.0, into `main` `1.3.4-pr.1234`. PHP's `version_compare` sorts it after its base and before the next prerelease or release.
The pull request workflow builds every pull request and publishes the image of the line `latest` of a pull request from a branch of this repository as `ghcr.io/peakimages/sqlite:pr-<number>`. Its version is `<base>-pr.<number>`:

- Into `next`: `1.4.0-beta.1-pr.1234` after `1.4.0-beta.1`, or `1.5.0-alpha.0-pr.1234` before the first alpha of 1.5.0
- Into `main`: `1.3.4-pr.1234`
- PHP's `version_compare` sorts it after its base and before the next prerelease or release
- Pull requests from forks and Dependabot are built, not published
- A push to a pull request from `main`, `next`, a release branch or a patch branch that changes `release.json` or `src/upstream.json` is not built, the release workflow builds it
- ghcr.io only, no git tag and no GitHub release, the clean manifests workflow keeps the image while the pull request is open
Expand Down
Loading
Loading