Settle the open points of the Ubuntu and nixpkgs image (closes #38)
check / check (push) Successful in 2m47s
check / check (push) Successful in 2m47s
ca-certificates, nix-bin and runit come from a dated Ubuntu snapshot no older than the pinned Ubuntu image. The Dockerfile names the SHA-256 hash of each snapshot InRelease file apt uses, and the build checks them before apt-get install, so every package is checked against hashed files. That install uses the Go image's CA certificate file. ca-certificates is installed by name. The image writes build-users-group = to /etc/nix/nix.conf so root can build without a daemon. nixpkgs comes from its release file on releases.nixos.org, checked by SHA-256, and takes about 500 MiB of disk. runsvinit is archived upstream and is built at a fixed commit with a go.mod written for the build. The example run scripts put their code in a main function. Model: opus-5-5
This commit was merged in pull request #42.
This commit is contained in:
@@ -291,10 +291,15 @@ stand for the app's own options:
|
|||||||
```bash
|
```bash
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
sleep 1
|
|
||||||
exec chpst -u app:app /usr/local/bin/app \
|
main() {
|
||||||
--listen 127.0.0.1:8081 \
|
sleep 1
|
||||||
--trusted-proxies 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.1/32,::1/128
|
exec chpst -u app:app /usr/local/bin/app \
|
||||||
|
--listen 127.0.0.1:8081 \
|
||||||
|
--trusted-proxies 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.1/32,::1/128
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
```
|
```
|
||||||
|
|
||||||
- The image's entrypoint, `runsvinit`, has runit start `smallwebwaf` and the app
|
- The image's entrypoint, `runsvinit`, has runit start `smallwebwaf` and the app
|
||||||
|
|||||||
@@ -1155,16 +1155,29 @@ The image holds:
|
|||||||
|
|
||||||
- Ubuntu 26.04 LTS, the newest long-term support release of Ubuntu, pinned by
|
- Ubuntu 26.04 LTS, the newest long-term support release of Ubuntu, pinned by
|
||||||
digest. The image moves to the next LTS release when that ships.
|
digest. The image moves to the next LTS release when that ships.
|
||||||
|
- Three packages from Ubuntu, `ca-certificates`, `nix-bin` and `runit`,
|
||||||
|
installed from a dated snapshot of Ubuntu's archive and checked by hash (see
|
||||||
|
"Packages from Ubuntu" below). The Ubuntu image has no CA certificates, and
|
||||||
|
they come with `nix-bin` only because a library it uses recommends them, so
|
||||||
|
`ca-certificates` is installed by name. Without it Nix cannot download
|
||||||
|
packages, and `smallwebwaf`, unable to reach GeoJS, would count every visitor
|
||||||
|
as coming from an unknown country.
|
||||||
- Nix, the package manager, from Ubuntu's own `nix-bin` package, and nixpkgs,
|
- Nix, the package manager, from Ubuntu's own `nix-bin` package, and nixpkgs,
|
||||||
the collection of packages Nix installs from, fixed at one commit (see
|
the collection of packages Nix installs from, fixed at one commit (see
|
||||||
"Packages from nixpkgs" below). Root uses Nix directly, and no Nix daemon runs
|
"Packages from nixpkgs" below). Root uses Nix directly, and no Nix daemon runs
|
||||||
in the container.
|
in the container. Nix run by root expects a group of build users, `nixbld`,
|
||||||
- runit, from Ubuntu's own `runit` package, and `runsvinit` as the entrypoint.
|
which `nix-bin` does not create, so the image writes `build-users-group =` to
|
||||||
Neither Ubuntu nor nixpkgs packages `runsvinit`, so the image builds it from
|
`/etc/nix/nix.conf`, and root's builds then run without build users.
|
||||||
its source (`github.com/peterbourgon/runsvinit`) at a version fixed by hash.
|
- runit, from Ubuntu's own `runit` package, and `runsvinit` as the entrypoint,
|
||||||
`runsvinit` starts runit's `runsvdir`, which starts a `runsv` for each
|
as the owner's code style guide asks for service containers. Neither Ubuntu
|
||||||
directory under `/etc/service`; each `runsv` runs the `run` script in its
|
nor nixpkgs packages `runsvinit`, so the image builds it from its source
|
||||||
directory, and runs it again whenever it exits. Ubuntu's runit looks for
|
(`github.com/peterbourgon/runsvinit`) at a fixed commit hash. Its repository
|
||||||
|
is archived and has not changed since 2015, and its last tag is `v2.0.0`. It
|
||||||
|
has no `go.mod`, and `go build` of its directory needs one, so the build
|
||||||
|
writes one; since `runsvinit` uses only Go's standard library, that file names
|
||||||
|
nothing else. `runsvinit` starts runit's `runsvdir`, which starts a `runsv`
|
||||||
|
for each directory under `/etc/service`; each `runsv` runs the `run` script in
|
||||||
|
its directory, and runs it again whenever it exits. Ubuntu's runit looks for
|
||||||
services in `/etc/service` too, so when `docker stop` has `runsvinit` stop
|
services in `/etc/service` too, so when `docker stop` has `runsvinit` stop
|
||||||
each service with runit's `sv`, `sv` finds it.
|
each service with runit's `sv`, `sv` finds it.
|
||||||
- The `smallwebwaf` binary, and a user of its own, `smallwebwaf` (uid and gid
|
- The `smallwebwaf` binary, and a user of its own, `smallwebwaf` (uid and gid
|
||||||
@@ -1179,8 +1192,9 @@ The image holds:
|
|||||||
(`HEALTHCHECK`).
|
(`HEALTHCHECK`).
|
||||||
|
|
||||||
Every `run` script, the app's included, is a bash script that starts with
|
Every `run` script, the app's included, is a bash script that starts with
|
||||||
`#!/usr/bin/env bash` and `set -euo pipefail`, as the owner's code style guide
|
`#!/usr/bin/env bash` and `set -euo pipefail` and puts its code in a `main`
|
||||||
asks; Ubuntu ships bash.
|
function, called on its last line, as the owner's code style guide asks; Ubuntu
|
||||||
|
ships bash.
|
||||||
|
|
||||||
Beyond its `FROM` line, the app's Dockerfile adds:
|
Beyond its `FROM` line, the app's Dockerfile adds:
|
||||||
|
|
||||||
@@ -1219,23 +1233,56 @@ with `app.run` beside the Dockerfile:
|
|||||||
```bash
|
```bash
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
sleep 1
|
|
||||||
exec chpst -u app:app /usr/local/bin/app \
|
main() {
|
||||||
--listen 127.0.0.1:8081 \
|
sleep 1
|
||||||
--trusted-proxies 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.1/32,::1/128
|
exec chpst -u app:app /usr/local/bin/app \
|
||||||
|
--listen 127.0.0.1:8081 \
|
||||||
|
--trusted-proxies 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.1/32,::1/128
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Packages from Ubuntu: the image installs `ca-certificates`, `nix-bin` and
|
||||||
|
`runit` from Ubuntu's snapshot service, which serves the archive as it was at a
|
||||||
|
given moment, rather than from the archive itself, whose packages change with
|
||||||
|
every update. The image's Dockerfile names that moment, in apt's
|
||||||
|
`--snapshot 20261001T000000Z` form, on both `apt-get update` and
|
||||||
|
`apt-get install`. That moment is never earlier than the date of the pinned
|
||||||
|
Ubuntu image, since packages from an older snapshot can need older versions of
|
||||||
|
packages the Ubuntu image already holds, and it moves forward whenever that
|
||||||
|
image's digest does. `apt-get update` keeps the snapshot's `InRelease` files,
|
||||||
|
which apt checks against the archive's signature, in `/var/lib/apt/lists/`; each
|
||||||
|
lists the SHA-256 hash of the package lists it covers, and each package list the
|
||||||
|
hash of every package in it. The Dockerfile also names the SHA-256 hash of each
|
||||||
|
`InRelease` file apt uses, and the build checks them after `apt-get update` and
|
||||||
|
before `apt-get install`, so every package apt installs is checked, through
|
||||||
|
those files, against hashes the Dockerfile names. The snapshot service is
|
||||||
|
reached over HTTPS, and the Ubuntu image has no CA certificates of its own, so
|
||||||
|
this one install uses those of the Go image that `smallwebwaf` is built in,
|
||||||
|
which is pinned by digest too: apt's `Acquire::https::CaInfo` option names that
|
||||||
|
image's CA certificate file, `/etc/ssl/certs/ca-certificates.crt`, copied into
|
||||||
|
the build.
|
||||||
|
|
||||||
Packages from nixpkgs: nixpkgs is fixed at one commit of its newest release
|
Packages from nixpkgs: nixpkgs is fixed at one commit of its newest release
|
||||||
branch, `nixos-26.05` today. The image's Dockerfile names the commit and the
|
branch, `nixos-26.05` today. For each commit of the branch that has passed its
|
||||||
hash of its contents, and the build checks that hash. nixpkgs is set up for root
|
tests, the Nix project publishes a release on `releases.nixos.org`, such as
|
||||||
under the name `nixpkgs`, so the app's Dockerfile installs a package with
|
`nixos-26.05.11045.774debe7a0d1`, and the image takes nixpkgs from that
|
||||||
`nix-env -iA nixpkgs.<name>`, and whatever it installs is on the `PATH` of every
|
release's file `nixexprs.tar.xz`, not from a GitHub archive of the commit, whose
|
||||||
service. Because nixpkgs stays at that commit, an app built on the same
|
bytes can change. The image's Dockerfile names the release and the SHA-256 hash
|
||||||
`smallwebwaf` image gets the same packages each time it is built. A newer commit
|
of that file, which the release's page lists, and the build checks the hash
|
||||||
of the branch, with its security fixes, comes with a newer `smallwebwaf` image,
|
before unpacking it. nixpkgs is set up for root under the name `nixpkgs`, so the
|
||||||
as do Ubuntu's own fixes; an app takes them by changing the digest in its `FROM`
|
app's Dockerfile installs a package with `nix-env -iA nixpkgs.<name>`, and
|
||||||
line. When nixpkgs makes its next release, every six months, the image moves to
|
whatever it installs is on the `PATH` of every service. Because nixpkgs stays at
|
||||||
that release's branch.
|
that commit, an app built on the same `smallwebwaf` image gets the same packages
|
||||||
|
each time it is built. Unpacked, nixpkgs takes about 500 MiB of disk, more on
|
||||||
|
some filesystems such as ZFS, and each package an app installs from it adds its
|
||||||
|
own size, with everything it depends on. A newer commit of the branch, with its
|
||||||
|
security fixes, comes with a newer `smallwebwaf` image, as do Ubuntu's own
|
||||||
|
fixes; an app takes them by changing the digest in its `FROM` line. When nixpkgs
|
||||||
|
makes its next release, every six months, the image moves to that release's
|
||||||
|
branch.
|
||||||
|
|
||||||
The two processes:
|
The two processes:
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user