erpnext/docs/COOLIFY_DEPLOY.md
epistemophiliac 2aca11bb75 Use :main tag only and host sync instead of compose preload.
Remove image-preload service (compose creates all containers before it can run); Jenkins and sync-main-from-forgejo.sh load :main on the host internally.
2026-06-16 21:05:44 -04:00

87 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Coolify deployment — Production ERPNext (+ HRMS, Lending, LMS)
## Prerequisites
- Coolify v4+ with Docker Compose support
- Jenkins green build → image in Forgejo Packages
- **4 GB+ RAM** (8 GB+ recommended)
- Compose file: `docker-compose.yml`
## 1. Create the Coolify service
| Setting | Value |
|---------|--------|
| Type | Docker Compose |
| Repository | `https://git.aexoradao.com/epistemophiliac/erpnext` |
| Branch | `main` |
| Compose file | `docker-compose.yml` |
## 2. Environment variables (Coolify UI)
Copy from [`coolify.env.example`](../coolify.env.example). **Required before first deploy:**
| Variable | Set in Coolify? | Source |
|----------|----------------|--------|
| `CUSTOM_IMAGE` | yes | Jenkins artifact / `dist/coolify-image.env` |
| `CUSTOM_TAG` | yes | `main` (latest Jenkins build — do not pin commit tags) |
| `PULL_POLICY` | yes | `if_not_present` |
| `DB_PASSWORD` | yes | strong secret |
| `ADMIN_PASSWORD` | yes | Frappe `Administrator` password |
| `INSTALL_APPS` | yes | `erpnext,payments,hrms,lending,lms` |
| `SITE_NAME` | **no** (auto) | From Coolify domain via `SERVICE_FQDN_FRONTEND` |
| `FRAPPE_SITE_NAME_HEADER` | **no** (auto) | Same as domain via `SERVICE_FQDN_FRONTEND` |
> **Coolify env cache:** If you previously set `SITE_NAME=erp.example.com` in Coolify, **delete it** so compose defaults use your real domain. Changing `docker-compose.yml` defaults alone does not update stored values.
## 3. Domain (before first deploy)
1. Coolify → your service → **Domains**
2. Add domain, e.g. `erp.aexoradao.com`
3. Attach to service **`frontend`**, port **`8080`**
4. Coolify writes `SERVICE_FQDN_FRONTEND=erp.aexoradao.com` into the stack `.env`
5. Compose sets:
- `create-site``SITE_NAME=erp.aexoradao.com`
- `frontend``FRAPPE_SITE_NAME_HEADER=erp.aexoradao.com`
**Order matters:** assign domain **then** deploy. If `create-site` runs with an empty site name, the stack exits with a clear error.
## 4. Image on the Coolify host (before first deploy)
The custom image is **~1.2 GB**. Coolify must find `git.aexoradao.com/epistemophiliac/erpnext:main` on the **host** Docker daemon — not pulled through Cloudflare during deploy.
**Jenkins does this automatically** after each green build (`jenkins-push-image.sh` copies `:main` from internal Forgejo via Skopeo).
**Manual / one-time** on the Coolify server as root:
```bash
export REGISTRY_USER=epistemophiliac
export REGISTRY_PASSWORD='<forgejo-token>'
bash scripts/coolify/sync-main-from-forgejo.sh
```
Coolify env: `CUSTOM_TAG=main` only — no `main-<sha>` pins.
## 5. First deploy
```text
db → redis → configurator
→ create-site (install apps, ~1020 min)
→ migrator → backend / workers / frontend
```
Login: `https://your-domain` — user `Administrator`, password = `ADMIN_PASSWORD`.
## 6. Upgrades
1. Jenkins builds new image → pushes `:main` and preloads host Docker
2. Redeploy Coolify — `if_not_present` uses the updated local `:main`
## Troubleshooting
| Symptom | Fix |
|---------|-----|
| `SITE_NAME empty` on create-site | Assign domain on `frontend:8080` before deploy |
| Wrong site / 404 nginx | Delete old `SITE_NAME` in Coolify UI; ensure header matches domain |
| Site created with wrong name | Wipe `sites` volume or rename site manually — env change alone won't rename |
| Deploy fails at pull / `No such image` | Run `scripts/coolify/sync-main-from-forgejo.sh` on host, or Jenkins **Build Now** (preloads `:main`) |
| Image pull failed | Ensure `:main` on host via Jenkins or sync script — do not pull large image through Cloudflare |