# Jenkins CI — custom image build + Forgejo registry Repo: `https://git.aexoradao.com/epistemophiliac/erpnext.git` Branch: `main` Registry image: `git.aexoradao.com/epistemophiliac/erpnext` ## What Jenkins does | Stage | Purpose | |-------|---------| | **Verify** | Required files including `apps.json`, `Containerfile` | | **Production readiness** | Secrets/docs/compose checks | | **Bootstrap Docker tools** | Static docker CLI + compose, socket access | | **Compose validate** | Coolify-safe `docker compose config` | | **Build custom image** | `bench init` from `apps.json` (ERPNext, HRMS, Lending, LMS, payments) | | **Push to Forgejo registry** | Tags `main-` and `main` | | **Verify registry pull** | Confirms the pushed image is pullable | **Artifacts:** `dist/coolify-image.env`, `dist/docker-compose.coolify.yml`, `dist/image-reference.txt` First image build can take **30–60+ minutes** (compiles assets). Later builds use Docker layer cache unless `apps.json` changes. ## Jenkins job setup Same as before — **Pipeline from SCM** or **Multibranch** with **Discover branches**. **Credentials:** `forgejo-erpnext` (username + Forgejo token) — used for git checkout **and** `docker login git.aexoradao.com`. Token needs: - Repo read (checkout) - **Package write** (push container images to Forgejo registry) Enable **Packages** on the Forgejo repo if pushes fail with 404/403. ## After a green build Download `dist/coolify-image.env` from Jenkins artifacts, or use: ```env CUSTOM_IMAGE=git.aexoradao.com/epistemophiliac/erpnext CUSTOM_TAG=main- PULL_POLICY=always ``` Set those in Coolify before deploy (or use `CUSTOM_TAG=main` for latest main build). ## Changing apps (HRMS, Lending, LMS, …) 1. Edit [`apps.json`](../apps.json) (branches must match `FRAPPE_BRANCH=version-16` where applicable) 2. Push to `main` 3. Jenkins rebuilds and pushes a new image tag 4. Update `CUSTOM_TAG` in Coolify and redeploy ## Troubleshooting ### Build fails: `BuildKit is enabled but the buildx component is missing` The bootstrap stage installs the **buildx** CLI plugin into `.ci-bin/docker-config/cli-plugins/`. If this regresses, re-run **Build Now** on latest `main` (not Rebuild on an old commit). ### `permission denied` on `/var/run/docker.sock` Set `DOCKER_GID` on the Jenkins Coolify service to the host docker group GID (`stat -c '%g' /var/run/docker.sock`), redeploy Jenkins. ### Registry push 401/403 - Token needs **write:package** (or full repo scope including packages) - `docker login git.aexoradao.com` with same credentials as git ### Build fails on `bench init` - All apps in `apps.json` must be compatible with `version-16` - LMS has no `version-16` branch — pinned to tag `v2.55.0` in `apps.json` ### `source: not found` All pipeline steps use `bash scripts/ci/*.sh` — do not use `source` in bare `sh '''` blocks. ### Use **Build Now**, not **Rebuild** on old runs Rebuild replays an old commit.