Running python3 -m venv venv over an existing cached venv recreates
the absolute symlinks and pyvenv.cfg paths so Python resolves to
the current system's python3 binary. Without this, cp -a preserves
stale symlinks from the cache source, causing venv/bin/python to
resolve to /usr/bin/python3 (system, not venv) and pytest not found.
Also switch validation to use python3 to match Ubuntu 24.04 convention.
Ubuntu-latest runner containers on NAS dont have the gitea_gitea network, so http://gitea:3000 is unreachable. Use 172.21.0.1:3300 (Docker bridge gateway) instead.
Ubuntu-latest runner containers on NAS dont have the gitea_gitea network, so http://gitea:3000 is unreachable. Use 172.21.0.1:3300 (Docker bridge gateway) instead.
Add build-image-dev job (runs-on: vps) - builds with Podman on server2,
pipes the finished image to NAS via SSH, retags from localhost/ prefix.
Deploy job now depends on build-image-dev instead of backend-tests.
NAS HDD I/O was the bottleneck for Docker builds. VPS has SSD and
matches NAS x86_64 architecture perfectly.
- Add build-image job (runs-on: vps) for deploy.yml (main) - builds with
Podman on server2, pipes finished image to NAS via SSH, retags
- Add build-image-dev job (runs-on: vps) for deploy-dev.yml (dev) - same
pattern for dev images
- Remove build + base image pre-warm from NAS-side deploy jobs (image is
now pre-loaded by the build job)
- deploy job condition: always() && build-image succeeded (so frontend
test failure doesn't block deployment, but build failure does)
NAS HDD I/O was the bottleneck. VPS has SSD and same x86_64 arch.
The VPS runner's host executor has a bug where completion callbacks
are silently dropped, causing jobs to appear stuck. Switched backend
and frontend tests to the NAS runner which correctly reports status.
Also updated checkout URL to use Docker bridge gateway 172.21.0.1:3300.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cached venv has broken internal paths even when using venv/bin/python
directly. Clear caches and use . venv/bin/activate + python -m pytest
which correctly sets VIRTUAL_ENV for module resolution.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
activate doesn't reliably shadow system python3 on the VPS runner.
Using the explicit venv path matches what the cache validation check
already uses.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
VPS host has python3 (not python) available. Fixes "python: command
not found" error from previous commit.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The CI container may not have /volume1/docker/claude-dev/.env mounted,
causing 'docker compose config' to fail.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Venv symlinks break when cache is used across different environments
(VPS host vs NAS Docker). python -m pytest is resilient because it
loads pytest as a module, not via a shebang-based script.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
host.docker.internal not resolving in act containers on Synology Docker.
The gateway IP 172.21.0.1 routes to the host where Gitea is now
bound to 0.0.0.0:3300.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Use host.docker.internal:3300 with ubuntu-latest runner.
Gitea port now bound to 0.0.0.0:3300 so Docker containers
can reach it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Changed Gitea HTTP port binding from 127.0.0.1:3300 to 0.0.0.0:3300
so Docker containers can reach Gitea via host.docker.internal.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Docker volume mounts may not auto-create mount points inside the
job container. Use mkdir -p to ensure the target directory exists
before copying files.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The act Docker containers on the NAS runner cannot reach Gitea
on the gitea_gitea network despite the runner config. Switching
to the 'nas' runner label which uses host mode — jobs run directly
on the NAS host where localhost:3300 reaches Gitea.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replaces 'gitea:3000' with '172.21.0.4:3000' to bypass DNS
resolution issues in act job containers. Also removed --dns
override from runner-config.yaml which was breaking Docker's
embedded DNS and container name resolution.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The cached venv's python binary may work but tool symlinks (pytest, etc.)
break when restored in a different environment. Test pytest specifically
to catch this.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cached venvs from NAS Docker containers have broken symlinks when
restored on the VPS host, causing "pytest: command not found".
Add a functional check that venv/bin/python runs before accepting
the cache as valid.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Backend and frontend tests now run on `runs-on: vps` (server2 at
158.101.140.85, host mode) with checkout via Tailscale IP. Deploy
job stays on `runs-on: nas` with gitea_gitea network for Docker
socket access. This eliminates the HDD bottleneck and Docker
network/DNS issues that plagued the all-NAS pipeline.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Job containers were created on isolated bridge networks that couldn't
reach Gitea at any address. Add workflow-level container blocks to
backend-tests and frontend-tests (matching deploy job) so all job
containers are on the gitea network and can resolve "gitea" via
Docker's embedded DNS. Revert checkout URLs back to gitea:3000.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
host.docker.internal doesn't resolve in job containers despite the
runner config setting --add-host. Use the NAS LAN IP directly,
which is reachable from any Docker bridge network.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Job containers are on their own bridge networks and can't reach
172.21.0.4 (Gitea's IP on gitea_gitea network). Use the Docker host
gateway with port 3300 (which maps to Gitea container's 3000) instead.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Runner's --dns options bypass Docker's embedded DNS resolver, so job
containers can't resolve the "gitea" hostname even when connected to the
gitea_gitea network. Add /etc/hosts entry pointing gitea to 172.21.0.4
before each checkout step.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cold venv installs on the NAS HDD exceed 300s, causing the backend
tests install step to be killed by timeout. Double the timeout so the
first or fallback pip mirror attempt can complete before the timeout
fires.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bypass Docker 24 network connection bug during compose container creation by stripping network settings and connecting networks manually.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The container takes ~183s to become healthy on the slow NAS HDD.
90 iterations at 2s (180s) kept timing out by ~3 seconds.
Increased to 120 iterations (240s) for safety margin.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The NAS HDD is slow enough that container startup can exceed 60
seconds. The app was starting successfully (Uvicorn running) but
the health check timed out just before the container became healthy.
Increased to 90 iterations at 2s = 180s max wait.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The ${GITEA_DB_PASSWORD} syntax in the workflow YAML expands to empty
because Gitea Actions doesn't pass workflow-level env vars to themselves.
Using the actual password value directly.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>