728x90
반응형

회사마다 다르겠지만, 본인은 아래와 같은 방법으로 생각을 해봤다.

  1. 이슈 등록
  2. 작업 후 PR 등록 ( 빌드 / 테스트 자동화, 라벨링 자동화 )
  3. Main에 Merge
  4. 적절한 시기에 release/0.0.1 같은 브랜치 생성
  5. release 브랜치에 main 병합 ( 릴리즈 자동화로 버전 관리)
  6. 적절한 시기에 배포 ( 배포 자동화 )

 

다른 자동화 workflow는 이미 이전 포스트에 등록을 했으니, 이번엔 릴리즈 자동화를 하고자 한다.

아래는 이번 포스트에 쓰일 Release Drafter action이다.

 

Release Drafter · Actions · GitHub Marketplace

 

Release Drafter - GitHub Marketplace

Drafts your next release notes as pull requests are merged into master

github.com

 

1. /.github/workflows/release_drafter.yml 생성

name: Auto Labeling

on:
  pull_request:
    branches:
      - main

permissions:
  contents: write
  pull-requests: write
  packages: write

jobs:
  update_release_draft:
    runs-on: self-hosted
    steps:
      - uses: release-drafter/release-drafter@v6
        with:
          config-name: release_drafter_config.yml
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

 

2. /.github/release_drafter_config.yml 생성

name-template: 'v$RESOLVED_VERSION 🌈'
tag-template: 'v$RESOLVED_VERSION'
categories:
  - title: '🚀 Features'
    labels:
      - 'feature'
      - 'enhancement'
  - title: '🐛 Bug Fixes'
    labels:
      - 'fix'
      - 'bugfix'
      - 'bug'
  - title: '🧰 Maintenance'
    label: 'chore'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
version-resolver:
  major:
    labels:
      - 'major'
  minor:
    labels:
      - 'minor'
  patch:
    labels:
      - 'patch'
  default: patch
template: |
  ## Changes

  $CHANGES

 

참고로 config 파일은 해당 브랜치에 병합이 되어야 인식할 수 있다.

자세한 설명은 위 사이트에서 확인 가능하다.

728x90
반응형
728x90
반응형

workflow를 사용하는 방법은 매우 간단하다

프로젝트/.github/workflows/ 경로 아래에 yml 파일을 만들면 인식해서 실행시켜준다.

 

1. /.github/workflows/auto_labeling.yml 생성

name: Auto Labeling

on:
  pull_request:
    types: [ opened, reopened, synchronize ]

permissions:
  contents: write
  pull-requests: write
  packages: write

jobs:
  update_release_draft:
    runs-on: self-hosted
    steps:
      - uses: release-drafter/release-drafter@v6
        with:
          commitish: main
          config-name: auto_labeling_config.yml
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

 

pull_request가 실행 될 때마다 작동하게 설계했으며, config 파일의 경로는 .github/ 이어야 한다.

권한 또한 중요하니 잊지 않도록 한다.

 

runs-on은 환경에 맞는 코드를 쓰면 된다.

 

2. /.github/auto_labeling_config.yml 작성

template: |
  ## What’s Changed

  $CHANGES
autolabeler:
  - label: 'Component: Client'
    files:
      - 'client/**'
  - label: 'Type: Bug'
    title:
      - '/^fix(\([a-zA-Z][a-zA-Z]\))?:/i'

template 은 필수 코드 이므로 추가하고, 경로와 PR title을 사용한 규칙을 지정하도록 한다.

사실상 template은 해당 작업에서 사용되진 않으며, 릴리즈 자동화에서 쓰일 예정이다.

title의 정규 표현식은 원하는대로 바꿀 수도 있다.

728x90
반응형
728x90
반응형

Pull Request를 올릴 때 자동으로 Label을 달아주는 workflow를 만들어보자.

 

먼저 .github/workflows에 workflow를 만들어준다.

name: Auto Labeling

on:
  pull_request:
    types: [ opened, reopened, synchronize ]

permissions:
  contents: write
  pull-requests: write
  packages: write

jobs:
  update_release_draft:
    runs-on: self-hosted
    steps:
      - uses: release-drafter/release-drafter@v6
        with:
          commitish: main
          config-name: auto_labeling.yml
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

 

그 다음 config 파일인 auto_labeling.yml 파일을 .github/ 경로에 만들어준다.

config 파일은 main 브랜치에 병합이 된 후 인식이 가능하니 알아두도록 하자.

 

template: |
  ## What’s Changed

  $CHANGES
autolabeler:
  - label: 'Component: Client'
    files:
      - 'client/**'
  - label: 'Component: DB'
    files:
      - 'docker/postgres/**'
  - label: 'Component: Server'
    files:
      - 'server/**'
  - label: 'Type: Bug'
    title:
      - '/^fix(\([a-zA-Z][a-zA-Z]\))?:/i'
  - label: 'Type: Build/CI/CD'
    title:
      - '/^build(\([a-zA-Z][a-zA-Z]\))?:/i'
      - '/^ci(\([a-zA-Z][a-zA-Z]\))?:/i'
      - '/^cd(\([a-zA-Z][a-zA-Z]\))?:/i'
  - label: 'Type: Change'
    title:
      - '/^change(\([a-zA-Z][a-zA-Z]\))?:/i'
  - label: 'Type: Chore'
    title:
      - '/^chore(\([a-zA-Z][a-zA-Z]\))?:/i'
  - label: 'Type: Documentation'
    title:
      - '/^docs(\([a-zA-Z][a-zA-Z]\))?:/i'
  - label: 'Type: Feature'
    title:
      - '/^feat(\([a-zA-Z][a-zA-Z]\))?:/i'
  - label: 'Type: Style'
    title:
      - '/^style(\([a-zA-Z][a-zA-Z]\))?:/i'
  - label: 'Type: Test'
    title:
      - '/^test(\([a-zA-Z][a-zA-Z]\))?:/i'
728x90
반응형
728x90
반응형

 

1. 액세스 토큰 생성

Personal Access Tokens (Classic) (github.com)  에서 패키지에 대한 권한을 가진 토큰을 생성한다.

생성되는 토큰 값을 저장한 뒤 원하는 곳에 txt 파일로 만들어두고, 아래 명령어 중 하나로 로그인 가능하다.

$ docker login https://ghcr.io -u outsideris // 입력 후 패스워드 토큰값 입력
$ cat TOKEN.txt | docker login https://ghcr.io -u outsideris --password-stdin

 

2. self_host runner를 만들고 등록해준다.

About self-hosted runners - GitHub Docs

 

About self-hosted runners - GitHub Docs

You can host your own runners and customize the environment used to run jobs in your GitHub Actions workflows.

docs.github.com

 

3. workflow를 만들어준다.

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle

name: Workflow

permissions:
  contents: read
  packages: write
  checks: write

# 어떤 이벤트가 발생하면 workflow 실행할 지 명시
on:
  # main 브랜치에 pull_request 발생 시
  pull_request:
    branches:
      - main


# 위 이벤트 발생 시 실행될 작업들
jobs:
  # 빌드 후 Container Registry에 image 등록
  push_to_registry:
    # VM의실행 환경 지정 => self-hosted
    runs-on: self-hosted

    # 실행될 jobs 순서 대로 명시
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Postgres Start
        env:
          ENV_FILE: ${{ secrets.ENV_FILE }}
        run: echo "$ENV_FILE" > ./.env &&
          docker image prune &&
          docker rm -f $(docker ps -qa) &&
          docker compose up db -d

      # JDK 17 설치
      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'

      # Gradle Build를 위한 권한 부여
      - name: Grant execute permission for gradlew
        run: chmod +x ./gradlew

      # Gradle Build
      - name: Build with Gradle
        run: ./gradlew clean build

      # 테스트 결과를 PR에 코멘트로 달아줌
      - name: Publish test result
        uses: EnricoMi/publish-unit-test-result-action@v2.15.1
        if: always()
        with:
          files: '**/build/test-results/test/*.xml'

      # 테스트 실패 시 해당 코드 라인에 코멘트 달아줌.
      - name: When test fail, a comment is registered in the error code line.
        uses: mikepenz/action-junit-report@v4.1.0
        if: always()
        with:
          report_paths: '**/build/test-results/test/*.xml'

      # GitHub Container Registry 로그인
      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ secrets.GHUB_USERNAME }}
          password: ${{ secrets.GHUB_TOKEN }}

      # Docker image 빌드 및 push
      - name: Server Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ./server/Dockerfile.prod
          push: true
          tags: ghcr.io/${{ secrets.GHUB_USERNAME }}/server:${{ secrets.RELEASE_VERSION }}

      - name: Client Build and push
        uses: docker/build-push-action@v5
        with:
          context: ./client
          file: ./client/Dockerfile.prod
          push: true
          tags: ghcr.io/${{ secrets.GHUB_USERNAME }}/client:${{ secrets.RELEASE_VERSION }}

      - name: Nginx Build and push
        uses: docker/build-push-action@v5
        with:
          context: ./docker/nginx
          push: true
          build-args: BUILD_ENV=prod
          tags: ghcr.io/${{ secrets.GHUB_USERNAME }}/nginx:${{ secrets.RELEASE_VERSION }}

      - name: DB Build and push
        uses: docker/build-push-action@v5
        with:
          context: ./docker/postgres
          push: true
          tags: ghcr.io/${{ secrets.GHUB_USERNAME }}/db:${{ secrets.RELEASE_VERSION }}

  # 서버에 배포
  deploy_via_ssh:
    needs: push_to_registry
    runs-on: self-hosted

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      # Env 추가
      - name: Add Env
        env:
          ENV_FILE: ${{ secrets.ENV_FILE }}
          GHUB_USERNAME: ${{ secrets.GHUB_USERNAME }}
          RELEASE_VERSION: ${{ secrets.RELEASE_VERSION }}
        run: echo "$ENV_FILE" > ./.env &&
          echo -e "GHUB_USERNAME=$GHUB_USERNAME \nRELEASE_VERSION=$RELEASE_VERSION" >> ./.env

      # .env, docker-compose.prod.yml 파일 scp로 서버에 전송
      - name: copy files to target server via scp
        uses: appleboy/scp-action@v0.1.7
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          username: ${{ secrets.DEPLOY_USERNAME }}
          key: ${{ secrets.DEPLOY_KEY }}
          port: ${{ secrets.DEPLOY_PORT }}
          source: ./docker-compose.prod.yml, ./.env
          target: /home

      #  원격으로 docker compose up 실행
      - name: remote docker-compose up via ssh
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          username: ${{ secrets.DEPLOY_USERNAME }}
          key: ${{ secrets.DEPLOY_KEY }}
          port: ${{ secrets.DEPLOY_PORT }}
          envs: APPTOKEN,USERNAME
          script: |
            echo ${{ secrets.GHUB_TOKEN }} | sudo docker login ghcr.io --username ${{ secrets.GHUB_USERNAME }} --password-stdin &&
            cd /home &&
            sudo docker pull ghcr.io/${{ secrets.GHUB_USERNAME }}/server:${{ secrets.RELEASE_VERSION }} &&
            sudo docker pull ghcr.io/${{ secrets.GHUB_USERNAME }}/client:${{ secrets.RELEASE_VERSION }} &&
            sudo docker pull ghcr.io/${{ secrets.GHUB_USERNAME }}/db:${{ secrets.RELEASE_VERSION }} &&
            sudo docker pull ghcr.io/${{ secrets.GHUB_USERNAME }}/nginx:${{ secrets.RELEASE_VERSION }}

 

 

4. Dockefile

ghcr(컨테이너 레지스트리)에서 image를 pull 하므로 배포용 Docker 파일을 다음과같이 바꿔야 한다.

    app:
        image: ghcr.io/${IMAGE_REPO}:${RELEASE_VERSION}

 

5. secrets

github repository -> Settings -> Secrets and variables에서 secrets 항목들을 추가해준다.

참고로 github username은 반드시 소문자로 해야된다.


self-hosted 로 사용할 경우 서버의 사용자에 Docker 권한을 부여해주어야 한다.

 

How to fix docker: Got permission denied issue - Stack Overflow

 

How to fix docker: Got permission denied issue

I installed Docker in my machine where I have Ubuntu OS. When I run: sudo docker run hello-world All is ok, but I want to hide the sudo command to make the command shorter. If I write the command

stackoverflow.com

 

 

참고

GitHub Action Docker Compose deployments via SSH (servicestack.net)

 

728x90
반응형
728x90
반응형

1. 프로세스는 다음과 같다.

  1. Git Repository에 push 또는 merge
  2. Github Actions에서 이를 감지하고 빌드 및 테스트 실행
  3. 테스트까지 실행될 경우 Docker 이미지로 빌드
  4. 빌드된 이미지를 Dockerhub에 업로드
  5. EC2 Instance에 ssh로 접속 후 이미지를 pull

2. 파이프라인 구축

1. Github에 Repository를 만들고 프로젝트를 업로드한다.

2. Dockerfile을 만들어준다.

3. Github에 들어가 Actions에서 Java with Gradle configure버튼을 클릭한다.

4. 원하는 yml 파일 이름을 작성하고 아래 코드를 붙여넣는다.

 

# Workflow 이름
name: Spring Boot & Gradle CI/CD

# 어떤 이벤트가 발생하면 workflow 실행할 지 명시
on:
  # main 브랜치에 push나 pull request 발생 시
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]
    
permissions:
  contents: write
  
# 위 이벤트 발생 시 실행될 작업들
jobs:
  build:
    # VM의실행 환경 지정 => 우분투 최신 버전
    runs-on: ubuntu-latest
    
    # working directory
    defaults:
    	run:
        	working-directory: ./backend

    # 실행될 jobs를 순서대로 명시
    steps:
    - name: Checkout
      uses: actions/checkout@v3

    # JDK 11 설치
    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'

    # Gradle Build를 위한 권한 부여
    - name: Grant execute permission for gradlew
      run: chmod +x gradlew

    # Gradle Build (test 제외)
    - name: Build with Gradle
      run: ./gradlew clean build --exclude-task test
      
    # 테스트 결과를 코멘트로 달아줌
    - name: Publish test result
      uses: EnricoMi/publish-unit-test-result-action@v1
      if: always()
      with:
        files: 'build/test-results/test/*.xml'
        
	# 테스트 실패 시 해당 부분에 코멘트 달아줌.
    - name: When test fail, a comment is registered in the error code line.
      uses: mikepenz/action-junit-report@v3
      if: always()
      with:
        report_paths: 'build/test-results/test/*.xml'

    # DockerHub 로그인
    - name: DockerHub Login
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_PASSWORD }}

    # Docker 이미지 빌드
    - name: Docker Image Build
      run: docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.PROJECT_NAME }} .

    # DockerHub Push
    - name: DockerHub Push
      run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.PROJECT_NAME }}

    # EC2 인스턴스 접속 및 애플리케이션 실행
    - name: Application Run
      uses: appleboy/ssh-action@v0.1.6
      with:
        host: ${{ secrets.EC2_HOST }}
        username: ${{ secrets.EC2_USERNAME }}
        key: ${{ secrets.EC2_KEY }}

        script: |
          sudo docker kill ${{ secrets.PROJECT_NAME }}
          sudo docker rm -f ${{ secrets.PROJECT_NAME }}
          sudo docker rmi ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.PROJECT_NAME }}
          sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.PROJECT_NAME }}

          sudo docker run -p ${{ secrets.PORT }}:${{ secrets.PORT }} \
          --name ${{ secrets.PROJECT_NAME }} \
          -e SPRING_DATASOURCE_URL=${{ secrets.DB_URL }} \
          -e SPRING_DATASOURCE_USERNAME=${{ secrets.DB_USERNAME }} \
          -e SPRING_DATASOURCE_PASSWORD=${{ secrets.DB_PASSWORD }} \
          -d ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.PROJECT_NAME }}
  • ${{}} 변수는 환경변수이다.
  • 완성되면 .github/workflows 경로에 yml 파일이 추가된다.
  • 수정하고 싶으면 이 파일을 수정하고, 다른 workflow 파일을 작성해도 된다.
  • 만약 안된다면 Github Settings -> Developer Settings -> Personal access tokens에서 생성한 토큰에 들어가 workflow를 체크해주면 된다.

5. Settings -> Secrets and variables -> Actions 에서 환경변수 추가

  • DOCKERHUB_USERNAME : 본인의 Docker Hub Username
  • DOCKERHUB_PASSWORD : 본인의 Docker Hub Password
  • PROJECT_NAME : 프로젝트 이름 (ci-cd-practice) => 이 이름으로 Docker Hub에 올라가게 되고, Docker Container 이름도 이 이름으로 설정할 예정
  • PORT : Docker을 실행시킬 포트 번호 (ex: 8080)
  • DB_URL : 프로젝트에 사용될 DB의 URL (ex:  jdbc:mysql://RDS주소:DB포트/DB명)
  • DB_USERNAME : 프로젝트에 사용될 DB의 Username (ex: root)
  • DB_PASSWORD : 프로젝트에 사용될 DB의 Password
  • EC2_HOST : AWS EC2 인스턴스의 퍼블릭 IPv4 DNS (ex: ec2-52-79-213-143.ap-northeast-2.compute.amazonaws.com)
  • EC2_USERNAME : AWS EC2 인스턴스의 Username (ex: ubuntu)
  • EC2_KEY : AWS EC2 인스턴스를 생성할 때 저장된 pem 키
    • MAC을 기준으로 터미널에서 cat <pem 키 경로>를 입력하면 (드래그앤 드롭해도 됨) '-----BEGIN RSA PRIVATE KEY-----'부터 '-----END RSA PRIVATE KEY-----'까지(맨 뒤에 %빼고)를 복사해서 이 값으로 넣어주면 됨

 

6. workflow를 실행해준다.

 

3. 테스트 실패 시 Merge 막기

Repository Settings  Branches  Add rule 을 선택한다.

 

Branch name pattern을 설정하고,
Require status checks to pass before merging 설정을 통해 merge를 위해 통과해야할 Action들을 선택할 수 있다.

설정 후에 다음과 같이 merge를 못하도록 막혀져있는 것을 확인할 수 있다.
(지금은 admin 이라 강제로 merge할 수 있게 merge 버튼이 활성화돼있지만, admin이 아닌 경우 merge 버튼이 비활성화 된다)

 

참고

[CI/CD] Github Actions를 활용한 CI/CD 파이프라인 구축 (+ Docker hub) (tistory.com)

 

 

728x90
반응형
728x90
반응형
FROM node:17-alpine as staged

WORKDIR /opt/app

COPY ["package.json", "package-lock.json", "./"]
RUN ["npm", "install"]

COPY ["tsconfig.build.json", "tsconfig.json", "./"]
COPY ["src/", "./src/"]
RUN ["npm", "run", "build"]

RUN ["/bin/sh", "-c", "find . ! -name dist ! -name node_modules -maxdepth 1 -mindepth 1 -exec rm -rf {} \\\\;"]

FROM node:17-alpine as completed
WORKDIR /opt/app
COPY --from=staged /opt/app ./
ENTRYPOINT ["node", "dist/src/main"]
EXPOSE 8080/tcp
728x90
반응형
728x90
반응형
FROM gradle:8-jdk17-alpine as builder
WORKDIR /build

# 그래들 파일이 변경되었을 때만 새롭게 의존패키지 다운로드 받게함.
COPY build.gradle settings.gradle /build/
RUN gradle build -x test --parallel --continue > /dev/null 2>&1 || true

# 빌더 이미지에서 애플리케이션 빌드
COPY . /build
RUN gradle build -x test --parallel

# APP
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app

# 빌더 이미지에서 jar 파일만 복사
COPY --from=builder /build/build/libs/my-app-*-SNAPSHOT.jar .

EXPOSE 8080

CMD java -jar ./my-app-*-SNAPSHOT.jar

이렇게 설정해주면 도커 이미지의 크기를 많이 줄일 수 있다.

 

참고 

Gradle을 사용할 때 도커 빌드를 빠르게 하는 방법 - Soo Story (findstar.pe.kr)

728x90
반응형
728x90
반응형

1. reset

아직 원격 저장소에 push하기 전이라면 reset을 사용할 수 있다.

없애고 싶은 커밋이 있을 때, reset을 이용하면 해당 커밋을 흔적도 없이 지울 수 있다.

 

문법은 아래와 같다.

$ git reset --옵션 커밋해시

옵션으로는 hard, soft, mixed 등이 있고,

커밋해시에는 돌아가고 싶은 커밋의 해시 주소를 입력하면 된다.

 

옵션에 대해 간략하게 살펴보자.

 

1) hard

돌아가려는 커밋 이후의 모든 내용을 지워 버린다.

staging area와 working directory 모두 돌아가려는 커밋과 동일해진다.

 

2) soft

돌아가려는 커밋으로 되돌아가고, HEAD가 돌아가려는 커밋을 새롭게 가리키게 된다.

staging area와 working directory는 아무런 변화도 없다.

 

3) mixed

돌아가려는 커밋으로 되돌아가고, HEAD가 돌아가려는 커밋을 새롭게 가리키게 된다.

staging area는 돌아가려는 커밋과 동일해지고, working directory는 아무 변화가 없다.

 

그다음 git push를 해준다.

$ git push --force --set-upstream origin master

git log를 다시 찍어보면 revert가 잘 된 것을 확인할 수 있을 것이다.

 

 

2. revert

이미 원격 저장소에 push한 상태라면 reset은 사용할 수 없고 revert를 사용해야 한다.

이것이 reset과 revert의 차이이다.

 

그렇다면 revert의 사용방법에 대해 알아보자.

 

우선 git log로 해시주소를 파악해야 한다.

git log 찍고, 커밋이 다음의 commit1>2>3의 순서로 발생했다고 해보자.

오른쪽에 뜨는 것이 git hash이다.

commit3        54c6547
commit2        a516d21
commit1        4567289    // 되돌아가려는 커밋

 

내가 돌아가려는 커밋이 commit1이면,

commit3를 먼저 revert하고 이후 commit2를 revert하는 방식으로 순차적으로 진행해야 한다.

아래와 같이 입력하면 된다.

$ git revert 54c6547
$ git revert a516d21

 

그다음 git push를 해준다.

$ git push --force --set-upstream origin master

 

git log를 다시 찍어보면 revert가 잘 된 것을 확인할 수 있을 것이다.

728x90
반응형
728x90
반응형

1. 인스턴스 서버에 도커 설치

$ sudo wget -qO- http://get.docker.com/ | sh

 

2. 인스턴스 서버에서 도커 로그인

$ docker login

 

3. 도커 시작

$ sudo systemctl start docker

 

4. 도커허브에서 이미지 pull 

ex) Next.js

$ docker pull 도커허브아이디/web_client:버전정보

 

ex) Spring

$ docker pull 도커허브아이디/java_server:버전정보

 

5. 이미지 확인

$ docker images

 

 

6. Docker run

포트는 프로젝트에 맞게 설정해야함.

$ docker run -p 8083:8083 -d --rm --name java_server ID/Repository

 

$ docker run -p 80:3000 -d --rm --name web_client ID/Repository

 

728x90
반응형
728x90
반응형

1. env 수정

 

ex) /next.config.js

/** @type {import('next').NextConfig} */
const path = require('path');
const withImages = require('next-images');

module.exports = {
  reactStrictMode: true,
  async rewrites() {
    if (process.env.NODE_ENV === "production") {
      return [
        {
          source: process.env.PRODUCTION_JAVA_SERVER_PATH,
          destination: process.env.PRODUCTION_JAVA_SERVER_URL,
        }

      ];
    } else {
      return [
        {
          source: process.env.JAVA_SERVER_PATH,
          destination: process.env.JAVA_SERVER_URL,
        }
      ];
    }
  },
};

 

 

/.env.local

NODE_ENV = 'development'

PRODUCTION_JAVA_SERVER_PATH = '/java/:path*'
PRODUCTION_JAVA_SERVER_URL = 'http://사용하는 IP 주소:8083/:path*'

JAVA_SERVER_PATH = '/java/:path*'
JAVA_SERVER_URL = 'http://localhost:8083/:path*'

 

2. Dockerfile 생성

프로젝트 루트 경로에 만들어준다.

/Dockerfile

# 위에서 도커 허브 node 이미지를 기반으로 로컬로 다운로드 및 캐싱 되었기 때문에 이미지를 가져올 수 있다.
FROM node:18.4.0

# 만약 컨테이너 안의 이미지의 경로가 /app 이런식으로 되어있다면 작업할 div 경로를 설정할 수도 있다.
# 설정해주면 COPY 의 두번째 경로를 ./ 이것으로 했을 때 자동으로 /app 경로가 된다.
WORKDIR /app

# package.json 파일을 복사한다. 만약 다시 빌드할 때 변경사항이 없을 경우 npm install까지 그냥 넘어간다.
COPY package.json /app

# 이미지를 받으면 npm install을 자동으로 해줌
RUN npm install


# 어떤 파일이 이미지에 들어가야 하는지 
# 첫 번째 .은 이 프로젝트의 모든 폴더 및 파일들 (Dockerfile을 제외한)
# 두 번째 .은 파일을 저장할 컨테이너 내부 경로 (ex /app)
COPY . /app

# 배포환경으로 설정
ENV NODE_ENV=production

RUN npm run build

# 도케에게 우리가 서버를 실행할 포트를 말해준다.
EXPOSE 3000

# 이미지가 생성될 때 실행되지 않고 컨테이너가 실행될 때 수행하는 명령어
CMD ["npm","start"]

 

당연한 말이지만 개발 서버와 node 버전을 맞춰주어야 한다. 

 

3. dockerignore 생성

/.dockerignore

.node_modules

.next

 

4. next.config.js 수정

module.exports = {
  output: 'standalone'
}

 

5. 이미지 빌드

$ docker build -t 도커허브아이디/web-client:버전정보 .

web_client 는 임의로 제가 지은 이름입니다.

docker 프로그램에서 확인할 수도 있다.

 

혹시 맥북에서 빌드하고 linux/amd64 서버에 배포할 예정이라면 

docker buildx build --platform=linux/amd64 -t 도커허브아이디/web_client:버전정보 .

 

6. Dockerhub Repository 생성

 

7. 도커허브 업로드

# 업로드
docker push 도커허브아이디/web_client

 

 


Server

 

1. 인스턴스 서버에 도커 설치

$ sudo wget -qO- http://get.docker.com/ | sh

 

2. 인스턴스 서버에서 도커 로그인

$ docker login

 

3. 도커 시작

$ sudo systemctl start docker

 

4. 도커허브에서 이미지 pull 

$ docker pull 도커허브아이디/web_client:버전정보

 

5. 이미지 id 확인

$ docker images

 

6. 컨테이너 실행

$ docker run -p 80:3000 -d --rm 도커허브아이디/web_client
728x90
반응형

+ Recent posts