# C0PY — Deployment ## SIAX Cloud Deploy - **Config**: [`siax.config.json`](siax.config.json) - **CI/CD**: `.gitea/workflows/ci.yml` — körs vid push/PR till main (Gitea Actions, git.siax.io). Deploy är **manuell** (se nedan) — CI triggar ej Coolify (git-buildpack trasig för detta monorepo, auto-deploy togs bort 2026-09-16). - **Runtime**: Node 22, port 3000 - **Domain**: `c0py-web.siax.io` (web) / `c0py-api.siax.io` (API) ## Produktion (live 2026-09-16) | Komponent | Coolify app-uuid | Server | Domän | Image | |---|---|---|---|---| | API (Fastify) | `wvmn6eg40jofssvm3nigmav6` | server6 | `c0py-api.siax.io` | `wvmn6eg40jofssvm3nigmav6:latest` | | Web (Next.js) | `58pa82h4qlzcwsc4shreuwk0` | server6 | `c0py-web.siax.io` + `c0py.siax.io` (apex) | `58pa82h4qlzcwsc4shreuwk0:latest` | | Postgres | `qhucpjjpv3mx9jupqkbyf5uh` | server6 | — (internt) | — | - **Deploy-mönster**: Coolify-appar finns som registry-poster, men bygge sker manuellt på server6 (`/tmp/c0py-build && docker build -t :latest .`) följt av `cd /data/coolify/applications/ && docker compose up -d` — Coolifys dockerfile+git-buildpack sätter build-context till helper-container utan repo-trädet och failar för detta monorepo (`"/apps": not found`). - **DNS**: `c0py-api` + `c0py-web` = Cloudflare A → 65.109.19.146, **DNS-only** (proxied=false). Edge-certet täcker bara `*.siax.io` — tredjenivå-hostnames (`api.c0py.siax.io`) ger TLS-handshake-failure via proxied; DNS-only låter Traefik LE-certifiera direkt (samma mönster som api.act0.siax.io). - **⚠️ c0py.siax.io (apex) var kapad av en Cloudflare Worker/Pages** ("Hello World!", text/plain) — LÖST 2026-09-16 utan Workers-perms: apex A-recorden sattes **DNS-only** (proxied=false), vilket omgår Worker-routes (de gäller endast proxied-trafik), och `c0py.siax.io` lades som domän på web-appen (compose-labels + DB-fqdn). LE-cert utfärdas av Traefik (SAN under c0py-web-certet). **VARNING:** sätts apex-recorden till proxied=true igen kommer Worker:n tillbaka — CLOUDFLARE_API_TOKEN saknar Workers-perms (kan ej identifiera/radera Worker:n). Server6-fällor: Coolify regenererar compose-filen vid nästa deploy och tappar apex-Hostnamnet från labels — efter varje deploy, sed:a `Host(`c0py-web.siax.io`) || Host(`c0py.siax.io`)` i `/data/coolify/applications/58pa82h4qlzcwsc4shreuwk0/docker-compose.yaml` och recreate (docker rm -f + compose up). ## Deploy via Coolify - **Coolify dashboard**: `cloud.siax.io` - **Resource type**: Application (dockerfile build pack, git source git.siax.io/sax3l/c0py) - **Build pack**: Dockerfile — API: `/Dockerfile`, Web: `/Dockerfile.web` - **ports_exposes**: `3000` (KRITISKT — default 80 ger Trasfik-labels mot fel port) ## Docker ```bash docker build -t siax/c0py . docker run -d -p 3000:3000 \ -e PORT=3000 \ -e NODE_ENV=production \ -e DATABASE_URL=postgresql://... \ -e CL0UD_BASE_URL=https://cl0ud.siax.io \ -e ZITADEL_ISSUER=https://id-customers.siax.io \ -e ZITADEL_AUDIENCE=c0py-api.siax.io \ -e AUD0_BASE_URL=https://aud0.siax.io \ -e AUD0_API_KEY=... \ -e ST0RE_BASE_URL=https://st0re.siax.io \ siax/c0py ``` ## Miljövariabler | Variable | Krävs | Default | Beskrivning | |---|---|---|---| | `PORT` | Nej | `3000` | HTTP-serverport | | `NODE_ENV` | Nej | `development` | Läge | | `CL0UD_BASE_URL` | Ja | — | CL0UD kontrollplan URL | | `ZITADEL_ISSUER` | Ja | — | OIDC-utfärdare (`https://id-customers.siax.io`) | | `ZITADEL_AUDIENCE` | Ja | — | API-audience | | `ZITADEL_INTROSPECTION_CLIENT_ID` | Prod | — | RFC 7662-introspection-klient (Zitadel app `c0py-introspect`) — utan dessa körs endast Bearer-presence-check (warn-logg i prod) | | `ZITADEL_INTROSPECTION_CLIENT_SECRET` | Prod | — | Introspection-klientsecret (Infisical: `C0PY_ZITADEL_INTROSPECTION_CLIENT_SECRET`) | | `ZITADEL_EXPECTED_AUDIENCE` | Prod | — | Projektnivå-aud (Zitadel projekt-id `391064954179944451`); PAT-introspection bär aud=[clientId, projectId] | | `DATABASE_URL` | Ja | — | Postgres-anslutning | | `AUD0_BASE_URL` | Nej | — | AUD0 evidens-URL | | `AUD0_API_KEY` | Nej | — | AUD0 autentisering | | `ST0RE_BASE_URL` | Nej | — | ST0RE lagrings-URL | | `INF0_BASE_URL` | Nej | — | INF0 AI-URL | | `N0D_BASE_URL` | Nej | — | N0D beräknings-URL | ## Hälsocheck ``` GET /health ``` Förväntad respons: `200 OK`