Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@
node_modules
**/node_modules

# Submodules (not needed for frontend build)
submodules

# Other services (not needed for frontend build)
workers
# Other services (not needed for most builds)
services
database

Expand Down
18 changes: 14 additions & 4 deletions .github/actions/build-docker-image/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ inputs:
description: The APP_ENV to pass as a build argument
required: false
default: production
dockerfile:
description: Path to the Dockerfile
required: true
image-name:
description: Image name (e.g. insights-app, package-downloads-worker)
required: true
build-args:
description: Extra build args (newline-separated KEY=VALUE)
required: false
default: ''

outputs:
image:
Expand All @@ -21,7 +31,7 @@ runs:
run: |
SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-6)
IMAGE_VERSION="${SHORT_SHA}.${{ github.run_attempt }}"
IMAGE_TAG="sjc.ocir.io/axbydjxa5zuh/insights-app:${IMAGE_VERSION}"
IMAGE_TAG="sjc.ocir.io/axbydjxa5zuh/${{ inputs.image-name }}:${IMAGE_VERSION}"
echo "IMAGE_VERSION=${IMAGE_VERSION}" >> $GITHUB_OUTPUT
echo "IMAGE_TAG=${IMAGE_TAG}" >> $GITHUB_OUTPUT

Expand All @@ -39,11 +49,11 @@ runs:
uses: docker/build-push-action@v6
with:
context: .
file: frontend/Dockerfile
file: ${{ inputs.dockerfile }}
push: true
Comment on lines 49 to 53
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docker/build-push-action is invoked with context: ., which uses the repo-root .dockerignore. That .dockerignore currently excludes workers and submodules, but the worker Dockerfiles copy those paths, so builds for the worker services will fail with missing files. Consider updating the root .dockerignore to include these directories (or make the build context/dockerignore configurable per service) so worker builds have access to required sources.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is a valid comment, but might be worth checking out

tags: ${{ steps.tag-generator.outputs.IMAGE_TAG }}
build-args: |
APP_ENV=${{ inputs.app-env }}
NUXT_REDIS_URL=${{ env.NUXT_REDIS_URL }}
${{ inputs.build-args }}
no-cache: true
provenance: false
provenance: false
54 changes: 49 additions & 5 deletions .github/workflows/production-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ name: Production Deploy

on:
workflow_dispatch:
inputs:
service:
description: Service to deploy
required: true
type: choice
default: frontend
options:
- frontend
- package-downloads-worker
- search-volume-worker

env:
CLOUD_ENV: lf-oracle-production
Expand All @@ -21,6 +31,36 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive

- name: Set service config
id: config
run: |
case "${{ inputs.service }}" in
frontend)
echo "dockerfile=frontend/Dockerfile" >> $GITHUB_OUTPUT
echo "image_name=insights-app" >> $GITHUB_OUTPUT
echo "k8s_deployment=insights-app-dpl" >> $GITHUB_OUTPUT
Comment on lines +40 to +44
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The case over ${{ inputs.service }} has no default (*) branch. If this workflow is triggered with an unexpected value (e.g., via API), it will continue with empty outputs and fail later in a less obvious way. Consider adding a default branch that prints an error and exits non-zero.

Copilot uses AI. Check for mistakes.
echo "k8s_container=frontend" >> $GITHUB_OUTPUT
;;
package-downloads-worker)
echo "dockerfile=workers/temporal/package_downloads_worker/Dockerfile" >> $GITHUB_OUTPUT
echo "image_name=package-downloads-worker" >> $GITHUB_OUTPUT
echo "k8s_deployment=package-downloads-worker-dpl" >> $GITHUB_OUTPUT
echo "k8s_container=package-downloads-worker" >> $GITHUB_OUTPUT
;;
search-volume-worker)
echo "dockerfile=workers/temporal/search_volume_worker/Dockerfile" >> $GITHUB_OUTPUT
echo "image_name=insights-search-volume-worker" >> $GITHUB_OUTPUT
echo "k8s_deployment=search-volume-worker-dpl" >> $GITHUB_OUTPUT
echo "k8s_container=search-volume-worker" >> $GITHUB_OUTPUT
;;
*)
echo "::error::Unknown service: ${{ inputs.service }}"
exit 1
;;
esac

- name: Setup OCI CLI and Kubectl
run: |
Expand Down Expand Up @@ -64,17 +104,21 @@ jobs:
id: build-docker-image
with:
app-env: production
env:
NUXT_REDIS_URL: ${{ env.NUXT_REDIS_URL }}
dockerfile: ${{ steps.config.outputs.dockerfile }}
image-name: ${{ steps.config.outputs.image_name }}
build-args: ''

- name: Update Deployment Image
run: |
kubectl set image deployment/insights-app-dpl frontend=${{ steps.build-docker-image.outputs.image }} -n insights
kubectl rollout status deployment/insights-app-dpl -n insights --timeout=300s
kubectl set image deployment/${{ steps.config.outputs.k8s_deployment }} \
${{ steps.config.outputs.k8s_container }}=${{ steps.build-docker-image.outputs.image }} \
-n insights
kubectl rollout status deployment/${{ steps.config.outputs.k8s_deployment }} -n insights --timeout=300s

- name: Flush Redis cache
if: inputs.service == 'frontend'
run: |
REDIS_URL=$(kubectl get configmap insights-config-map -n insights -o jsonpath="{.data.NUXT_REDIS_URL}")
PASSWORD=$(echo "$REDIS_URL" | sed -n 's|.*://:\([^@]*\)@.*|\1|p')
kubectl exec -i redis-client -n insights -- \
redis-cli -h redis-svc -a "$PASSWORD" FLUSHALL
redis-cli -h redis-svc -a "$PASSWORD" FLUSHALL
51 changes: 47 additions & 4 deletions .github/workflows/staging-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ name: Staging Deploy

on:
workflow_dispatch:
inputs:
service:
description: Service to deploy
required: true
type: choice
default: frontend
options:
- frontend
- package-downloads-worker
- search-volume-worker

env:
CLOUD_ENV: lf-oracle-staging
Expand All @@ -21,6 +31,36 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive

- name: Set service config
id: config
run: |
case "${{ inputs.service }}" in
frontend)
echo "dockerfile=frontend/Dockerfile" >> $GITHUB_OUTPUT
echo "image_name=insights-app" >> $GITHUB_OUTPUT
echo "k8s_deployment=insights-app-dpl" >> $GITHUB_OUTPUT
Comment on lines +40 to +44
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The case over ${{ inputs.service }} has no default (*) branch. If this workflow is triggered with an unexpected value (e.g., via API), it will continue with empty outputs and fail later in a less obvious way. Consider adding a default branch that prints an error and exits non-zero.

Copilot uses AI. Check for mistakes.
echo "k8s_container=frontend" >> $GITHUB_OUTPUT
;;
package-downloads-worker)
echo "dockerfile=workers/temporal/package_downloads_worker/Dockerfile" >> $GITHUB_OUTPUT
echo "image_name=package-downloads-worker" >> $GITHUB_OUTPUT
echo "k8s_deployment=package-downloads-worker-dpl" >> $GITHUB_OUTPUT
echo "k8s_container=package-downloads-worker" >> $GITHUB_OUTPUT
;;
search-volume-worker)
echo "dockerfile=workers/temporal/search_volume_worker/Dockerfile" >> $GITHUB_OUTPUT
echo "image_name=insights-search-volume-worker" >> $GITHUB_OUTPUT
echo "k8s_deployment=search-volume-worker-dpl" >> $GITHUB_OUTPUT
echo "k8s_container=search-volume-worker" >> $GITHUB_OUTPUT
;;
*)
echo "::error::Unknown service: ${{ inputs.service }}"
exit 1
;;
esac

- name: Setup OCI CLI and Kubectl
run: |
Expand Down Expand Up @@ -64,10 +104,13 @@ jobs:
id: build-docker-image
with:
app-env: staging
env:
NUXT_REDIS_URL: ${{ env.NUXT_REDIS_URL }}
dockerfile: ${{ steps.config.outputs.dockerfile }}
image-name: ${{ steps.config.outputs.image_name }}
build-args: ''

- name: Update Deployment Image
run: |
kubectl set image deployment/insights-app-dpl frontend=${{ steps.build-docker-image.outputs.image }} -n insights
kubectl rollout status deployment/insights-app-dpl -n insights --timeout=300s
kubectl set image deployment/${{ steps.config.outputs.k8s_deployment }} \
${{ steps.config.outputs.k8s_container }}=${{ steps.build-docker-image.outputs.image }} \
-n insights
kubectl rollout status deployment/${{ steps.config.outputs.k8s_deployment }} -n insights --timeout=300s
4 changes: 1 addition & 3 deletions frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1.4
ARG NODE_VERSION=22
ARG NODE_VERSION=24

# ============================================
# Base stage: Node with pnpm via corepack
Expand Down Expand Up @@ -33,10 +33,8 @@ RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \
FROM deps AS builder

ARG APP_ENV=production
ARG NUXT_REDIS_URL

ENV NUXT_APP_ENV=$APP_ENV
ENV NUXT_REDIS_URL=$NUXT_REDIS_URL
ENV NODE_OPTIONS=--max-old-space-size=4096

WORKDIR /app
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ scripts/
.flake8
*.md
Makefile
backend/
backend/
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
FROM node:20-alpine as builder
FROM node:24-alpine AS builder

RUN apk add --no-cache python3 make g++

WORKDIR /usr/insights/app
RUN npm install -g corepack@latest && corepack enable pnpm && corepack prepare pnpm@9.15.0 --activate
RUN npm install -g corepack@latest && corepack enable pnpm && corepack prepare pnpm@10.12.4 --activate

COPY ./package.json ./pnpm-workspace.yaml ./pnpm-lock.yaml ./
RUN pnpm fetch
COPY ./patches ./patches
RUN pnpm fetch --ignore-scripts

COPY ./submodules ./submodules
COPY ./workers/temporal/base ./workers/temporal/base
COPY ./workers/temporal/package_downloads_worker ./workers/temporal/package_downloads_worker

RUN pnpm i --frozen-lockfile

FROM node:20-bookworm-slim as runner
FROM node:20-bookworm-slim AS runner

WORKDIR /usr/insights/app
RUN npm install -g corepack@latest && corepack enable pnpm && corepack prepare pnpm@9.15.0 --activate && apt update && apt install -y ca-certificates --no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN npm install -g corepack@latest && corepack enable pnpm && corepack prepare pnpm@10.12.4 --activate && apt update && apt install -y ca-certificates --no-install-recommends && rm -rf /var/lib/apt/lists/*

COPY --from=builder /usr/insights/app/node_modules ./node_modules
COPY --from=builder /usr/insights/app/submodules ./submodules
Expand Down
3 changes: 2 additions & 1 deletion workers/temporal/search_volume_worker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ RUN npm install -g corepack@latest && \

# Copy root-level files
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY patches ./patches

COPY ./workers/temporal/search_volume_worker/package.json ./workers/temporal/search_volume_worker/

# Pre-fetch dependencies and use a Docker cache mount for pnpm to speed up subsequent builds
RUN --mount=type=cache,id=pnpm,target=${PNPM_CACHE_DIR} pnpm config set store-dir ${PNPM_CACHE_DIR} && \
pnpm fetch --frozen-lockfile
pnpm fetch --frozen-lockfile --ignore-scripts

COPY ./submodules ./submodules
COPY ./workers/temporal/base ./workers/temporal/base
Expand Down