fix: give the backend CI job a docker daemon it can address
The runner has docker, so the database container started; the job just could not reach it. pytest-databases takes the address from DOCKER_HOST, and unset means 127.0.0.1 -- the job container's loopback, not the namespace the sibling published on. A dind service makes it resolve to a host that answers.
This commit is contained in:
+18
-2
@@ -19,6 +19,24 @@ jobs:
|
|||||||
backend:
|
backend:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
# pytest-databases starts PostgreSQL in a container and then connects to it. Which address
|
||||||
|
# it connects to is decided by DOCKER_HOST: unset or unix:// means 127.0.0.1, which is wrong
|
||||||
|
# here because the job is itself a container and the database is a sibling, published on
|
||||||
|
# another network namespace. Pointing at a dind service instead makes pytest-databases
|
||||||
|
# resolve the host to `docker`, where the port really is.
|
||||||
|
#
|
||||||
|
# If the runner is ever configured with its own dind sidecar, delete this block and the
|
||||||
|
# DOCKER_HOST below: every job gets a daemon then, including the ones in release.yml.
|
||||||
|
services:
|
||||||
|
docker:
|
||||||
|
image: docker:27-dind
|
||||||
|
options: --privileged
|
||||||
|
env:
|
||||||
|
DOCKER_TLS_CERTDIR: ''
|
||||||
|
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: tcp://docker:2375
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: backend
|
working-directory: backend
|
||||||
@@ -42,8 +60,6 @@ jobs:
|
|||||||
- name: Lint
|
- name: Lint
|
||||||
run: uv run ruff check src/ tests/
|
run: uv run ruff check src/ tests/
|
||||||
|
|
||||||
# pytest-databases starts a throwaway PostgreSQL container, so this needs a working
|
|
||||||
# Docker daemon on the runner — the same requirement the release workflow has.
|
|
||||||
- name: Tests
|
- name: Tests
|
||||||
run: uv run pytest tests/ -q
|
run: uv run pytest tests/ -q
|
||||||
|
|
||||||
|
|||||||
@@ -99,12 +99,27 @@ the workflow.
|
|||||||
|
|
||||||
1. **A registered `act_runner`.** Gitea Actions is enabled instance-side but does nothing without a
|
1. **A registered `act_runner`.** Gitea Actions is enabled instance-side but does nothing without a
|
||||||
runner. Register one against the repo or the instance with the label `ubuntu-latest`.
|
runner. Register one against the repo or the instance with the label `ubuntu-latest`.
|
||||||
2. **The runner needs a Docker daemon.** This is the single most common failure for image-building
|
2. **The runner needs a Docker daemon, at an address the job can reach.** `act_runner` in docker
|
||||||
workflows on Gitea. `act_runner` in docker mode runs each job inside a container that has no
|
mode runs each job inside a container with no daemon of its own. Either run a `docker:dind`
|
||||||
daemon of its own. Either run a `docker:dind` sidecar next to the runner and set
|
sidecar next to the runner and set `DOCKER_HOST=tcp://docker:2376` (with TLS certs shared over a
|
||||||
`DOCKER_HOST=tcp://docker:2376` (with TLS certs shared over a volume), or run the runner in host
|
volume), or run the runner in host mode. The dind sidecar is the safer of the two — mounting the
|
||||||
mode with the socket mounted. The dind sidecar is the safer of the two — mounting the host socket
|
host socket into job containers gives any workflow root on the runner host.
|
||||||
into job containers gives any workflow root on the runner host.
|
|
||||||
|
**Reachability is a separate question from availability, and it bit us.** Mounting the host
|
||||||
|
socket into a containerised job gives it a working daemon, and `pytest tests/` still fails with
|
||||||
|
`Service 'pytest_databases_postgres' failed to come online`: the container starts fine, but its
|
||||||
|
published port lands on the *host's* network namespace while the test process looks for it on
|
||||||
|
the job container's loopback. `pytest_databases/docker/__init__.py` picks the address from
|
||||||
|
`DOCKER_HOST` — `127.0.0.1` when it is unset or `unix://`, otherwise the hostname out of
|
||||||
|
`tcp://host:port`. So a TCP `DOCKER_HOST` is what makes the sibling container addressable, and
|
||||||
|
the value must include the port or it raises rather than falling back.
|
||||||
|
|
||||||
|
Until the runner grows its own sidecar, `ci.yml`'s backend job carries a `docker:dind` service
|
||||||
|
of its own with `DOCKER_HOST: tcp://docker:2375`. That needs the runner to permit
|
||||||
|
`--privileged`. The same treatment is still owed to `release.yml` — its `quality` job runs the
|
||||||
|
same tests, and its `smoke` job talks to compose, where the published ports would move to the
|
||||||
|
dind host too, so `curl http://localhost:3000` becomes `curl http://docker:3000`. Configuring
|
||||||
|
the runner once (option 1) avoids all of that.
|
||||||
3. **Action resolution.** A bare `uses: docker/build-push-action@v6` does not mean github.com here.
|
3. **Action resolution.** A bare `uses: docker/build-push-action@v6` does not mean github.com here.
|
||||||
Gitea resolves it against `[actions] DEFAULT_ACTIONS_URL`, which defaults to `https://gitea.com`.
|
Gitea resolves it against `[actions] DEFAULT_ACTIONS_URL`, which defaults to `https://gitea.com`.
|
||||||
That is fine as it stands — `actions/checkout@v4`, `docker/setup-buildx-action@v3`,
|
That is fine as it stands — `actions/checkout@v4`, `docker/setup-buildx-action@v3`,
|
||||||
|
|||||||
Reference in New Issue
Block a user