From 5176c20cce5c643e396fd6dff799cd21942f90fc Mon Sep 17 00:00:00 2001 From: John Smith Date: Thu, 28 Nov 2024 19:41:13 +1030 Subject: [PATCH] ci: Add Dockerfiles and build pipeline --- .github/workflows/build.yml | 96 +++++++++++++++++++++++++++++++++++- app/Dockerfile | 55 +++++++++++++++++++++ app/Dockerfile.dev | 16 ------ control-plane/Dockerfile | 39 +++++++++++++++ control-plane/Dockerfile.dev | 12 ----- 5 files changed, 189 insertions(+), 29 deletions(-) create mode 100644 app/Dockerfile delete mode 100644 app/Dockerfile.dev create mode 100644 control-plane/Dockerfile delete mode 100644 control-plane/Dockerfile.dev diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d8c27bfc..e6e31e4f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -158,7 +158,7 @@ jobs: - name: Build package run: npm run build env: - NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: ${{ secrets.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY }} + NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: ${{ secrets.CLOUD_PROD_CLERK_PUBLISHABLE_KEY }} build-node: needs: check_changes @@ -401,3 +401,97 @@ jobs: run: npm ci - name: Run tests run: npm test + + build-app-image: + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' }} + permissions: + id-token: write + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_ARN }} + aws-region: us-east-1 + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build App Docker Image + env: + IMAGE_TAG: ${{ github.sha }} + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY: inferable-app + run: | + cd app + VERSION=${{ github.sha }} + SHORT_VERSION=$(echo ${{ github.sha }} | cut -c 1-6) + docker buildx build \ + --target run \ + --push \ + --cache-to mode=min,image-manifest=true,oci-mediatypes=true,type=registry,ref=$ECR_REGISTRY/$ECR_REPOSITORY:cache \ + --cache-from type=registry,ref=$ECR_REGISTRY/$ECR_REPOSITORY:cache \ + --build-arg="VERSION=$VERSION" \ + --build-arg="SHORT_VERSION=$SHORT_VERSION" \ + --build-arg="NEXT_PUBLIC_INFERABLE_API_URL=${{ vars.API_URL }}" \ + --build-arg="NEXT_PUBLIC_APP_URL=${{ vars.APP_URL }}" \ + --build-arg="NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=${{ secrets.CLOUD_PROD_CLERK_PUBLISHABLE_KEY }}" \ + --build-arg="NEXT_PUBLIC_HYPERDX_API_KEY=${{ secrets.CLOUD_PROD_HYPERDX_API_KEY }}" \ + --build-arg="NEXT_PUBLIC_POSTHOG_KEY=${{ secrets.CLOUD_PROD_POSTHOG_KEY }}" \ + -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -t $ECR_REGISTRY/$ECR_REPOSITORY:latest ./ + + build-control-plane-image: + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' }} + permissions: + id-token: write + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_ARN }} + aws-region: us-east-1 + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build Control Plane Docker Image + env: + IMAGE_TAG: ${{ github.sha }} + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY: inferable-api + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }} + run: | + cd control-plane + VERSION=${{ github.sha }} + SHORT_VERSION=$(echo ${{ github.sha }} | cut -c 1-6) + docker buildx build \ + --target run \ + --push \ + --cache-to mode=min,image-manifest=true,oci-mediatypes=true,type=registry,ref=$ECR_REGISTRY/$ECR_REPOSITORY:cache \ + --cache-from type=registry,ref=$ECR_REGISTRY/$ECR_REPOSITORY:cache \ + --build-arg="VERSION=$VERSION" \ + --build-arg="SHORT_VERSION=$SHORT_VERSION" \ + -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -t $ECR_REGISTRY/$ECR_REPOSITORY:latest ./ + echo "Pushing Control Plane Image to Docker Hub" + docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD + docker pull $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG + docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $DOCKERHUB_USERNAME/control-plane:$IMAGE_TAG + docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $DOCKERHUB_USERNAME/control-plane:latest + docker push $DOCKERHUB_USERNAME/control-plane:$IMAGE_TAG + docker push $DOCKERHUB_USERNAME/control-plane:latest diff --git a/app/Dockerfile b/app/Dockerfile new file mode 100644 index 00000000..a807532b --- /dev/null +++ b/app/Dockerfile @@ -0,0 +1,55 @@ +# syntax = docker/dockerfile:1 + +ARG NODE_VERSION=20.11.1 + +FROM node:${NODE_VERSION}-slim AS base +WORKDIR /app + +FROM base AS build +WORKDIR /build +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 + +COPY --link ./ /build/ + +RUN npm ci + +ARG NEXT_PUBLIC_INFERABLE_API_URL +ENV NEXT_PUBLIC_INFERABLE_API_URL=$NEXT_PUBLIC_INFERABLE_API_URL + +ARG NEXT_PUBLIC_APP_URL +ENV NEXT_PUBLIC_APP_URL=$NEXT_PUBLIC_APP_URL + +ARG NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY +ENV NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=$NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY + +ARG NEXT_PUBLIC_HYPERDX_API_KEY +ENV NEXT_PUBLIC_HYPERDX_API_KEY=$NEXT_PUBLIC_HYPERDX_API_KEY + +ARG NEXT_PUBLIC_POSTHOG_KEY +ENV NEXT_PUBLIC_POSTHOG_KEY=$NEXT_PUBLIC_POSTHOG_KEY +ENV NEXT_PUBLIC_POSTHOG_HOST="https://www.inferable.ai/ingest" + +RUN npm run build +RUN npm prune --omit=dev + +FROM base AS run + +# Install curl for healthchecks +RUN apt-get update -qq && \ + apt-get install -y curl && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +ARG VERSION +ENV VERSION=$VERSION + +ARG SHORT_VERSION +ENV SHORT_VERSION=$SHORT_VERSION + +COPY --from=build /build/ /app + +ENV NODE_ENV=production + +EXPOSE 3001 +CMD [ "node", "server.js" ] diff --git a/app/Dockerfile.dev b/app/Dockerfile.dev deleted file mode 100644 index 17013777..00000000 --- a/app/Dockerfile.dev +++ /dev/null @@ -1,16 +0,0 @@ -FROM node:20 - -WORKDIR /app - -# copy package.json and package-lock.json -COPY --link package.json package-lock.json ./ - -# install dependencies -RUN npm install - -# copy source code -COPY --link . . - -RUN npm install - -ENTRYPOINT [ "npm", "run", "dev" ] \ No newline at end of file diff --git a/control-plane/Dockerfile b/control-plane/Dockerfile new file mode 100644 index 00000000..a64c3211 --- /dev/null +++ b/control-plane/Dockerfile @@ -0,0 +1,39 @@ +# syntax = docker/dockerfile:1 + +ARG NODE_VERSION=20.11.1 + +FROM node:${NODE_VERSION}-slim AS base +WORKDIR /app + +FROM base AS build +WORKDIR /build +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 + +COPY --link ./ /build + +RUN npm ci + +RUN npm run build +RUN npm prune --omit=dev + +FROM base AS run + +# Install curl for healthchecks +RUN apt-get update -qq && \ + apt-get install -y curl && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +ARG VERSION +ENV VERSION=$VERSION + +ARG SHORT_VERSION +ENV SHORT_VERSION=$SHORT_VERSION + +COPY --from=build /build/ /app + +ENV NODE_ENV=production + +EXPOSE 4000 +CMD [ "npm", "run", "start" ] diff --git a/control-plane/Dockerfile.dev b/control-plane/Dockerfile.dev deleted file mode 100644 index 96a10725..00000000 --- a/control-plane/Dockerfile.dev +++ /dev/null @@ -1,12 +0,0 @@ -FROM node:20 - -WORKDIR /app - -COPY package.json . -COPY package-lock.json . - -RUN npm install - -ADD . . - -ENTRYPOINT [ "npm", "run", "dev" ] \ No newline at end of file