diff --git a/.github/workflows/cr.yml b/.github/workflows/cr.yml index 240d330..c9aef2e 100644 --- a/.github/workflows/cr.yml +++ b/.github/workflows/cr.yml @@ -7,8 +7,8 @@ permissions: on: pull_request: types: [opened, synchronize] - -jobs: + workflow_dispatch: +jobs: test: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..1d6dcab --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,88 @@ +name: Deploy NextJs To ECR + +on: + pull_request: + branches: ['develop'] + workflow_dispatch: + +jobs: + deploy: + env: + AWS_REGION: ap-northeast-2 + ECR_REPOSITORY: devs-nextjs + ECS_SERVICE: devs-nextjs-service + ECS_CLUSTER: devs-nextjs-cluster + ECS_TASK_DEFINITION: ./devs-nextjs-task.json + CONTAINER_NAME: nextjs + + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: '20' + cache: 'npm' + + - name: Restore cache + uses: actions/cache@v4 + with: + path: | + .next/cache + key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }} + restore-keys: | + ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}- + + - name: Install dependencies + run: npm ci + + - name: Build with Next.js + env: + NEXT_PUBLIC_API_SERVER_URL: https://api.dev-study.com + run: npm run build + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.ECR_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.ECR_SECRET_ACCESS_KEY }} + aws-region: ${{ env.AWS_REGION }} + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + + - name: Build and Push Image to Amazon ECR + uses: docker/build-push-action@v3 + id: build-and-push + env: + ECR: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }} + with: + context: . + push: true + provenance: false + tags: ${{ env.ECR }}:${{ github.sha }} + platforms: linux/arm64 + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Fill in the new image ID in the Amazon ECS task definition + id: task-def + uses: aws-actions/amazon-ecs-render-task-definition@v1 + with: + task-definition: ${{ env.ECS_TASK_DEFINITION }} + container-name: ${{ env.CONTAINER_NAME }} + image: ${{ fromJSON(steps.build-and-push.outputs.metadata)['image.name'] }} + + - name: Deploy Amazon ECS task definition + uses: aws-actions/amazon-ecs-deploy-task-definition@v1 + with: + task-definition: ${{ steps.task-def.outputs.task-definition }} + service: ${{ env.ECS_SERVICE }} + cluster: ${{ env.ECS_CLUSTER }} + wait-for-service-stability: true diff --git a/.github/workflows/next.yml b/.github/workflows/next.yml index b743427..c76ce11 100644 --- a/.github/workflows/next.yml +++ b/.github/workflows/next.yml @@ -1,10 +1,9 @@ name: Check NextJs build on: - push: - branches: ['develop'] pull_request: branches: ['develop'] + workflow_dispatch: jobs: build: @@ -12,20 +11,24 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Setup Node uses: actions/setup-node@v3 with: node-version: '20' cache: 'npm' + - name: Restore cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | .next/cache key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }} restore-keys: | ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}- + - name: Install dependencies run: npm ci - - name: Build with Next.js - run: npm run build + + - name: Lint And Build with Next.js + run: npm run lint && npm run build diff --git a/Dockerfile b/Dockerfile index 277d487..e2c8f76 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,23 +1,8 @@ -FROM node:20-alpine AS base +FROM node:20-alpine -FROM base AS deps -RUN apk add --no-cache libc6-compat -WORKDIR /app - -# Install dependencies based on the preferred package manager -COPY package.json package-lock.json ./ -RUN npm ci - -FROM base AS builder -WORKDIR /app -COPY --from=deps /app/node_modules ./node_modules -COPY . . -ENV NEXT_PUBLIC_API_SERVER_URL https://www.dev-study.com -RUN npm run build - -FROM base AS runner WORKDIR /app +ENV PORT 3000 ENV NODE_ENV production # Uncomment the following line in case you want to disable telemetry during runtime. # ENV NEXT_TELEMETRY_DISABLED 1 @@ -25,22 +10,20 @@ ENV NODE_ENV production 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 +USER nextjs +EXPOSE 3000 + +COPY ./public ./public # 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 +COPY --chown=nextjs:nodejs ./.next/static ./.next/static -USER nextjs +COPY --chown=nextjs:nodejs ./.next/standalone ./ -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 diff --git a/devs-nextjs-task.json b/devs-nextjs-task.json new file mode 100644 index 0000000..fadd452 --- /dev/null +++ b/devs-nextjs-task.json @@ -0,0 +1,97 @@ +{ + "taskDefinitionArn": "arn:aws:ecs:ap-northeast-2:381492172680:task-definition/devs-nextjs-task:1", + "containerDefinitions": [ + { + "name": "nextjs", + "image": "381492172680.dkr.ecr.ap-northeast-2.amazonaws.com/devs-nextjs", + "cpu": 0, + "portMappings": [ + { + "name": "nextjs-3000-tcp", + "containerPort": 3000, + "hostPort": 3000, + "protocol": "tcp", + "appProtocol": "http" + } + ], + "essential": true, + "environment": [], + "environmentFiles": [ + { + "value": "arn:aws:s3:::devs-env-bucket/nextjs.env", + "type": "s3" + } + ], + "mountPoints": [], + "volumesFrom": [], + "ulimits": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-group": "/ecs/devs-nextjs-task", + "awslogs-create-group": "true", + "awslogs-region": "ap-northeast-2", + "awslogs-stream-prefix": "ecs" + }, + "secretOptions": [] + }, + "systemControls": [] + } + ], + "family": "devs-nextjs-task", + "taskRoleArn": "arn:aws:iam::381492172680:role/ecsTaskExecutionRole", + "executionRoleArn": "arn:aws:iam::381492172680:role/ecsTaskExecutionRole", + "networkMode": "awsvpc", + "revision": 1, + "volumes": [], + "status": "ACTIVE", + "requiresAttributes": [ + { + "name": "com.amazonaws.ecs.capability.logging-driver.awslogs" + }, + { + "name": "ecs.capability.execution-role-awslogs" + }, + { + "name": "com.amazonaws.ecs.capability.ecr-auth" + }, + { + "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19" + }, + { + "name": "ecs.capability.env-files.s3" + }, + { + "name": "com.amazonaws.ecs.capability.task-iam-role" + }, + { + "name": "ecs.capability.execution-role-ecr-pull" + }, + { + "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18" + }, + { + "name": "ecs.capability.task-eni" + }, + { + "name": "com.amazonaws.ecs.capability.docker-remote-api.1.29" + } + ], + "placementConstraints": [], + "compatibilities": [ + "EC2", + "FARGATE" + ], + "requiresCompatibilities": [ + "FARGATE" + ], + "cpu": "1024", + "memory": "3072", + "runtimePlatform": { + "cpuArchitecture": "ARM64", + "operatingSystemFamily": "LINUX" + }, + "registeredAt": "2024-08-09T05:07:02.807Z", + "registeredBy": "arn:aws:iam::381492172680:root", + "tags": [] +} \ No newline at end of file diff --git a/next.config.mjs b/next.config.mjs index 9fbab95..53be71d 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,6 +1,12 @@ /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: false, + eslint: { + ignoreDuringBuilds: true + }, + generateBuildId: async () => { + return 'i5JCtxqrbVzVm8aWDr3K2'; + }, swcMinify: true, async rewrites() { return [