Files
bun/test/docker/Dockerfile.postgres-auth
robobun 90f8746301 test/docker: bake mysql+postgres data dirs so cold start is ~2-3s, stop healthcheck wedge (#33822)
## What

Fixes the recurring `application not healthy after 1m0s` flake that
takes out every mysql-backed test file on alpine shards (26030, 24850,
26063, 28632, sql-mysql.*, integration/mysql2), by baking
pre-initialized data directories into the mysql and postgres test images
so cold container start is ~2-3s instead of ~60s, and by removing the
healthcheck configuration that turned a slow start into a permanent
wedge.

- `Dockerfile.mysql-plain`, `Dockerfile.mysql-native-password`, and the
mysql-tls Dockerfile run the stock entrypoint once at `docker build`
time with `MYSQL_INITDB_SKIP_TZINFO=1` against a sibling datadir (the
base image's `VOLUME /var/lib/mysql` discards build-time writes there).
At container start the entrypoint sees the datadir is populated and
`exec`s `mysqld` directly.
- `Dockerfile.postgres-plain`, `Dockerfile.postgres-auth`, and the
postgres-tls Dockerfile do the same against a `PGDATA` outside `VOLUME
/var/lib/postgresql/data`.
- Every healthcheck's `interval` drops from `1h` to `5s`.
- `compose up --wait-timeout` goes from 60 to 180 and the container
`beforeAll` hook timeouts go to 240s.
- `scripts/bootstrap.sh` bumped to v38 so the next Linux AMI bake runs
`prepare-ci.ts` against the new compose file and pre-builds
`bun-mysql-*:local` / `bun-postgres-*:local` into the runner. Until the
v38 AMIs are published each shard still pays one image build under
parallel prestart; afterwards it is just `docker run` (~2-3s).

## Why

The ~62s mysql cold start breaks down as: ~39s loading
`/usr/share/zoneinfo` into `mysql.time_zone_*` via
`mysql_tzinfo_to_sql`, ~15s `mysqld --initialize-insecure`, and ~8s of
entrypoint setup plus the temp-server bounce. No test touches MySQL's
named-timezone tables (the datetime-roundtrip test only varies the
**process** `TZ`, not the MySQL session `time_zone`), so the tzinfo load
is dead weight, and the rest is deterministic and can run at image-build
time instead of every container start. Postgres's own init (initdb +
temp server + init scripts) is ~5-8s, but on alpine shards it queued
behind the three parallel mysql builds and was observed at 130-220s
ensure-to-ready.

On alpine 3.23 CI hosts, mysql's ~62s overshot `start_period: 60s`, and
once start_period elapses Docker's health monitor switches from
`start_interval: 1s` to `interval: 1h`. So the container sat at `health:
starting` for an hour even though mysqld was accepting TCP connections
two seconds later, and every `compose up --wait --wait-timeout 60` timed
out from then on. Each affected test file was retried four times at 60s
apiece.

From [build 70876's alpine x64-baseline
shard](https://buildkite.com/bun/bun/builds/70876#019f457d-d9ef-494b-ae4a-06c08a13acb8):

```
mysql_plain-1  | 2026-07-09 06:38:49 [Entrypoint]: Entrypoint script ... started.
...
mysql_plain-1  | 2026-07-09T06:39:51 [MY-010931] ... ready for connections. ... port: 3306
```

62s from entrypoint to ready, yet `docker compose ps` two minutes later
still shows:

```
bun-test-services-mysql_plain-1 ... Up 2 minutes (health: starting)
```

because the next probe is scheduled for ~07:39.

Sampling the last 30 failed `:alpine: 3.23` test-bun jobs, **20** were
this exact error (x64, x64-baseline, aarch64). **0** of 20 sampled
debian/ubuntu failures were.

`tmpfs` is dropped for both: the baked data dir lives on the container's
CoW layer, so a fresh container is still a fresh database/cluster and
the light test workloads don't need RAM-backed I/O. `interval: 5s`
everywhere means that even if some future service overshoots its
`start_period`, it recovers within one probe instead of freezing
`compose up --wait` for an hour; a `SELECT 1` / `pg_isready` every 5s is
negligible and would need 30 consecutive failures (150s) to mark a
running container unhealthy.
2026-07-09 20:09:15 -07:00

21 lines
785 B
Docker

FROM postgres:15
COPY init-scripts/postgres-auth/ /docker-entrypoint-initdb.d/
COPY config/pg_hba_auth.conf /etc/postgresql/pg_hba.conf
# See Dockerfile.postgres-plain for the rationale. The custom hba_file and
# connection-limit flags are supplied by the compose `command:` at runtime;
# build-time init only needs the default local-trust hba to run its scripts.
ENV POSTGRES_HOST_AUTH_METHOD=trust \
POSTGRES_USER=postgres \
PGDATA=/var/lib/postgresql/pgdata-init
RUN set -e; \
docker-entrypoint.sh postgres & pid=$!; \
for i in $(seq 180); do \
pg_isready -h 127.0.0.1 -U postgres >/dev/null 2>&1 && break; \
sleep 1; \
done; \
pg_isready -h 127.0.0.1 -U postgres; \
gosu postgres pg_ctl -D "$PGDATA" -m fast -w stop; \
wait "$pid"