From e88d21fa35299876ad7047ef0608079daeef242b Mon Sep 17 00:00:00 2001 From: Jackson Roberts Date: Wed, 8 Apr 2026 03:04:58 +0000 Subject: [PATCH] ci(global): go through and make sure all related files are working and good to go --- .github/workflows/api-build-and-publish.yaml | 2 +- .github/workflows/api-tests.yaml | 7 +- .github/workflows/dalpuri-tests.yaml | 33 ++ .github/workflows/deploy.yaml | 400 +++++++++++++++++++ .github/workflows/ui-build-and-publish.yaml | 106 ----- api/Dockerfile | 107 +++-- api/kubernetes/deployment.yaml | 23 +- api/kubernetes/ingress.yaml | 6 +- api/kubernetes/migration-job.yaml | 2 +- api/kubernetes/worker-deployment.yaml | 34 ++ api/src/api/server.ts | 2 + api/src/workert.ts | 5 +- ui/kubernetes/deployment.yaml | 2 +- 13 files changed, 584 insertions(+), 145 deletions(-) create mode 100644 .github/workflows/dalpuri-tests.yaml create mode 100644 .github/workflows/deploy.yaml delete mode 100644 .github/workflows/ui-build-and-publish.yaml create mode 100644 api/kubernetes/worker-deployment.yaml diff --git a/.github/workflows/api-build-and-publish.yaml b/.github/workflows/api-build-and-publish.yaml index c35acea..8b7254b 100644 --- a/.github/workflows/api-build-and-publish.yaml +++ b/.github/workflows/api-build-and-publish.yaml @@ -11,7 +11,7 @@ jobs: defaults: run: working-directory: api - steps: + steps:x - name: Checkout source code uses: actions/checkout@v4 diff --git a/.github/workflows/api-tests.yaml b/.github/workflows/api-tests.yaml index 1da5db8..01252fc 100644 --- a/.github/workflows/api-tests.yaml +++ b/.github/workflows/api-tests.yaml @@ -8,9 +8,6 @@ jobs: test: name: Test runs-on: ubuntu-latest - defaults: - run: - working-directory: api steps: - name: Checkout source code uses: actions/checkout@v4 @@ -23,8 +20,10 @@ jobs: - name: Install dependencies run: bun install --frozen-lockfile - - name: Generate Prisma client + - name: Generate API Prisma client run: DATABASE_URL="postgresql://dummy:dummy@localhost:5432/dummy" bunx prisma generate + working-directory: api - name: Run tests run: bun test --preload ./tests/setup.ts + working-directory: api diff --git a/.github/workflows/dalpuri-tests.yaml b/.github/workflows/dalpuri-tests.yaml new file mode 100644 index 0000000..b1025c7 --- /dev/null +++ b/.github/workflows/dalpuri-tests.yaml @@ -0,0 +1,33 @@ +name: Dalpuri - Tests + +on: + push: + branches: ["**"] + +jobs: + test: + name: Test + runs-on: ubuntu-latest + steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: "1.3.6" + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Generate Dalpuri Prisma client (CW MSSQL) + run: DATABASE_URL="sqlserver://localhost:1433;database=dummy;user=dummy;password=dummy;trustServerCertificate=true" bunx prisma generate + working-directory: dalpuri + + - name: Generate API Prisma client (required by Dalpuri translators) + run: DATABASE_URL="postgresql://dummy:dummy@localhost:5432/dummy" bunx prisma generate + working-directory: api + + - name: Run tests + run: bun test + working-directory: dalpuri diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml new file mode 100644 index 0000000..13c81f9 --- /dev/null +++ b/.github/workflows/deploy.yaml @@ -0,0 +1,400 @@ +name: Build and Deploy + +on: + release: + types: [created] + +jobs: + # ========================================================================== + # Test jobs — all three run concurrently. No build or deploy job may + # proceed until every test job has succeeded. + # ========================================================================== + + test-api: + name: Test - API + runs-on: ubuntu-latest + steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: "1.3.6" + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Generate API Prisma client + run: DATABASE_URL="postgresql://dummy:dummy@localhost:5432/dummy" bunx prisma generate + working-directory: api + + - name: Run API tests + run: bun test --preload ./tests/setup.ts + working-directory: api + + test-dalpuri: + name: Test - Dalpuri + runs-on: ubuntu-latest + steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: "1.3.6" + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Generate Dalpuri Prisma client (CW MSSQL) + run: DATABASE_URL="sqlserver://localhost:1433;database=dummy;user=dummy;password=dummy;trustServerCertificate=true" bunx prisma generate + working-directory: dalpuri + + - name: Generate API Prisma client (required by Dalpuri translators) + run: DATABASE_URL="postgresql://dummy:dummy@localhost:5432/dummy" bunx prisma generate + working-directory: api + + - name: Run Dalpuri tests + run: bun test + working-directory: dalpuri + + test-ui: + name: Test - UI + runs-on: ubuntu-latest + defaults: + run: + working-directory: ui + steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: "1.3.11" + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Run UI unit tests + run: bun run test:unit -- --run + env: + PUBLIC_API_URL: "https://api.example.com" + + # ========================================================================== + # Build jobs — run concurrently, but all require every test to pass first. + # ========================================================================== + + build-api: + name: Build - API + needs: [test-api, test-dalpuri, test-ui] + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push the API runtime image + uses: docker/build-push-action@v6 + with: + context: . + file: api/Dockerfile + push: true + target: runtime + tags: | + ghcr.io/horizonstacksoftware/optima-api:latest + ghcr.io/horizonstacksoftware/optima-api:${{ github.event.release.tag_name }} + + - name: Build and push the API migration image + uses: docker/build-push-action@v6 + with: + context: . + file: api/Dockerfile + push: true + target: migration + tags: | + ghcr.io/horizonstacksoftware/optima-api-migrate:latest + ghcr.io/horizonstacksoftware/optima-api-migrate:${{ github.event.release.tag_name }} + + build-worker: + name: Build - Worker + needs: [test-api, test-dalpuri, test-ui] + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push the worker image + uses: docker/build-push-action@v6 + with: + context: . + file: api/Dockerfile + push: true + target: worker + tags: | + ghcr.io/horizonstacksoftware/optima-worker:latest + ghcr.io/horizonstacksoftware/optima-worker:${{ github.event.release.tag_name }} + + build-ui-server: + name: Build - UI Server + needs: [test-api, test-dalpuri, test-ui] + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Build and push the UI server image + uses: docker/build-push-action@v6 + with: + context: ./ui + push: true + build-args: | + PUBLIC_API_URL=https://opt-api.osdci.net + tags: | + ghcr.io/horizonstacksoftware/optima-ui:latest + ghcr.io/horizonstacksoftware/optima-ui:${{ github.event.release.tag_name }} + + build-ui-desktop-macos: + name: Build - UI Desktop (macOS) + needs: [test-api, test-dalpuri, test-ui] + runs-on: macos-latest + permissions: + contents: write + defaults: + run: + working-directory: ui + steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Install Bun + uses: oven-sh/setup-bun@v2 + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Rebuild native modules + run: npm rebuild + + - name: Build macOS distributables + run: bun run make:macos + env: + PUBLIC_API_URL: https://opt-api.osdci.net + + - name: Upload macOS artifacts to release + uses: softprops/action-gh-release@v2 + with: + files: | + ui/out/make/**/*.dmg + ui/out/make/**/*.zip + + build-ui-desktop-windows: + name: Build - UI Desktop (Windows) + needs: [test-api, test-dalpuri, test-ui] + runs-on: windows-latest + permissions: + contents: write + defaults: + run: + working-directory: ui + steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Install dependencies + run: npm install + + - name: Build Windows distributables + run: npm run make -- --platform win32 + env: + PUBLIC_API_URL: https://opt-api.osdci.net + + - name: Upload Windows artifacts to release + uses: softprops/action-gh-release@v2 + with: + files: | + ui/out/make/**/*.exe + + # ========================================================================== + # Deploy jobs + # ========================================================================== + + migrate-api: + name: Migrate - API Database + needs: [build-api] + runs-on: ubuntu-latest + steps: + - name: Set the Kubernetes context + uses: azure/k8s-set-context@v2 + with: + method: kubeconfig + kubeconfig: ${{ secrets.KUBECONFIG }} + + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Delete previous migration job if exists + run: kubectl delete job -n optima -l app=prisma-migrate --ignore-not-found + + - name: Apply migration job + run: | + TAG=${{ github.event.release.tag_name }} + sed "s/RELEASE_TAG/${TAG}/g" api/kubernetes/migration-job.yaml | kubectl apply -f - + + - name: Wait for migration to complete + run: | + TAG=${{ github.event.release.tag_name }} + kubectl wait --for=condition=complete --timeout=120s -n optima job/prisma-migrate-${TAG} + + deploy-api: + name: Deploy - API + needs: [migrate-api] + runs-on: ubuntu-latest + steps: + - name: Set the Kubernetes context + uses: azure/k8s-set-context@v2 + with: + method: kubeconfig + kubeconfig: ${{ secrets.KUBECONFIG }} + + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Lint API Kubernetes manifests + uses: azure/k8s-lint@v3 + with: + lintType: dryrun + manifests: | + api/kubernetes/deployment.yaml + api/kubernetes/ingress.yaml + namespace: optima + + - name: Deploy API to the Kubernetes cluster + uses: azure/k8s-deploy@v5 + with: + namespace: optima + force: true + skip-tls-verify: true + manifests: | + api/kubernetes/deployment.yaml + api/kubernetes/ingress.yaml + images: | + ghcr.io/horizonstacksoftware/optima-api:${{ github.event.release.tag_name }} + + deploy-ui: + name: Deploy - UI Server + needs: [build-ui-server] + runs-on: ubuntu-latest + steps: + - name: Set the Kubernetes context + uses: azure/k8s-set-context@v2 + with: + method: kubeconfig + kubeconfig: ${{ secrets.KUBECONFIG }} + + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Lint UI Kubernetes manifests + uses: azure/k8s-lint@v3 + with: + lintType: dryrun + manifests: | + ui/kubernetes/deployment.yaml + ui/kubernetes/ingress.yaml + namespace: optima + + - name: Deploy UI to the Kubernetes cluster + uses: azure/k8s-deploy@v5 + with: + namespace: optima + force: true + skip-tls-verify: true + manifests: | + ui/kubernetes/deployment.yaml + ui/kubernetes/ingress.yaml + images: | + ghcr.io/horizonstacksoftware/optima-ui:${{ github.event.release.tag_name }} + + deploy-worker: + name: Deploy - Worker + needs: [build-worker] + runs-on: ubuntu-latest + steps: + - name: Set the Kubernetes context + uses: azure/k8s-set-context@v2 + with: + method: kubeconfig + kubeconfig: ${{ secrets.KUBECONFIG }} + + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Lint worker Kubernetes manifests + uses: azure/k8s-lint@v3 + with: + lintType: dryrun + manifests: | + api/kubernetes/worker-deployment.yaml + namespace: optima + + - name: Deploy worker to the Kubernetes cluster + uses: azure/k8s-deploy@v5 + with: + namespace: optima + force: true + skip-tls-verify: true + manifests: | + api/kubernetes/worker-deployment.yaml + images: | + ghcr.io/horizonstacksoftware/optima-worker:${{ github.event.release.tag_name }} diff --git a/.github/workflows/ui-build-and-publish.yaml b/.github/workflows/ui-build-and-publish.yaml deleted file mode 100644 index 51fc45b..0000000 --- a/.github/workflows/ui-build-and-publish.yaml +++ /dev/null @@ -1,106 +0,0 @@ -name: UI - Build and Publish - -on: - release: - types: [created] - -jobs: - build-server: - name: Build Server Image - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - steps: - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Checkout source code - uses: actions/checkout@v4 - - - name: Build and push the Docker image - uses: docker/build-push-action@v6 - with: - context: ./ui - push: true - build-args: | - PUBLIC_API_URL=https://opt-api.osdci.net - tags: | - ghcr.io/project-optima/ttscm-ui:latest - ghcr.io/project-optima/ttscm-ui:${{ github.event.release.tag_name }} - - build-desktop-macos: - name: Build Desktop (macOS) - runs-on: macos-latest - permissions: - contents: write - defaults: - run: - working-directory: ui - steps: - - name: Checkout source code - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: 22 - - - name: Install bun - uses: oven-sh/setup-bun@v2 - - - name: Install dependencies - run: bun install --frozen-lockfile - - - name: Rebuild native modules - run: npm rebuild - - - name: Build macOS distributables - run: bun run make:macos - env: - PUBLIC_API_URL: https://opt-api.osdci.net - - - name: Upload macOS artifacts to release - uses: softprops/action-gh-release@v2 - with: - files: | - ui/out/make/**/*.dmg - ui/out/make/**/*.zip - - build-desktop-windows: - name: Build Desktop (Windows) - runs-on: windows-latest - permissions: - contents: write - defaults: - run: - working-directory: ui - steps: - - name: Checkout source code - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: 22 - - - name: Install dependencies - run: npm install - - - name: Build Windows distributables - run: npm run make -- --platform win32 - env: - PUBLIC_API_URL: https://opt-api.osdci.net - - - name: Upload Windows artifacts to release - uses: softprops/action-gh-release@v2 - with: - files: | - ui/out/make/**/*.exe diff --git a/api/Dockerfile b/api/Dockerfile index 34b1813..f56d739 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -1,9 +1,20 @@ -# ---- Stage 1: Install dependencies ---- +# ============================================================================= +# Build context: monorepo root (.) +# This Dockerfile is built with `docker build -f api/Dockerfile .` from root. +# ============================================================================= + +# ---- Stage 1: Install production dependencies ---- FROM oven/bun:1 AS deps WORKDIR /app +# Copy root workspace manifest and lockfile COPY package.json bun.lock ./ + +# Copy workspace package manifests (source not needed — just for bun workspace resolution) +COPY api/package.json ./api/package.json +COPY dalpuri/package.json ./dalpuri/package.json + RUN bun install --frozen-lockfile --production # ---- Stage 2: Build ---- @@ -11,27 +22,51 @@ FROM oven/bun:1 AS build WORKDIR /app -# Copy dependency manifests and install all deps (including dev) +# Copy root workspace manifest and lockfile, plus workspace package manifests COPY package.json bun.lock ./ +COPY api/package.json ./api/package.json +COPY dalpuri/package.json ./dalpuri/package.json + +# Install all deps (including dev) for the full workspace RUN bun install --frozen-lockfile -# Copy source code and supporting files -COPY src/ src/ -COPY prisma/ prisma/ -COPY prisma.config.ts tsconfig.json ./ +# Copy API source and config +COPY api/src/ ./api/src/ +COPY api/prisma/ ./api/prisma/ +COPY api/prisma.config.ts api/tsconfig.json ./api/ +COPY api/logo.png ./api/logo.png -# Generate Prisma client (dummy URL — generate only needs the schema, not a real DB) +# Copy Dalpuri source and Prisma schema +COPY dalpuri/src/ ./dalpuri/src/ +COPY dalpuri/prisma/ ./dalpuri/prisma/ +COPY dalpuri/prisma.config.ts ./dalpuri/prisma.config.ts + +# Generate Dalpuri Prisma client (ConnectWise MSSQL schema) +# prisma generate does not connect — dummy URL just satisfies the env requirement +WORKDIR /app/dalpuri +RUN DATABASE_URL="sqlserver://localhost:1433;database=dummy;user=dummy;password=dummy;trustServerCertificate=true" \ + bunx prisma generate + +# Generate API Prisma client (PostgreSQL schema) +WORKDIR /app/api RUN DATABASE_URL="postgresql://dummy:dummy@localhost:5432/dummy" bunx prisma generate -# Compile to a standalone executable +# Compile the API server to a standalone binary RUN NODE_ENV=production bun build src/index.ts \ --compile \ --minify \ --target=bun-linux-x64 \ --outfile=server -# ---- Stage 3: Production image ---- -FROM ubuntu:22.04 AS runtime +# Compile the worker process to a standalone binary +RUN NODE_ENV=production bun build src/workert.ts \ + --compile \ + --minify \ + --target=bun-linux-x64 \ + --outfile=worker + +# ---- Stage 3: Shared runtime base (API server and worker share the same deps/files) ---- +FROM ubuntu:22.04 AS runtime-base WORKDIR /app @@ -40,40 +75,56 @@ RUN apt-get update && \ apt-get install -y --no-install-recommends ca-certificates && \ rm -rf /var/lib/apt/lists/* -# Copy the compiled binary from the build stage -COPY --from=build /app/server ./server - -# Quote PDF branding asset loaded at runtime by pdf generation -COPY logo.png ./logo.png - -# Sales tax lookup data loaded by expectedSalesTax at runtime -COPY --from=build /app/src/modules/sales-utils/salesTaxRates.json ./salesTaxRates.json - # Copy Prisma artifacts needed at runtime -COPY --from=build /app/generated/ ./generated/ -COPY --from=build /app/prisma/ ./prisma/ -COPY --from=build /app/prisma.config.ts ./prisma.config.ts +COPY --from=build /app/api/generated/ ./generated/ +COPY --from=build /app/api/prisma/ ./prisma/ +COPY --from=build /app/api/prisma.config.ts ./prisma.config.ts + +# Copy Dalpuri generated Prisma client (worker imports dalpuri which references this) +COPY --from=build /app/dalpuri/generated/ ./dalpuri/generated/ # Copy production node_modules (Prisma adapter needs native bindings) COPY --from=deps /app/node_modules/ ./node_modules/ ENV NODE_ENV=production -EXPOSE 3000 +# ---- Stage 4: API server runtime image ---- +FROM runtime-base AS runtime + +# API-specific: PDF branding asset and sales tax lookup data +COPY --from=build /app/api/server ./server +COPY --from=build /app/api/logo.png ./logo.png +COPY --from=build /app/api/src/modules/sales-utils/salesTaxRates.json ./salesTaxRates.json + +EXPOSE 3000 CMD ["./server"] -# ---- Stage 4: Migration runner ---- +# ---- Stage 5: Worker runtime image ---- +FROM runtime-base AS worker + +COPY --from=build /app/api/worker ./worker + +# Default to localhost for local dev; override with k8s internal service URL in production +ENV MANAGER_SOCKET_URL=http://localhost:8671 + +CMD ["./worker"] + +# ---- Stage 6: Migration runner ---- FROM oven/bun:1 AS migration WORKDIR /app +# Copy workspace manifests for bun workspace resolution COPY package.json bun.lock ./ +COPY api/package.json ./api/package.json +COPY dalpuri/package.json ./dalpuri/package.json + RUN bun install --frozen-lockfile -COPY prisma/ prisma/ -COPY prisma.config.ts ./ +COPY api/prisma/ ./api/prisma/ +COPY api/prisma.config.ts ./api/prisma.config.ts -COPY prisma/migrate-entrypoint.sh ./prisma/migrate-entrypoint.sh -RUN chmod +x prisma/migrate-entrypoint.sh +RUN chmod +x /app/api/prisma/migrate-entrypoint.sh +WORKDIR /app/api CMD ["sh", "prisma/migrate-entrypoint.sh"] \ No newline at end of file diff --git a/api/kubernetes/deployment.yaml b/api/kubernetes/deployment.yaml index 2c216fa..4899398 100644 --- a/api/kubernetes/deployment.yaml +++ b/api/kubernetes/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: optima-api - image: ghcr.io/project-optima/ttscm-api:latest + image: ghcr.io/horizonstacksoftware/optima-api:latest imagePullPolicy: Always envFrom: - secretRef: @@ -24,5 +24,26 @@ spec: name: optima-keys-secret ports: - containerPort: 3000 + resources: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "512Mi" + cpu: "1000m" + livenessProbe: + httpGet: + path: /healthz + port: 3000 + initialDelaySeconds: 10 + periodSeconds: 30 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /healthz + port: 3000 + initialDelaySeconds: 5 + periodSeconds: 10 + failureThreshold: 2 imagePullSecrets: - name: github-container-registry diff --git a/api/kubernetes/ingress.yaml b/api/kubernetes/ingress.yaml index e738516..1b7dec2 100644 --- a/api/kubernetes/ingress.yaml +++ b/api/kubernetes/ingress.yaml @@ -33,7 +33,11 @@ metadata: spec: type: ClusterIP ports: - - port: 3000 + - name: http + port: 3000 + protocol: TCP + - name: worker-comms + port: 8671 protocol: TCP selector: app: optima-api diff --git a/api/kubernetes/migration-job.yaml b/api/kubernetes/migration-job.yaml index b886822..4ef87bf 100644 --- a/api/kubernetes/migration-job.yaml +++ b/api/kubernetes/migration-job.yaml @@ -12,7 +12,7 @@ spec: spec: containers: - name: migrate - image: ghcr.io/project-optima/ttscm-api-migrate:RELEASE_TAG + image: ghcr.io/horizonstacksoftware/optima-api-migrate:RELEASE_TAG envFrom: - secretRef: name: api-env-secret diff --git a/api/kubernetes/worker-deployment.yaml b/api/kubernetes/worker-deployment.yaml new file mode 100644 index 0000000..90e3eab --- /dev/null +++ b/api/kubernetes/worker-deployment.yaml @@ -0,0 +1,34 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: optima-worker + namespace: optima +spec: + selector: + matchLabels: + app: optima-worker + replicas: 1 + template: + metadata: + labels: + app: optima-worker + spec: + containers: + - name: optima-worker + image: ghcr.io/horizonstacksoftware/optima-worker:latest + imagePullPolicy: Always + env: + - name: MANAGER_SOCKET_URL + value: "http://optima-api.optima.svc.cluster.local:8671" + envFrom: + - secretRef: + name: api-env-secret + resources: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "512Mi" + cpu: "1000m" + imagePullSecrets: + - name: github-container-registry diff --git a/api/src/api/server.ts b/api/src/api/server.ts index e52907e..fdcc661 100644 --- a/api/src/api/server.ts +++ b/api/src/api/server.ts @@ -46,6 +46,8 @@ app.onError((err, ctx) => { app.use("*", cors()); +app.get("/healthz", (c) => c.json({ status: "ok" })); + app.notFound((c) => { const response = apiResponse.error( new GenericError({ diff --git a/api/src/workert.ts b/api/src/workert.ts index b95c3ed..d18be99 100644 --- a/api/src/workert.ts +++ b/api/src/workert.ts @@ -37,7 +37,8 @@ export function ensureManagerSocketReady(): Promise { return Promise.resolve(managerSocket); if (managerSocketReadyPromise) return managerSocketReadyPromise; - managerSocket = io("http://localhost:8671", { + const managerUrl = process.env.MANAGER_SOCKET_URL ?? "http://localhost:8671"; + managerSocket = io(managerUrl, { reconnection: true, reconnectionDelay: 1000, reconnectionDelayMax: 5000, @@ -152,7 +153,7 @@ if (import.meta.main) { console.log("[worker] Worker process starting..."); console.log( - "[worker] Connecting to PgBoss on DATABASE_URL and SocketIO on :8671" + `[worker] Connecting to PgBoss on DATABASE_URL and SocketIO on ${process.env.MANAGER_SOCKET_URL ?? "http://localhost:8671"}` ); // Ensure PgBoss is connected and queues exist diff --git a/ui/kubernetes/deployment.yaml b/ui/kubernetes/deployment.yaml index 4d74712..110d0b6 100644 --- a/ui/kubernetes/deployment.yaml +++ b/ui/kubernetes/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: optima-ui - image: ghcr.io/project-optima/ttscm-ui:latest + image: ghcr.io/horizonstacksoftware/optima-ui:latest imagePullPolicy: Always resources: requests: