mirror of
https://github.com/oven-sh/bun.git
synced 2026-10-25 21:40:30 +08:00
## 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.
21 lines
785 B
Docker
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"
|