diff --git a/.github/workflows/awsdeploy.yml b/.github/workflows/awsdeploy.yml index bc4351911..9d73404ad 100644 --- a/.github/workflows/awsdeploy.yml +++ b/.github/workflows/awsdeploy.yml @@ -1,117 +1,30 @@ # Based on https://docs.github.com/en/actions/deployment/deploying-to-your-cloud-provider/deploying-to-amazon-elastic-container-service -name: aws ecs deploy +name: aws ecs deploy - blake on: push: branches: - main -env: - AWS_REGION: us-east-1 # set this to your preferred AWS region, e.g. us-west-1 - ECR_REPOSITORY: pubpub-v7 # set this to your Amazon ECR repository name - ECS_SERVICE: blake-core # set this to your Amazon ECS service name - ECS_CLUSTER: blake-ecs-cluster-staging # set this to your Amazon ECS cluster name - ECS_TASK_DEFINITION_TEMPLATE: blake-core # set this to the FAMILY of your task definition - CONTAINER_NAME: core # set this to the name of the container in the - # containerDefinitions section of your task definition - jobs: - build: - name: Build - runs-on: ubuntu-latest - environment: production - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: ${{ env.AWS_REGION }} - - - name: Get short sha - id: shortsha - run: echo "sha_short=$(git describe --always --abbrev=40 --dirty)" >> $GITHUB_OUTPUT - - - name: Login to Amazon ECR - id: login-ecr - uses: aws-actions/amazon-ecr-login@v2 - - - name: Build, tag, and push image to Amazon ECR - id: build-image - env: - ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - IMAGE_TAG: ${{ steps.shortsha.outputs.sha_short }} - run: | - # Build a docker container and - # push it to ECR so that it can - # be deployed to ECS. - docker build \ - --platform linux/amd64 \ - --build-arg PACKAGE=core \ - --build-arg PACKAGE_DIR=core \ - -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG \ - . - docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG - echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT - - deploy: - name: Deploy - runs-on: ubuntu-latest - environment: production - needs: - - build - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: ${{ env.AWS_REGION }} - - - name: Get short sha - id: shortsha - run: echo "sha_short=$(git describe --always --abbrev=40 --dirty)" >> $GITHUB_OUTPUT - - - name: Login to Amazon ECR - id: login-ecr - uses: aws-actions/amazon-ecr-login@v2 - - - name: Retrieve Task Definition contents from template - id: get-taskdef - run: | - aws ecs describe-task-definition \ - --task-definition $ECS_TASK_DEFINITION_TEMPLATE \ - --query taskDefinition >> template_task_def.json - - - name: Interpolate image tag - id: write-tag - env: - ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - IMAGE_TAG: ${{ steps.shortsha.outputs.sha_short }} - run: | - echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT - - - name: Fill in the new image ID in the Amazon ECS task definition - id: task-def - uses: aws-actions/amazon-ecs-render-task-definition@c804dfbdd57f713b6c079302a4c01db7017a36fc - with: - task-definition: template_task_def.json - container-name: ${{ env.CONTAINER_NAME }} - image: ${{ steps.write-tag.outputs.image }} - - - name: Deploy Amazon ECS task definition - uses: aws-actions/amazon-ecs-deploy-task-definition@df9643053eda01f169e64a0e60233aacca83799a - with: - task-definition: ${{ steps.task-def.outputs.task-definition }} - service: ${{ env.ECS_SERVICE }} - cluster: ${{ env.ECS_CLUSTER }} - wait-for-service-stability: true + deploy-core: + uses: ./.github/workflows/deploy-template.yml + with: + service-name: core + environment: staging + env-proper-name: blake + secrets: + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + + deploy-jobs: + uses: ./.github/workflows/deploy-template.yml + needs: deploy-core + with: + service-name: jobs + environment: staging + env-proper-name: blake + secrets: + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} diff --git a/.github/workflows/deploy-template.yml b/.github/workflows/deploy-template.yml new file mode 100644 index 000000000..17daa25c8 --- /dev/null +++ b/.github/workflows/deploy-template.yml @@ -0,0 +1,85 @@ +# Based on https://docs.github.com/en/actions/deployment/deploying-to-your-cloud-provider/deploying-to-amazon-elastic-container-service + +name: aws ecs deploy template + +on: + workflow_call: + inputs: + service-name: # example: core + required: true + type: string + env-proper-name: # example: blake + required: true + type: string + environment: # example: staging + required: true + type: string + secrets: + AWS_ACCESS_KEY_ID: + required: true + AWS_SECRET_ACCESS_KEY: + required: true + +env: + AWS_REGION: us-east-1 + ECR_REPOSITORY: pubpub-v7-${{ inputs.service-name }} + ECS_SERVICE: ${{ inputs.env-proper-name }}-${{inputs.service-name}} + ECS_CLUSTER: ${{inputs.env-proper-name}}-ecs-cluster-${{inputs.environment}} + ECS_TASK_DEFINITION_TEMPLATE: ${{ inputs.env-proper-name }}-${{inputs.service-name}} + CONTAINER_NAME: ${{inputs.service-name}} + +jobs: + deploy: + name: Deploy + runs-on: ubuntu-latest + environment: production + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ env.AWS_REGION }} + + - name: Get short sha + id: shortsha + run: echo "sha_short=$(git describe --always --abbrev=40 --dirty)" >> $GITHUB_OUTPUT + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 + + - name: Retrieve Task Definition contents from template + id: get-taskdef + run: | + aws ecs describe-task-definition \ + --task-definition $ECS_TASK_DEFINITION_TEMPLATE \ + --query taskDefinition >> template_task_def.json + + - name: Interpolate image tag + id: write-tag + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + IMAGE_TAG: ${{ steps.shortsha.outputs.sha_short }} + run: | + echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT + + - name: Fill in the new image ID in the Amazon ECS task definition + id: task-def + uses: aws-actions/amazon-ecs-render-task-definition@c804dfbdd57f713b6c079302a4c01db7017a36fc + with: + task-definition: template_task_def.json + container-name: ${{ env.CONTAINER_NAME }} + image: ${{ steps.write-tag.outputs.image }} + + - name: Deploy Amazon ECS task definition + uses: aws-actions/amazon-ecs-deploy-task-definition@df9643053eda01f169e64a0e60233aacca83799a + with: + task-definition: ${{ steps.task-def.outputs.task-definition }} + service: ${{ env.ECS_SERVICE }} + cluster: ${{ env.ECS_CLUSTER }} + wait-for-service-stability: false diff --git a/.github/workflows/ecrbuild-all.yml b/.github/workflows/ecrbuild-all.yml index 5b1b6545e..c281434ee 100644 --- a/.github/workflows/ecrbuild-all.yml +++ b/.github/workflows/ecrbuild-all.yml @@ -23,3 +23,13 @@ jobs: secrets: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + + build-jobs: + uses: ./.github/workflows/ecrbuild-template.yml + with: + target: jobs + package-name: jobs + package-src: jobs + secrets: + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} diff --git a/.github/workflows/ecrbuild-template.yml b/.github/workflows/ecrbuild-template.yml index 271247b56..00d4aa544 100644 --- a/.github/workflows/ecrbuild-template.yml +++ b/.github/workflows/ecrbuild-template.yml @@ -5,6 +5,10 @@ name: aws ecr build template on: workflow_call: inputs: + target: + required: true + default: "main" + type: string package-name: required: true type: string @@ -61,6 +65,7 @@ jobs: --platform linux/amd64 \ --build-arg PACKAGE=$PACKAGE \ --build-arg PACKAGE_DIR=$PACKAGE_DIR \ + --target ${{ inputs.target }} \ -t $ECR_REGISTRY/$ECR_REPOSITORY_PREFIX-$PACKAGE:$IMAGE_TAG \ . docker push $ECR_REGISTRY/$ECR_REPOSITORY_PREFIX-$PACKAGE:$IMAGE_TAG diff --git a/Dockerfile b/Dockerfile index 6a7d0a467..e40203a5f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,6 +9,7 @@ ARG PNPM_VERSION=8.14.3 ARG PACKAGE_DIR=core ARG PACKAGE=core +ARG PORT=3000 ################################################################################ # Use node image for base image for all stages. @@ -64,8 +65,11 @@ RUN ./bin/render-build.sh ${PACKAGE} ################################################################################ # Create a new stage to run the application with minimal runtime dependencies # where the necessary files are copied from the build stage. -FROM base as final -ARG PACKAGE_DIR PACKAGE +FROM base as shared +ARG PACKAGE_DIR PACKAGE PORT + +# needed so that the CMD can use this var +ENV PACKAGE=$PACKAGE # Use production node environment by default. ENV NODE_ENV production @@ -86,11 +90,18 @@ COPY ./${PACKAGE_DIR}/package.json \ COPY --from=deps /usr/src/app/node_modules ./node_modules COPY --from=build /usr/src/app/${PACKAGE_DIR}/node_modules ./${PACKAGE_DIR}/node_modules -COPY --from=build /usr/src/app/${PACKAGE_DIR}/.next ./${PACKAGE_DIR}/.next - # Expose the port that the application listens on. -EXPOSE 3000 - +EXPOSE $PORT # Run the application. CMD pnpm --filter ${PACKAGE} start + +# add an optional target to use for the jobs package only +FROM shared AS jobs +ARG PACKAGE_DIR +COPY --from=build /usr/src/app/${PACKAGE_DIR}/index.ts ./${PACKAGE_DIR}/index.ts + +# But most packages are built in this standard next.js way. +FROM shared AS main +ARG PACKAGE_DIR +COPY --from=build /usr/src/app/${PACKAGE_DIR}/.next ./${PACKAGE_DIR}/.next