๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Server

github-action์—์„œ Docker์™€ SSH๋กœ Nextjs ์›๊ฒฉ ๋ฐฐํฌํ•˜๊ธฐ

by LasBe 2024. 10. 18.
๋ฐ˜์‘ํ˜•

๐Ÿ“’ github-action์—์„œ Docker์™€ SSH๋กœ Nextjs ์›๊ฒฉ ๋ฐฐํฌํ•˜๊ธฐ


์ด์ „ ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ๋ฅผ ๋ฐฐํฌํ–ˆ๋˜ ์ž์ทจ๋ฐฉ ๊ณ ๋ฌผ ๋…ธํŠธ๋ถ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค.

 

๋ณด์•ˆ๋„ ํ—ˆ์ˆ ํ•˜๊ฒŒ ์„ค์ •ํ•ด๋†“๊ณ  ํ•˜์—ผ์—†์ด ๋ฐฉ์น˜ํ•˜๋‹ค ๋ณด๋‹ˆ ์–ด๋Š ์ˆœ๊ฐ„ ์šฐ๋ถ„ํˆฌ๊ฐ€ ๋จนํ†ต์ด ๋˜์–ด ์ด๋ฒˆ์— ํฌ๋งทํ•˜๊ณ  ์ƒˆ๋กœ ์„ค์น˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์ด๋ฒˆ์—” ํฌํŠธํด๋ฆฌ์˜ค ์šฉ๋„๋กœ ๋งŒ๋“  Nextjs ์›น์‚ฌ์ดํŠธ๋ฅผ ๋ฐฐํฌํ•˜๋ ค ํ•˜๋Š”๋ฐ,

์ „์— github self hosted runner๋ฅผ ์„œ๋ฒ„์— ์ง์ ‘ ์„ค์น˜ํ•ด ์‚ฌ์šฉํ•˜๋˜ ๋ฐฉ์‹์ด ๋„ˆ๋ฌด ๋ถˆํŽธํ–ˆ๋˜ ๊ฒƒ์„ ๋– ์˜ฌ๋ ธ์Šต๋‹ˆ๋‹ค.

 

์ƒ๊ฐํ•ด๋ณด๋‹ˆ ๊นƒํ—ˆ๋ธŒ์—์„œ ๋ฌด๋ฃŒ๋กœ github hosted runner๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ๊ณ ,

์ด๊ฑธ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ด์šฉํ•ด ๋ณด์ž๋Š” ์ƒ๊ฐ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

github hosted runner์—์„œ ์•ฑ ๋นŒ๋“œ
-> docker ๋นŒ๋“œ
-> docker hub์— ์ด๋ฏธ์ง€ push

-> ssh๋กœ ๋ฐฐํฌํ•  ์„œ๋ฒ„์— ์˜ฌ๋ฆฐ ์ด๋ฏธ์ง€ ๋ฐ›๊ณ  ์ปจํ…Œ์ด๋„ˆ ์˜ฌ๋ฆฌ๋Š” ๋ช…๋ น์–ด ์ „์†ก

-> ๋ฐฐํฌ ๋

 

์ด๋Ÿฐ ํ๋ฆ„์ด๋ฉด docker repo ๋•์— ๋นŒ๋“œํ•˜๋Š” ์„œ๋ฒ„์™€ ๋ฐฐํฌํ•˜๋Š” ์„œ๋ฒ„ ๊ฐ„ ์˜์กด์„ฑ์ด ์—†์–ด์ ธ ์„œ๋ฒ„ ๊ด€๋ฆฌ๊ฐ€ ๋„ˆ๋ฌด๋‚˜ ํŽธ๋ฆฌํ•ด์ง‘๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿผ ์ œ๊ฐ€ ์งœ๋ณธ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์†Œ๊ฐœ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

 

๐Ÿ“Œ Dockerfile

FROM node:22-alpine AS base

FROM base AS deps
  RUN apk add --no-cache libc6-compat
  WORKDIR /app

  COPY package.json pnpm-lock.yaml ./
  RUN corepack enable pnpm 
  RUN pnpm i --frozen-lockfile

FROM base AS builder
  WORKDIR /app
  COPY --from=deps /app/node_modules ./node_modules
  COPY . .

  ARG FIREBASE_KEY
  ARG FIREBASE_PROJECT
  ARG FIREBASE_MESSAGING
  ARG FIREBASE_APP_ID
  ARG FIREBASE_MEASUREMENT_ID

  RUN echo "NEXT_PUBLIC_FIREBASE_KEY=$FIREBASE_KEY" >> .env \
    && echo "NEXT_PUBLIC_FIREBASE_PROJECT=$FIREBASE_PROJECT" >> .env \
    && echo "NEXT_PUBLIC_FIREBASE_MESSAGING=$FIREBASE_MESSAGING" >> .env \
    && echo "NEXT_PUBLIC_FIREBASE_APP_ID=$FIREBASE_APP_ID" >> .env \
    && echo "NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=$FIREBASE_MEASUREMENT_ID" >> .env
    
  RUN corepack enable pnpm
  RUN pnpm run build

FROM base AS runner
  WORKDIR /app

  ENV NODE_ENV=production

  RUN addgroup --system --gid 1001 nodejs
  RUN adduser --system --uid 1001 nextjs

  COPY --from=builder /app/public ./public

  RUN mkdir .next
  RUN chown nextjs:nodejs .next

  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

  ENV HOSTNAME="0.0.0.0"
  CMD ["node", "server.js"]

๋„์ปค ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•  ๋•Œ ์‹คํ–‰๋˜๋Š” ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ์„œ๋Š” node ์ด๋ฏธ์ง€๋ฅผ ์ด์šฉํ•ด pnpm์œผ๋กœ ์•ฑ์„ ๋นŒ๋“œํ•˜๊ณ  ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•ด ์ฃผ๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์‚ฌ์‹ค ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•  ๋•Œ ๋ฏผ๊ฐํ•œ ํ‚ค ์ •๋ณด๊ฐ€ ํฌํ•จ๋˜๋ฉด ์ด๋ฏธ์ง€๋ฅผ ๊นŒ๋ดค์„ ๋•Œ ์ฃ„๋‹ค ๋…ธ์ถœ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์•ˆ๋˜์ง€๋งŒ,

์„œ๋ฒ„์— ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์˜ฌ๋ฆฐ ํ›„, exec ๋ช…๋ น์–ด๋กœ env ํŒŒ์ผ์„ ์ถ”๊ฐ€ ํ•ด๋„ ์ธ์‹์ด ๋˜์ง€ ์•Š์•„ ๋ณ„ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

 

์ด ๊ธ€์„ ๋ณด์‹ ๋‹ค๋ฉด github repo์™€ docker hub๊ฐ€ public์ผ ๋•Œ ๋ฏผ๊ฐํ•œ ํ‚ค ์ •๋ณด๋Š” ์ถ”๊ฐ€ํ•˜์ง€ ๋งˆ์‹œ๊ธธ ๋‹น๋ถ€๋“œ๋ฆฝ๋‹ˆ๋‹ค.

 

Nextjs Dockerfile์€ ๊ณต์‹ ์˜ˆ์ œ๋ฅผ ์กฐ๊ธˆ ์ˆ˜์ •ํ–ˆ์œผ๋‹ˆ ํ•„์š”ํ•˜์‹œ๋ฉด ๋‹ค์Œ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”.

https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile

 

๐Ÿ“Œ .github/workflows/deploy.yml

name: deploy

on:
  push:
    branches: [main]

jobs:
  app-build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login docker hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_TOKEN }}

      - name: Build and Push Docker Image
        uses: docker/build-push-action@v6
        with:
          push: true
          tags: ${{ secrets.DOCKER_USERNAME }}/${{secrets.DOCKER_IMAGENAME}}:${{github.run_id}}
          build-args: |
            FIREBASE_KEY=${{secrets.FIREBASE_KEY}}
            FIREBASE_PROJECT=${{secrets.FIREBASE_PROJECT}}
            FIREBASE_MESSAGING=${{secrets.FIREBASE_MESSAGING}}
            FIREBASE_APP_ID=${{secrets.FIREBASE_APP_ID}}
            FIREBASE_MEASUREMENT_ID=${{secrets.FIREBASE_MEASUREMENT_ID}}

      - name: execute remote ssh
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_IP }}
          username: ${{ secrets.SERVER_USERNAME }}
          key: ${{ secrets.SERVER_SSH_KEY }}
          port: ${{ secrets.SERVER_SSH_PORT }}
          script: |
            docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_TOKEN }}
            docker pull ${{ secrets.DOCKER_USERNAME }}/${{secrets.DOCKER_IMAGENAME}}:${{github.run_id}}
            docker stop ${{secrets.DOCKER_IMAGENAME}} || true
            docker rm ${{secrets.DOCKER_IMAGENAME}} || true
            docker run -d --restart=always --name ${{secrets.DOCKER_IMAGENAME}} -p 3000:3000 ${{ secrets.DOCKER_USERNAME }}/${{secrets.DOCKER_IMAGENAME}}:${{github.run_id}}

์ „ ํšŒ์‚ฌ์—์„œ ๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ ์งค ๋•Œ๋Š” gitlab ci๋ฅผ ์‚ฌ์šฉํ•ด ๋ชจ๋“  ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ „๋ถ€ ์ˆ˜์ž‘์—…์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ–ˆ๋Š”๋ฐ,

github-action์€ ์ด๋Ÿฐ ๋ฐฐํฌ ๋ชจ๋“ˆ ์ƒํƒœ๊ณ„๊ฐ€ ๋„ˆ๋ฌด ์ž˜ ์งœ์—ฌ์žˆ์–ด ์‚ฌ์šฉํ•  ๋•Œ๋งˆ๋‹ค ๋„ˆ๋ฌด๋‚˜ ํŽธ๋ฆฌํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

์ œ๊ฐ€ ์‚ฌ์šฉํ•œ ๋ชจ๋“ˆ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • actions/checkout@v3
    github ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์˜ ์ฝ”๋“œ๋ฅผ ์ฒดํฌ์•„์›ƒ
  • docker/setup-buildx-action@v3
    docker์˜ ๋ฉ€ํ‹ฐ ์•„ํ‚คํ…์ฒ˜ ๋นŒ๋“œ๋ฅผ ์ง€์›ํ•˜๋Š” Buildx๋ฅผ ์„ค์ •
  • docker/login-action@v3
    docker Hub์— ๋กœ๊ทธ์ธ
  • docker/build-push-action@v6
    docker ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ํ‘ธ์‹œ
  • appleboy/ssh-action@master
    SSH๋กœ ์›๊ฒฉ ์„œ๋ฒ„์— ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰
    ๋„์ปค ๋กœ๊ทธ์ธ -> ์ด๋ฏธ์ง€ pull -> ๊ธฐ์กด ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ฆผ -> ์ƒˆ ์ด๋ฏธ์ง€ ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰

๋„์ปค ํŒŒ์ผ์˜ ๋ณ€์ˆ˜๋Š” docker/build-push-action์˜ build-args๋กœ ๋„˜๊ฒจ์ฃผ์—ˆ๊ณ ,

appleboy/ssh-action์„ ์ด์šฉํ•ด ์„œ๋ฒ„์— ํ‚ค ๋ฐฉ์‹์œผ๋กœ ssh ๋ช…๋ น์–ด๋ฅผ ๋‚ ๋ ค์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

 

ํ”„๋กœ์ ํŠธ๊ฐ€ ์ž˜ ๋ฐฐํฌ๋˜์—ˆ์œผ๋‹ˆ ๊ณ„์†ํ•ด์„œ github hosted runner๋ฅผ ๋ฌด๋ฃŒ ํ•œ๋„ ๋‚ด์—์„œ ์•ผ๋ฌด์ง€๊ฒŒ ์‚ฌ์šฉํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€


์˜คํ”ˆ ์ฑ„ํŒ