๐ 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๋ฅผ ๋ฌด๋ฃ ํ๋ ๋ด์์ ์ผ๋ฌด์ง๊ฒ ์ฌ์ฉํ ์์ ์ ๋๋ค.
๋๊ธ