diff --git a/.forgejo/workflows/deploy-scraper-google.yml b/.forgejo/workflows/deploy-scraper-google.yml new file mode 100644 index 0000000..d9e63af --- /dev/null +++ b/.forgejo/workflows/deploy-scraper-google.yml @@ -0,0 +1,56 @@ +name: Deploy scraper-google + +# Forgejo Actions (git.altricade.com). Workflow files live in .forgejo/workflows/. +# Mirrors the old .gitlab-ci.yml deploy: build/test the Go code, then SSH + rsync +# to the server and `docker compose up -d --build` for scraper-google. +on: + push: + workflow_dispatch: {} # manual "deploy" button, matching the GitLab `when: manual` gate + +jobs: + build: + runs-on: go # golang:1.23-bookworm — Go auto-fetches the 1.24 toolchain (go.work is 1.24) + steps: + - uses: actions/checkout@v4 + - run: go version + - run: go build ./... + - run: go test ./... + + deploy: + needs: build + runs-on: docker # node:22-bookworm (Debian) — has the Docker socket + # Only deploy from the default branch, and only when triggered manually, + # matching `if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH / when: manual`. + if: ${{ github.event_name == 'workflow_dispatch' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }} + environment: + name: production + # url: https://jobs-scraper.ai-assistant-bot.xyz + steps: + - uses: actions/checkout@v4 + + - name: Install ssh + rsync + run: | + apt-get update + apt-get install -y --no-install-recommends openssh-client rsync + + - name: Set up SSH key + run: | + mkdir -p ~/.ssh + printf '%s' "${{ secrets.SSH_PRIVATE_KEY }}" | tr -d '\r' > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh-keyscan -H "${{ secrets.DEPLOY_HOST }}" >> ~/.ssh/known_hosts + + - name: Sync project to server + run: | + ssh "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" "mkdir -p /opt/apps/jobs-scraper" + rsync -az --delete \ + --exclude='.git' \ + --exclude='.env' \ + --exclude='.env.*' \ + --exclude='.local.env' \ + ./ "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}:/opt/apps/jobs-scraper/" + + - name: Build & start on server + run: | + ssh "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" \ + "cd /opt/apps/jobs-scraper/services/scraper-google && docker compose up -d --build" diff --git a/altricade-ci-guide.md b/altricade-ci-guide.md new file mode 100644 index 0000000..abd231f --- /dev/null +++ b/altricade-ci-guide.md @@ -0,0 +1,133 @@ +# Using CI on git.altricade.com (Forgejo Actions) + +This is a self-hosted **Forgejo** git server with **Forgejo Actions** (CI/CD). +A shared runner is already set up and running on the server — **you do not need to +install or register anything.** Just add a workflow file to your repo and it runs. + +> Forgejo Actions uses the same syntax as GitHub Actions, so most GitHub workflow +> examples work here with minor tweaks (mainly the `runs-on:` label — see below). + +--- + +## Quick start + +1. In your repo, create a file at: + ``` + .forgejo/workflows/ci.yml + ``` +2. Paste a workflow (see examples below). +3. Commit & push. +4. Open your repo's **Actions** tab to watch it run. + +Minimal example: +```yaml +name: CI +on: [push] +jobs: + build: + runs-on: docker + steps: + - uses: actions/checkout@v4 + - run: echo "Hello from CI" +``` + +--- + +## Important: `runs-on:` must match a runner label + +The shared runner only provides these labels. Your `runs-on:` **must** be one of them, +or the job will never start (it'll sit "waiting for a runner"): + +| Label | Image it runs in | Use for | +|------------------|-----------------------------|------------------------------------------| +| `docker` | `node:22-bookworm` | General jobs, `docker` / `docker compose`, Node | +| `node` | `node:22-bookworm` | Node projects | +| `go` | `golang:1.23-bookworm` | Go projects | +| `ubuntu-latest` | `catthehacker/ubuntu:act-22.04` | GitHub-compatible workflows (heavier image) | + +**Tip:** prefer `docker`, `node`, or `go` — they use small images that pull fast. +Use `ubuntu-latest` only if a workflow really needs the full GitHub-style environment +(its image is ~2 GB and slow to download the first time). + +--- + +## Examples + +### Go project +```yaml +name: Go CI +on: [push] +jobs: + test: + runs-on: go + steps: + - uses: actions/checkout@v4 + - run: go version + - run: go build ./... + - run: go test ./... +``` + +### Node project +```yaml +name: Node CI +on: [push] +jobs: + test: + runs-on: node + steps: + - uses: actions/checkout@v4 + - run: node --version + - run: npm ci + - run: npm test +``` + +### Docker / docker compose build +```yaml +name: Build +on: [push] +jobs: + build: + runs-on: docker + steps: + - uses: actions/checkout@v4 + - run: docker --version + - run: docker compose build +``` +> The runner has access to Docker, so `docker` and `docker compose` commands work +> inside jobs. + +--- + +## Good to know + +- **First run of any new image is slow** — the runner downloads the job image once, + then caches it on the server. Later runs are fast. +- **The runner is shared and capped at 1 concurrent job.** If we both push at the same + time, jobs queue and run one after another. That's expected on this server. +- **Triggers:** `on: [push]` runs on every push. You can also use + `on: [pull_request]`, schedules, manual `workflow_dispatch`, etc. — same as GitHub Actions. +- **Where things live:** workflow files go in `.forgejo/workflows/` in each repo. +- **Actions like `actions/checkout@v4`** are fetched from the public Forgejo actions + registry the first time; also cached after. + +--- + +## If a job doesn't start + +- Check `runs-on:` is exactly one of: `docker`, `node`, `go`, `ubuntu-latest`. +- Check the **Actions** tab of the repo for the run and its logs. +- If it's stuck "waiting", the label probably doesn't match, or the shared runner is + busy with another job (wait for it to finish). + +--- + +## Notes for an LLM helping with this + +- This is **Forgejo Actions** (not GitHub Actions, not GitLab CI). Syntax is + GitHub-Actions-compatible; workflow files live in `.forgejo/workflows/*.yml`. +- Jobs run in **Docker containers** on a shared self-hosted runner. +- Valid `runs-on:` values are limited to the runner's registered labels: + `docker` and `node` → `node:22-bookworm`, `go` → `golang:1.23-bookworm`, + `ubuntu-latest` → `catthehacker/ubuntu:act-22.04`. Do **not** invent other labels. +- The runner has the Docker socket available, so `docker` / `docker compose` work in jobs. +- Concurrency is capped at 1; assume no parallelism across jobs. diff --git a/services/api/docker-compose.yml b/services/api/docker-compose.yml index 3c3ea5e..a9578fa 100644 --- a/services/api/docker-compose.yml +++ b/services/api/docker-compose.yml @@ -7,7 +7,7 @@ services: ports: - "8080:8080" environment: - DB_HOST: shared_postgres + DB_HOST: postgres DB_PORT: 5432 DB_NAME: jobs_scraper DB_USER: scraper_user @@ -21,13 +21,7 @@ services: networks: - proxy restart: unless-stopped - labels: - - traefik.enable=true - - traefik.docker.network=proxy - - traefik.http.routers.api-jobs.rule=Host(`api-jobs.ai-assistant-bot.xyz`) - - traefik.http.routers.api-jobs.entrypoints=web,websecure - - traefik.http.routers.api-jobs.tls.certresolver=le - - traefik.http.services.api-jobs.loadbalancer.server.port=8080 + # deploy: # resources: # limits: diff --git a/services/scraper-google/docker-compose.yml b/services/scraper-google/docker-compose.yml index 012e70e..209f161 100644 --- a/services/scraper-google/docker-compose.yml +++ b/services/scraper-google/docker-compose.yml @@ -7,7 +7,7 @@ services: dockerfile: services/scraper-google/Dockerfile container_name: jobs-scraper-google environment: - DB_HOST: shared_postgres + DB_HOST: postgres DB_PORT: 5432 DB_NAME: jobs_scraper DB_USER: scraper_user @@ -26,7 +26,8 @@ services: CHROMEDP_DISABLE_GPU: true CHROMEDP_NO_SANDBOX: true networks: - - proxy + - backend # internal — reach Postgres + - proxy # has internet egress (nginx-proxy-manager network) restart: unless-stopped deploy: resources: @@ -38,5 +39,7 @@ services: cpus: "0.5" networks: + backend: + external: true proxy: external: true