From 3c823258dd811b6cfd69545514d254f93a80d4f6 Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 01:23:36 -0500 Subject: [PATCH 01/22] Containerize app, Dockerfile and ignore --- web/.dockerignore | 7 +++++ web/Dockerfile | 69 +++++++++++++++++++++++++++++++++++++++++++++ web/next.config.mjs | 5 +--- 3 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 web/.dockerignore create mode 100644 web/Dockerfile diff --git a/web/.dockerignore b/web/.dockerignore new file mode 100644 index 0000000..72e9aa4 --- /dev/null +++ b/web/.dockerignore @@ -0,0 +1,7 @@ +Dockerfile +.dockerignore +node_modules +npm-debug.log +README.md +.next +.git \ No newline at end of file diff --git a/web/Dockerfile b/web/Dockerfile new file mode 100644 index 0000000..8450f7d --- /dev/null +++ b/web/Dockerfile @@ -0,0 +1,69 @@ +# Next.js Dockerfile taken from example repo - https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile +FROM node:18-alpine AS base + +# Install dependencies only when needed +FROM base AS deps +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. +RUN apk add --no-cache libc6-compat +WORKDIR /app + +# Install dependencies based on the preferred package manager +COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ +RUN \ + if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ + elif [ -f package-lock.json ]; then npm ci; \ + elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \ + else echo "Lockfile not found." && exit 1; \ + fi + + +# Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry during the build. +ENV NEXT_TELEMETRY_DISABLED=1 + +RUN \ + if [ -f yarn.lock ]; then yarn run build; \ + elif [ -f package-lock.json ]; then npm run build; \ + elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \ + else echo "Lockfile not found." && exit 1; \ + fi + +# Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app + +ENV NODE_ENV=production +# Uncomment the following line in case you want to disable telemetry during runtime. +# ENV NEXT_TELEMETRY_DISABLED=1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=builder /app/public ./public + +# Set the correct permission for prerender cache +RUN mkdir .next +RUN chown nextjs:nodejs .next + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 + +ENV PORT=3000 + +# server.js is created by next build from the standalone output +# https://nextjs.org/docs/pages/api-reference/next-config-js/output +ENV HOSTNAME="0.0.0.0" +CMD ["node", "server.js"] \ No newline at end of file diff --git a/web/next.config.mjs b/web/next.config.mjs index 5cb5eb2..01761fd 100644 --- a/web/next.config.mjs +++ b/web/next.config.mjs @@ -1,10 +1,7 @@ /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, - output: "export", - images: { - unoptimized: true, - }, + output: "standalone", }; export default nextConfig; From 23c52df516e194a0d89c5b825a71b0bb00d9e7a3 Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 03:00:10 -0500 Subject: [PATCH 02/22] Add docker build to pipeline --- .github/workflows/main.yml | 19 ++++++++++++++++--- .github/workflows/predeploy.yml | 7 ++++++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 20d40f9..5539bb7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -47,8 +47,8 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} needs: ["TF-Apply"] steps: - - name: Check Out - uses: actions/checkout@v4 + - name: Set up Docker Buildx and Checkout + uses: docker/setup-buildx-action@v3 - name: Use Node.js uses: actions/setup-node@v4 - name: Configure AWS Credentials @@ -68,7 +68,12 @@ jobs: cd web echo "NEXT_PUBLIC_APIGW=${{needs.TF-Apply.outputs.apigw}}" > .env - - name: 🔨 Build Project + - name: 🔨 Build Static Project + run: | + cd web + npm run build + + - name: đŸŗ Build Image run: | cd web npm run build @@ -77,3 +82,11 @@ jobs: run: | aws s3 sync ./web/out s3://${{ secrets.S3_BUCKET }}/ --region us-west-2 aws s3 sync ./web/out s3://${{ secrets.S3_BUCKET }}-failover/ --region us-west-2 + + - name: 🌩ī¸ Upload Image + uses: docker/build-push-action@v6 + with: + file: ./web/Dockerfile + push: false # if we wanted to push the image to DockerHub + add-hosts: 3000:3000 + tags: user/app:latest diff --git a/.github/workflows/predeploy.yml b/.github/workflows/predeploy.yml index 7c6c9ae..fe983ea 100644 --- a/.github/workflows/predeploy.yml +++ b/.github/workflows/predeploy.yml @@ -70,7 +70,12 @@ jobs: cd web echo "NEXT_PUBLIC_APIGW=${{needs.TF-Apply.outputs.apigw}}" > .env - - name: 🔨 Build Project + - name: 🔨 Build Static Project + run: | + cd web + npm run build + + - name: đŸŗ Build Image run: | cd web npm run build From 510222c8f1327c35d2ecca3c2a85024d0ba427c3 Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 03:05:28 -0500 Subject: [PATCH 03/22] Test shared deploy and Docker build --- .github/workflows/bundle_test.yml | 93 +++++++++++++++++++++++++++++++ web/next.config.mjs | 5 +- 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/bundle_test.yml diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml new file mode 100644 index 0000000..918e16c --- /dev/null +++ b/.github/workflows/bundle_test.yml @@ -0,0 +1,93 @@ +on: + push: + branches: + - "34-Throw-it-in-a-box!" +permissions: + pull-requests: write +name: 🌱 Apply, Build, Deploy đŸŒŋ +jobs: + TF-Apply: + name: 🏗ī¸ Apply Infra + runs-on: ubuntu-latest + # https://stackoverflow.com/questions/59175332/using-output-from-a-previous-job-in-a-new-one-in-a-github-action + outputs: + apigw: ${{steps.APIGW.outputs.NEXT_PUBLIC_APIGW}} + steps: + - name: Check Out + uses: actions/checkout@v4 + - name: Setup Terraform + uses: hashicorp/setup-terraform@v3 + with: + cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }} + terraform_version: 1.9.2 + - name: Look around nd Init 👁ī¸đŸ‘ī¸ + run: | + echo Looking around 👁ī¸đŸ‘ī¸ + ls + cd terraform + echo Looking around 👁ī¸đŸ‘ī¸ + ls + terraform init + - name: 🏗ī¸ Terraform Apply + run: | + cd terraform + terraform apply -var="bucket-name=${{ secrets.S3_BUCKET }}" -var="db-name=${{ secrets.DB_NAME }}" -var="db-username=${{ secrets.DB_USER }}" -auto-approve + - run: echo ${{ steps.plan.outputs.stdout }} + - run: echo ${{ steps.plan.outputs.stderr }} + - run: echo ${{ steps.plan.outputs.exitcode }} + - name: Fetch API GW + id: APIGW + run: | + cd terraform + echo "NEXT_PUBLIC_APIGW=$(terraform output -raw api-route)" >> $GITHUB_OUTPUT + web-deploy: + name: đŸ’Ģ Deploy + runs-on: ubuntu-latest + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + needs: ["TF-Apply"] + steps: + - name: Set up Docker Buildx and Checkout + uses: docker/setup-buildx-action@v3 + - name: Use Node.js + uses: actions/setup-node@v4 + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4.0.2 + with: + aws-region: us-west-2 + aws-access-key-id: ${{secrets.AWS_ACCESS_KEY_ID}} + aws-secret-access-key: ${{secrets.AWS_SECRET_ACCESS_KEY}} + + - name: đŸ˜Ē Installing Dependencies + run: | + cd web + npm install + + - name: ⚗ī¸ Write env variables + run: | + cd web + echo "NEXT_PUBLIC_APIGW=${{needs.TF-Apply.outputs.apigw}}" > .env + + - name: 🔨 Build Static Project + run: | + cd web + STATIC=1 npm run build + + - name: đŸŗ Build Image + run: | + cd web + npm run build + + - name: 🚀 Upload Package + run: | + aws s3 sync ./web/out s3://${{ secrets.S3_BUCKET }}/ --region us-west-2 + aws s3 sync ./web/out s3://${{ secrets.S3_BUCKET }}-failover/ --region us-west-2 + + - name: 🌩ī¸ Upload Image + uses: docker/build-push-action@v6 + with: + file: ./web/Dockerfile + push: false # if we wanted to push the image to DockerHub + add-hosts: 3000:3000 + tags: user/app:latest diff --git a/web/next.config.mjs b/web/next.config.mjs index 01761fd..cea775f 100644 --- a/web/next.config.mjs +++ b/web/next.config.mjs @@ -1,7 +1,10 @@ /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, - output: "standalone", + output: process.env.STATIC ? "export" : "standalone", + images: { + unoptimized: process.env.STATIC ? true : false, + }, }; export default nextConfig; From 84afc08e3007c4cdb9be32f2fff2a26c2567a24a Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 03:11:52 -0500 Subject: [PATCH 04/22] Bring back checkout --- .github/workflows/bundle_test.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml index 918e16c..bf16185 100644 --- a/.github/workflows/bundle_test.yml +++ b/.github/workflows/bundle_test.yml @@ -4,7 +4,7 @@ on: - "34-Throw-it-in-a-box!" permissions: pull-requests: write -name: 🌱 Apply, Build, Deploy đŸŒŋ +name: ✨ Build Test 🧐 jobs: TF-Apply: name: 🏗ī¸ Apply Infra @@ -48,7 +48,9 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} needs: ["TF-Apply"] steps: - - name: Set up Docker Buildx and Checkout + - name: Check Out + uses: actions/checkout@v4 + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Use Node.js uses: actions/setup-node@v4 From e9cd1ff347e32a12df73b0fa0450a71192f44397 Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 03:22:33 -0500 Subject: [PATCH 05/22] Clean up build params --- .github/workflows/bundle_test.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml index bf16185..49f80ec 100644 --- a/.github/workflows/bundle_test.yml +++ b/.github/workflows/bundle_test.yml @@ -76,20 +76,19 @@ jobs: cd web STATIC=1 npm run build - - name: đŸŗ Build Image - run: | - cd web - npm run build - - name: 🚀 Upload Package run: | aws s3 sync ./web/out s3://${{ secrets.S3_BUCKET }}/ --region us-west-2 aws s3 sync ./web/out s3://${{ secrets.S3_BUCKET }}-failover/ --region us-west-2 - - name: 🌩ī¸ Upload Image + - name: đŸŗ Build and Upload Image uses: docker/build-push-action@v6 with: file: ./web/Dockerfile push: false # if we wanted to push the image to DockerHub add-hosts: 3000:3000 tags: user/app:latest + cache-to: user/app:cache + outputs: type=local,dest=./alpine_storefront + secret-envs: NEXT_PUBLIC_APIGW=${{needs.TF-Apply.outputs.apigw}} + secret-files: ./web/.env From 3b06bdab508c13c10e72802e0ee51ad7b253fdca Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 03:25:56 -0500 Subject: [PATCH 06/22] Allegedly .env isn't a valid secret --- .github/workflows/bundle_test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml index 49f80ec..546b838 100644 --- a/.github/workflows/bundle_test.yml +++ b/.github/workflows/bundle_test.yml @@ -91,4 +91,3 @@ jobs: cache-to: user/app:cache outputs: type=local,dest=./alpine_storefront secret-envs: NEXT_PUBLIC_APIGW=${{needs.TF-Apply.outputs.apigw}} - secret-files: ./web/.env From 92f23594fbe7d0c6bd57935c39553b197bbc6aea Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 03:48:32 -0500 Subject: [PATCH 07/22] Invalid hosts --- .github/workflows/bundle_test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml index 546b838..c269ea0 100644 --- a/.github/workflows/bundle_test.yml +++ b/.github/workflows/bundle_test.yml @@ -86,7 +86,6 @@ jobs: with: file: ./web/Dockerfile push: false # if we wanted to push the image to DockerHub - add-hosts: 3000:3000 tags: user/app:latest cache-to: user/app:cache outputs: type=local,dest=./alpine_storefront From d072577997b574b80881848a3abd48e3e87b6097 Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 03:55:56 -0500 Subject: [PATCH 08/22] Add path context --- .github/workflows/bundle_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml index c269ea0..0d70d14 100644 --- a/.github/workflows/bundle_test.yml +++ b/.github/workflows/bundle_test.yml @@ -84,6 +84,7 @@ jobs: - name: đŸŗ Build and Upload Image uses: docker/build-push-action@v6 with: + context: ./web/ file: ./web/Dockerfile push: false # if we wanted to push the image to DockerHub tags: user/app:latest From aef4eb8dcfb24f71dc2ee5c68f4c0d3e7fd5a9e1 Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 04:20:54 -0500 Subject: [PATCH 09/22] cache-to was attempting to upload to Dockerhub, since errors are thrown if there's no upload I'm continuing past it and failing if the upload finds nothing. --- .github/workflows/bundle_test.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml index 0d70d14..31081ff 100644 --- a/.github/workflows/bundle_test.yml +++ b/.github/workflows/bundle_test.yml @@ -81,13 +81,22 @@ jobs: aws s3 sync ./web/out s3://${{ secrets.S3_BUCKET }}/ --region us-west-2 aws s3 sync ./web/out s3://${{ secrets.S3_BUCKET }}-failover/ --region us-west-2 - - name: đŸŗ Build and Upload Image + - name: đŸŗ Build Image uses: docker/build-push-action@v6 with: context: ./web/ file: ./web/Dockerfile push: false # if we wanted to push the image to DockerHub tags: user/app:latest - cache-to: user/app:cache + # cache-to: type=local,dest=user/app:cache outputs: type=local,dest=./alpine_storefront secret-envs: NEXT_PUBLIC_APIGW=${{needs.TF-Apply.outputs.apigw}} + continue-on-error: true + + - name: 🌩ī¸ Upload Image + uses: actions/upload-artifact@v4 + with: + if-no-files-found: error + overwrite: true + name: storefront_img + path: ./web/alpine_storefront From 778b4a225b6c514544a229c90dba3bec3cdea834 Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 04:26:56 -0500 Subject: [PATCH 10/22] Try again with no continue, looks like artifact is uploaded regardless --- .github/workflows/bundle_test.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml index 31081ff..0441d02 100644 --- a/.github/workflows/bundle_test.yml +++ b/.github/workflows/bundle_test.yml @@ -91,12 +91,3 @@ jobs: # cache-to: type=local,dest=user/app:cache outputs: type=local,dest=./alpine_storefront secret-envs: NEXT_PUBLIC_APIGW=${{needs.TF-Apply.outputs.apigw}} - continue-on-error: true - - - name: 🌩ī¸ Upload Image - uses: actions/upload-artifact@v4 - with: - if-no-files-found: error - overwrite: true - name: storefront_img - path: ./web/alpine_storefront From 69e1c079d66002437bfaa2a3acf4c6a8040f4cb1 Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 04:49:41 -0500 Subject: [PATCH 11/22] Look around --- .github/workflows/bundle_test.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml index 0441d02..d70dcc3 100644 --- a/.github/workflows/bundle_test.yml +++ b/.github/workflows/bundle_test.yml @@ -91,3 +91,8 @@ jobs: # cache-to: type=local,dest=user/app:cache outputs: type=local,dest=./alpine_storefront secret-envs: NEXT_PUBLIC_APIGW=${{needs.TF-Apply.outputs.apigw}} + + - name: Look around + run: | + ls + ls ./web \ No newline at end of file From 71f9715eb3931aba6b27c835dc4a4935e70ef72b Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 10:36:29 -0500 Subject: [PATCH 12/22] Bring back artifact upload --- .github/workflows/bundle_test.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml index d70dcc3..ec137d5 100644 --- a/.github/workflows/bundle_test.yml +++ b/.github/workflows/bundle_test.yml @@ -94,5 +94,14 @@ jobs: - name: Look around run: | - ls - ls ./web \ No newline at end of file + ls + ls ./web + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + id: artifact-upload-step + with: + name: storefront_image + path: ./alpine_storefront + overwrite: true + if-no-files-found: error From 3e94aa69d6e761b3f6c28ed79bb42150a3e3ca02 Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 10:52:06 -0500 Subject: [PATCH 13/22] Change upload path, got EACCESS error --- .github/workflows/bundle_test.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml index ec137d5..35d7d0b 100644 --- a/.github/workflows/bundle_test.yml +++ b/.github/workflows/bundle_test.yml @@ -94,14 +94,13 @@ jobs: - name: Look around run: | - ls - ls ./web + ls -E - name: Upload Artifact uses: actions/upload-artifact@v4 id: artifact-upload-step with: name: storefront_image - path: ./alpine_storefront + path: /alpine_storefront overwrite: true if-no-files-found: error From 7818709fe1cdf2ac15d44990a960284b06f504eb Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 10:57:24 -0500 Subject: [PATCH 14/22] verbose ls --- .github/workflows/bundle_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml index 35d7d0b..d6a206e 100644 --- a/.github/workflows/bundle_test.yml +++ b/.github/workflows/bundle_test.yml @@ -94,7 +94,7 @@ jobs: - name: Look around run: | - ls -E + ls -l - name: Upload Artifact uses: actions/upload-artifact@v4 From cf5776afd3b13f1ce3838c76d37a6e56f234badf Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 11:40:41 -0500 Subject: [PATCH 15/22] Now we're certain of the path and structure https://github.com/Guysnacho/ssg-s3/actions/runs/11406988041/job/31742046921 --- .github/workflows/bundle_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml index d6a206e..1b0293c 100644 --- a/.github/workflows/bundle_test.yml +++ b/.github/workflows/bundle_test.yml @@ -101,6 +101,6 @@ jobs: id: artifact-upload-step with: name: storefront_image - path: /alpine_storefront + path: ./alpine_storefront overwrite: true if-no-files-found: error From efa9696c0f48f8d76d4551a75be89878c1947b4b Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 11:52:02 -0500 Subject: [PATCH 16/22] Move artifact somewhere we have permission to upload from --- .github/workflows/bundle_test.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml index 1b0293c..81f8a5b 100644 --- a/.github/workflows/bundle_test.yml +++ b/.github/workflows/bundle_test.yml @@ -92,15 +92,14 @@ jobs: outputs: type=local,dest=./alpine_storefront secret-envs: NEXT_PUBLIC_APIGW=${{needs.TF-Apply.outputs.apigw}} - - name: Look around - run: | - ls -l + - name: Move Image to copyable location + run: cp ./alpine_storefront /home/alpine_storefront - name: Upload Artifact uses: actions/upload-artifact@v4 id: artifact-upload-step with: name: storefront_image - path: ./alpine_storefront + path: /home/alpine_storefront overwrite: true if-no-files-found: error From d4a0c651fe7ace71efc0e14116d68fb0212d140e Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 12:01:34 -0500 Subject: [PATCH 17/22] Fix copy and send the artifact to an SSM param --- .github/workflows/bundle_test.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml index 81f8a5b..9c07a61 100644 --- a/.github/workflows/bundle_test.yml +++ b/.github/workflows/bundle_test.yml @@ -93,7 +93,7 @@ jobs: secret-envs: NEXT_PUBLIC_APIGW=${{needs.TF-Apply.outputs.apigw}} - name: Move Image to copyable location - run: cp ./alpine_storefront /home/alpine_storefront + run: sudo cp ./alpine_storefront /home/ - name: Upload Artifact uses: actions/upload-artifact@v4 @@ -103,3 +103,8 @@ jobs: path: /home/alpine_storefront overwrite: true if-no-files-found: error + + - name: Echo artifact url and send to SSM parameter + run: | + echo ARTIFACT_URL=${{steps.artifact-upload-step.outputs.artifact-url}} >> $GITHUB_OUTPUT + aws ssm put-parameter --name "ecr_artifact_url" --value "${{steps.artifact-upload-step.outputs.artifact-url}}" --type String From b9457d0e35357fe0c2618f1f139e593505f15a08 Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 12:19:42 -0500 Subject: [PATCH 18/22] Get some info on location of our image, might need to tar it --- .github/workflows/bundle_test.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml index 9c07a61..6edad2d 100644 --- a/.github/workflows/bundle_test.yml +++ b/.github/workflows/bundle_test.yml @@ -93,7 +93,13 @@ jobs: secret-envs: NEXT_PUBLIC_APIGW=${{needs.TF-Apply.outputs.apigw}} - name: Move Image to copyable location - run: sudo cp ./alpine_storefront /home/ + run: | + stat ./alpine_storefront + ls -l + sudo cp -r ./alpine_storefront /home/ + ls -l /home/ + ls -l /home/alpine_storefront + continue-on-error: true - name: Upload Artifact uses: actions/upload-artifact@v4 From d9c0569ec60304bbe603891fcfce93e216f2cd20 Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 12:28:13 -0500 Subject: [PATCH 19/22] Tar our image because we're given a folder instead of a single file --- .github/workflows/bundle_test.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml index 6edad2d..62b34ed 100644 --- a/.github/workflows/bundle_test.yml +++ b/.github/workflows/bundle_test.yml @@ -96,17 +96,16 @@ jobs: run: | stat ./alpine_storefront ls -l - sudo cp -r ./alpine_storefront /home/ - ls -l /home/ + tar -zcvf alpine_storefront.tar.gz ./alpine_storefront + sudo cp ./alpine_storefront.tar.gz /home/ ls -l /home/alpine_storefront - continue-on-error: true - name: Upload Artifact uses: actions/upload-artifact@v4 id: artifact-upload-step with: name: storefront_image - path: /home/alpine_storefront + path: /home/alpine_storefront.tar.gz overwrite: true if-no-files-found: error From f0f796c49be05cf35da2a249908904e18915adb6 Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 12:34:53 -0500 Subject: [PATCH 20/22] Clean up output --- .github/workflows/bundle_test.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml index 62b34ed..a3ce223 100644 --- a/.github/workflows/bundle_test.yml +++ b/.github/workflows/bundle_test.yml @@ -96,9 +96,8 @@ jobs: run: | stat ./alpine_storefront ls -l - tar -zcvf alpine_storefront.tar.gz ./alpine_storefront + tar -zcf alpine_storefront.tar.gz ./alpine_storefront sudo cp ./alpine_storefront.tar.gz /home/ - ls -l /home/alpine_storefront - name: Upload Artifact uses: actions/upload-artifact@v4 @@ -111,5 +110,5 @@ jobs: - name: Echo artifact url and send to SSM parameter run: | - echo ARTIFACT_URL=${{steps.artifact-upload-step.outputs.artifact-url}} >> $GITHUB_OUTPUT + echo ARTIFACT_URL=${{steps.artifact-upload-step.outputs.artifact-url}} aws ssm put-parameter --name "ecr_artifact_url" --value "${{steps.artifact-upload-step.outputs.artifact-url}}" --type String From f5775a9fded715fbbad530f57e0409d1b5449dda Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 12:55:18 -0500 Subject: [PATCH 21/22] Update main workflows --- .github/workflows/bundle_test.yml | 114 ------------------------------ .github/workflows/main.yml | 41 ++++++++--- .github/workflows/predeploy.yml | 26 +++++-- 3 files changed, 51 insertions(+), 130 deletions(-) delete mode 100644 .github/workflows/bundle_test.yml diff --git a/.github/workflows/bundle_test.yml b/.github/workflows/bundle_test.yml deleted file mode 100644 index a3ce223..0000000 --- a/.github/workflows/bundle_test.yml +++ /dev/null @@ -1,114 +0,0 @@ -on: - push: - branches: - - "34-Throw-it-in-a-box!" -permissions: - pull-requests: write -name: ✨ Build Test 🧐 -jobs: - TF-Apply: - name: 🏗ī¸ Apply Infra - runs-on: ubuntu-latest - # https://stackoverflow.com/questions/59175332/using-output-from-a-previous-job-in-a-new-one-in-a-github-action - outputs: - apigw: ${{steps.APIGW.outputs.NEXT_PUBLIC_APIGW}} - steps: - - name: Check Out - uses: actions/checkout@v4 - - name: Setup Terraform - uses: hashicorp/setup-terraform@v3 - with: - cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }} - terraform_version: 1.9.2 - - name: Look around nd Init 👁ī¸đŸ‘ī¸ - run: | - echo Looking around 👁ī¸đŸ‘ī¸ - ls - cd terraform - echo Looking around 👁ī¸đŸ‘ī¸ - ls - terraform init - - name: 🏗ī¸ Terraform Apply - run: | - cd terraform - terraform apply -var="bucket-name=${{ secrets.S3_BUCKET }}" -var="db-name=${{ secrets.DB_NAME }}" -var="db-username=${{ secrets.DB_USER }}" -auto-approve - - run: echo ${{ steps.plan.outputs.stdout }} - - run: echo ${{ steps.plan.outputs.stderr }} - - run: echo ${{ steps.plan.outputs.exitcode }} - - name: Fetch API GW - id: APIGW - run: | - cd terraform - echo "NEXT_PUBLIC_APIGW=$(terraform output -raw api-route)" >> $GITHUB_OUTPUT - web-deploy: - name: đŸ’Ģ Deploy - runs-on: ubuntu-latest - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - needs: ["TF-Apply"] - steps: - - name: Check Out - uses: actions/checkout@v4 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Use Node.js - uses: actions/setup-node@v4 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4.0.2 - with: - aws-region: us-west-2 - aws-access-key-id: ${{secrets.AWS_ACCESS_KEY_ID}} - aws-secret-access-key: ${{secrets.AWS_SECRET_ACCESS_KEY}} - - - name: đŸ˜Ē Installing Dependencies - run: | - cd web - npm install - - - name: ⚗ī¸ Write env variables - run: | - cd web - echo "NEXT_PUBLIC_APIGW=${{needs.TF-Apply.outputs.apigw}}" > .env - - - name: 🔨 Build Static Project - run: | - cd web - STATIC=1 npm run build - - - name: 🚀 Upload Package - run: | - aws s3 sync ./web/out s3://${{ secrets.S3_BUCKET }}/ --region us-west-2 - aws s3 sync ./web/out s3://${{ secrets.S3_BUCKET }}-failover/ --region us-west-2 - - - name: đŸŗ Build Image - uses: docker/build-push-action@v6 - with: - context: ./web/ - file: ./web/Dockerfile - push: false # if we wanted to push the image to DockerHub - tags: user/app:latest - # cache-to: type=local,dest=user/app:cache - outputs: type=local,dest=./alpine_storefront - secret-envs: NEXT_PUBLIC_APIGW=${{needs.TF-Apply.outputs.apigw}} - - - name: Move Image to copyable location - run: | - stat ./alpine_storefront - ls -l - tar -zcf alpine_storefront.tar.gz ./alpine_storefront - sudo cp ./alpine_storefront.tar.gz /home/ - - - name: Upload Artifact - uses: actions/upload-artifact@v4 - id: artifact-upload-step - with: - name: storefront_image - path: /home/alpine_storefront.tar.gz - overwrite: true - if-no-files-found: error - - - name: Echo artifact url and send to SSM parameter - run: | - echo ARTIFACT_URL=${{steps.artifact-upload-step.outputs.artifact-url}} - aws ssm put-parameter --name "ecr_artifact_url" --value "${{steps.artifact-upload-step.outputs.artifact-url}}" --type String diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5539bb7..1b56cfe 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -47,7 +47,9 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} needs: ["TF-Apply"] steps: - - name: Set up Docker Buildx and Checkout + - name: Check Out + uses: actions/checkout@v4 + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Use Node.js uses: actions/setup-node@v4 @@ -71,22 +73,41 @@ jobs: - name: 🔨 Build Static Project run: | cd web - npm run build - - - name: đŸŗ Build Image - run: | - cd web - npm run build + STATIC=1 npm run build - name: 🚀 Upload Package run: | aws s3 sync ./web/out s3://${{ secrets.S3_BUCKET }}/ --region us-west-2 aws s3 sync ./web/out s3://${{ secrets.S3_BUCKET }}-failover/ --region us-west-2 - - name: 🌩ī¸ Upload Image + - name: đŸŗ Build Image uses: docker/build-push-action@v6 with: + context: ./web/ file: ./web/Dockerfile - push: false # if we wanted to push the image to DockerHub - add-hosts: 3000:3000 + push: false # if we wanted to push the image to DockerHub or a local registry tags: user/app:latest + # cache-to: type=local,dest=user/app:cache + outputs: type=local,dest=./alpine_storefront + secret-envs: NEXT_PUBLIC_APIGW=${{needs.TF-Apply.outputs.apigw}} + + - name: Move Image to copyable location + run: | + stat ./alpine_storefront + ls -l + tar -zcf alpine_storefront.tar.gz ./alpine_storefront + sudo cp ./alpine_storefront.tar.gz /home/ + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + id: artifact-upload-step + with: + name: storefront_image + path: /home/alpine_storefront.tar.gz + overwrite: true + if-no-files-found: error + + - name: Echo artifact url and send to SSM parameter + run: | + echo ARTIFACT_URL=${{steps.artifact-upload-step.outputs.artifact-url}} + aws ssm put-parameter --name "ecr_artifact_url" --value "${{steps.artifact-upload-step.outputs.artifact-url}}" --type String diff --git a/.github/workflows/predeploy.yml b/.github/workflows/predeploy.yml index fe983ea..8938c6c 100644 --- a/.github/workflows/predeploy.yml +++ b/.github/workflows/predeploy.yml @@ -31,7 +31,7 @@ jobs: - name: 🏗ī¸ Terraform Plan run: | cd terraform - terraform plan -var="bucket-name=${{ secrets.S3_BUCKET }}" -var="db-name=${{ secrets.DB_NAME }}" -var="db-username=${{ secrets.DB_USER }}" # -auto-approve + terraform plan -refresh-only -var="bucket-name=${{ secrets.S3_BUCKET }}" -var="db-name=${{ secrets.DB_NAME }}" -var="db-username=${{ secrets.DB_USER }}" # -auto-approve - run: echo ${{ steps.plan.outputs.stdout }} - run: echo ${{ steps.plan.outputs.stderr }} - run: echo ${{ steps.plan.outputs.exitcode }} @@ -50,6 +50,8 @@ jobs: steps: - name: Check Out uses: actions/checkout@v4 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - name: Use Node.js uses: actions/setup-node@v4 - name: Configure AWS Credentials @@ -58,8 +60,7 @@ jobs: aws-region: us-west-2 aws-access-key-id: ${{secrets.AWS_ACCESS_KEY_ID}} aws-secret-access-key: ${{secrets.AWS_SECRET_ACCESS_KEY}} - - name: Setup Terraform - uses: hashicorp/setup-terraform@v3 + - name: đŸ˜Ē Installing Dependencies run: | cd web @@ -73,9 +74,22 @@ jobs: - name: 🔨 Build Static Project run: | cd web - npm run build + STATIC=1 npm run build - name: đŸŗ Build Image + uses: docker/build-push-action@v6 + with: + context: ./web/ + file: ./web/Dockerfile + push: false # if we wanted to push the image to DockerHub or a local registry + tags: user/app:latest + # cache-to: type=local,dest=user/app:cache + outputs: type=local,dest=./alpine_storefront + secret-envs: NEXT_PUBLIC_APIGW=${{needs.TF-Apply.outputs.apigw}} + + - name: Move Image to copyable location run: | - cd web - npm run build + stat ./alpine_storefront + ls -l + tar -zcf alpine_storefront.tar.gz ./alpine_storefront + sudo cp ./alpine_storefront.tar.gz /home/ From a9ec830bad494f5e617c71019003b2fc641b9058 Mon Sep 17 00:00:00 2001 From: Samuel Adetunji Date: Fri, 18 Oct 2024 13:02:26 -0500 Subject: [PATCH 22/22] Update readme --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index c5f5196..d09b6ac 100644 --- a/README.md +++ b/README.md @@ -4,18 +4,17 @@ This repo is to help me actually build this AWS course. ~Shouldn't be too hard~ This has and will continue to be a learning experience. Follow along, check the releases, make a fork, go crazy, but check the [Project Home](https://blackbelt-init.notion.site/) for more details. ✨ -## Initial Plan - -### Monorepo +## Project Layout - Terraform Package - Web package -- Github workflows with Smart builds - - Applies after grep on repo - - If changes in AWS package, apply tf apply first - - Put [plan output](https://github.com/marketplace/actions/github-script#welcome-a-first-time-contributor) in PR - - Deploy static package -- Look into [atmos](https://atmos.tools/) for environments +- Github workflows + - Applies terraform infra changes after commits to main branch + - Bundles our app into static site files and a Docker image + - Deploys uploads static site to S3 to be served by CloudFront + - Uploads our Docker Image to the run context + - Updates an SSM parameter's value to this artifact's URL + - Important note - by default, an artifact upload will only live for 90 days. Keep this in mind if you want to roll changes back to a given date past that. ### Local Setup @@ -25,5 +24,6 @@ This repo is to help me actually build this AWS course. ~Shouldn't be too hard~ 4. Build starter [Next](https://nextjs.org/) site 1. [Configure ssg export](https://nextjs.org/docs/pages/building-your-application/deploying/static-exports) 5. Setup bucket, cloudfront, provider, outputs, whatever else locally -6. Setup workflow -7. Make it smart +6. Add GitHub action secrets +7. Test workflows +8. Sip water