The Docker daemon reaches the Nexus Docker group over the dedicated
connector port 8087 (its registry mirror), not the main 8081 HTTP port,
which caused HTTPS-to-HTTP pull failures in CI. Repoint all image refs to
171.22.25.73:8087 at the connector root; npm and NuGet stay on 8081.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Point Docker, NuGet, and npm pulls at the Nexus group repos on
171.22.25.73:8081 for both CI/CD and local builds, so the pipeline and
developers no longer depend on Docker Hub, MCR, nuget.org, or npmjs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Rebrand the public café-discovery app: directories web/finder→web/koja and
docker/finder→docker/koja, plus all service wiring (docker-compose, Caddy
subdomain koja.meezi.ir, env vars KOJA_PORT / NEXT_PUBLIC_KOJA_URL, CI
workflows) and the app's display name (Koja / کجا).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- aspnet:10.0, postgres:16-alpine, redis:7-alpine all fail on first
fetch through Nexus proxy (OCI manifest format bug in Nexus)
- Change DOTNET_ASPNET_IMAGE default to mcr-mirror.liara.ir directly
- Change postgres/redis service images to docker-mirror.liara.ir
- CI service containers (api-build job) also use Liara directly
- All images parameterized so ENV_FILE can override for any registry
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
act runner (host mode) inherits a minimal PATH from the process
environment — docker is not found even though it is installed.
Explicitly include all standard locations plus /snap/bin.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Node.js is not in PATH on the self-hosted:host runner, so JS actions
(actions/checkout@v4) fail with "cannot find node". Use the same shell
git init/fetch/checkout pattern used in all other jobs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
python3 is not in PATH inside dotnet/sdk:10.0 container — replace the
"Write NuGet config" step with a cat heredoc which works in any container.
Also syncs GitHub with the Gitea-side changes:
- All images pulled from local Nexus mirrors (no internet round-trip)
171.22.25.73:5000 → docker-hub-proxy (node, postgres, redis)
171.22.25.73:5002 → mcr-proxy (dotnet/sdk)
- npm steps already on npm-group (Liara + Runflare fallback)
- docker-compose.mirror.yml: expose port 5002 for mcr-proxy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
apk add git downloads from dl-cdn.alpinelinux.org (Fastly CDN) which is
slow/blocked in Iran — caused 6m+ checkout times.
New approach: wget the repo tarball from Gitea's archive API endpoint.
wget + tar (busybox) are already in node:20-alpine — no package install.
Gitea is on the same machine as the runner = download is instant.
GET /api/v1/repos/{owner}/{repo}/archive/{sha}.tar.gz
Authorization: Bearer {token}
dotnet/sdk jobs unchanged — Debian base has git pre-installed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
NuGet 10 blocks HTTP sources by default. allowInsecureConnections=true
must be set in a config file — the --source CLI flag doesn't support it.
Write the config to /tmp/nuget.ci.config inline in the step so there is
no dependency on any file existing in the workspace.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
--configfile nuget.mirror.config fails when the file isn't present in
the workspace (e.g. when Gitea is behind GitHub on commits).
--source inline URL is simpler, self-contained, and replaces all
configured sources — no extra file dependency in CI.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
github.server_url returns 'http://gitea:3000' (Gitea ROOT_URL using Docker
service name). CI job containers run on an isolated network and can't resolve
the 'gitea' hostname.
host-gateway maps to the Docker bridge IP (172.17.0.1). Gitea publishes
port 3000 on all interfaces, so http://gitea:3000 becomes reachable inside
every job container via the bridge.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
actions/checkout@v4 is a JS action executed inside the job container:
- dotnet/sdk:10.0 has no Node.js → exit 127
- node:20-alpine has no git → checkout fails
Fix: manual git clone via shell using http.extraheader for token auth.
Token never appears in process list or git log. deploy job (self-hosted:host)
keeps actions/checkout — the act_runner image has both node and git.
Also removes defaults.run.working-directory from Node.js jobs (the checkout
step must start in workspace root, not web/<app>).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Switch CI jobs to container: image: overrides so jobs run inside official
SDK containers (dotnet/sdk:10.0, node:20-alpine) instead of the bare
runner container. This bypasses blocked CDN downloads for dotnet/node.
Deploy job stays on self-hosted:host where Docker CLI is available.
Update workflow comments to explain the required runner label config:
ubuntu-latest:docker://node:20-alpine (CI jobs)
self-hosted:host (deploy)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root cause: actions/setup-dotnet@v4 downloads .NET from
download.visualstudio.microsoft.com and actions/setup-node@v4 downloads
Node from nodejs.org — both CDNs are blocked from Iran so jobs hang at 0s.
Fix:
- All .NET jobs: add container: mcr.microsoft.com/dotnet/sdk:10.0
so .NET is already inside the image — no download needed.
Remove actions/setup-dotnet step entirely.
- All Node.js jobs: add container: node:20-alpine
so Node/npm are already inside the image — no download needed.
Remove actions/setup-node step entirely.
- api-build: add postgres + redis service containers + env vars so
dotnet test can actually connect to a database (was silently failing).
- deploy job: change back to runs-on: self-hosted
ubuntu-latest containers don't have Docker CLI — docker compose
commands would fail immediately. Deploy MUST run on the server.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
.gitea/workflows/ci-cd.yml:
- Triggers on push to main and PRs
- CI jobs: dotnet build/test, dashboard tsc, finder tsc (all self-hosted)
- Deploy job: only on push to main, needs all CI jobs to pass
- Writes .env from ENV_FILE secret (set in Gitea repo settings)
- docker compose build --parallel with BuildKit
- Rolling restart (postgres/redis untouched)
- Health-check poll: waits up to 2min for meezi-api healthy
- Auto-prunes old images on success
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>