반응형

반복 작업의 필요성

Schedule이란 일정 주기별로 반복되는 Job을 처리하는 것을 의미합니다.
주기는 다음과 같은 것들이 있을 수 있습니다.

  • 매시, 매일, 매주, 매월, 매년
  • 격주, 격월
  • 특정 시간, 특정 요일, 특정 일자 등등

 

반복되는 작업들은 어떤 것들이 있을까요?

  • 어제의 사이트 통계를 다음날 아침 Slack에 뿌려주기
  • 일주일에 한번 특정 사이트를 크롤링해서 데이터 저장하기
  • 생일인 고객에게 쿠폰을 발행해서 메시지 보내기

이런 작업들을 일일이 수동으로 처리하기는 매우 어렵습니다.

이때 자동화된 스케줄러가 필요합니다.

리눅스의 Crontab

이런 Schedule을 처리하는 대표적인 프로그램이 Linux에서 제공하는 crontab입니다.

리눅스 shell에서 "crontab -e" 명령을 사용하여 편집모드에서 설정을 하게되면,

일정 주기별로 반복 수행하는 형태입니다.

crontab 형식
crontab 샘플

 

AWS 에서 Scheduler 사용하기

Cloud 환경이 되면서 오면서 crontab을 사용하는 것이 어려워졌습니다.

쿠버네티스, AWS ECS등의 도커 기반 오케스트레이션 플랫폼을 사용하게 되면서, 인스턴스의 관리를 사용자가 아닌 플랫폼이 맡게 되기 때문입니다. 이로 인해 사용자가 직접 서버를 수정하는 일이 대부분 사라지게 되었습니다.

 

crontab을 대신할 수 있도록 AWS에서는 Amazon Event Bridge라는 서비스를 제공하고 있습니다.

Amazon EventBridge

Amazon Event Bridge와 AWS Lambda를 조합하면 다양한 구현이 가능합니다.

Amazon Event Bridge + AWS Lambda

 

Amazon EventBridge는 crontab과 거의 유사한 방식으로 aws console에서 구현이 가능합니다.

 

스케줄러 샘플 구현 

Amazon Event Bridge와 Lambda를 이용해 API를 호출하는 서비스를 구현하는 방법을 샘플을 통해 알아봅니다.

순서는 다음과 같습니다.

  • (API를 호출하는) Lambda Function 만들기
  • Amazon EventBridge에 Schedule 등록하기

Lambda Function 만들기

  • AWS Lambda에서 함수를 생성합니다.
  • Python 3.10과 arm을 이용하도록 셋팅합니다.
  • 코드를 다음과 같이 작성합니다.
import json
import requests

def lambda_handler(event, context):
	print('calling...')
	url = "https://api.sample.com/..."
	header = {
		'Content-Type': 'application/json; charset=UTF-8',
		'User-Agent': ...
	}
	res = requests.get(
		url,
		headers,
		data={}
	)
	print(res.content)
	return {
		'statusCode': 200,
		'body': ...
	}
  • requests 라이브러리는 aws에서 기본 제공이 아니기 때문에 Layer를 만들어 추가해 주어야 합니다.
  • Layer는 반드시 python 폴더를 만드시고 해당 폴더에서 pip install로 추가해야 합니다.
mkdir python
cd python

pip install requests -t .
  • python 폴더를 압축합니다. (python.zip)
  • Lambda 메뉴에서 계층을 선택 후 계층 생성 버튼을 클릭합니다.

  • upload에서 python.zip 파일을 추가합니다.

 

Amazon EventBridge에 Scheduler 등록하기

  • Amazon EventBridge 서비스에서 좌측 메뉴의 Scheduler - 일정 메뉴 선택
  • 일정 생성 버튼 클릭
  • cron 형식으로 일정 패턴 등록

  • 대상 선택에서 AWS Lambda를 선택

  • Invoke를 선택하고, 생성한 Lambda function을 선택하면 됩니다.

이렇게 하면 매일 아침 9시에 API를 호출하는 Schedule을 사용할 수 있습니다.

반응형
반응형

AWS의 S3에 이미지를 올리면 자동으로 썸네일을 만들어 주는 람다에 대해 설명합니다.

다음은 이글의 유튜브 강의입니다.

https://youtu.be/fMtNmmtlLig


홈페이지에 갤러리 기능을 만들게 되면 꼭 필요한게 이미지의 썸네일 입니다.

이미지를 업로드 할때마다 썸네일을 별도로 제작하기는 너무 귀찮은 작업이죠.

이럴때 AWS의 람다를 사용하면 썸네일을 자동으로 생성할 수 있습니다.

 

해당 내용은 AWS 공식 홈페이지에 자세하게 설명이 되어 있습니다.

https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/with-s3-tutorial.html

 

자습서: Amazon S3 트리거를 사용하여 썸네일 이미지 생성 - AWS Lambda

자습서: Amazon S3 트리거를 사용하여 썸네일 이미지 생성 이 자습서에서는 Lambda 함수를 생성하고 Amazon Simple Storage Service(Amazon S3)에 대한 트리거를 구성합니다. Amazon S3는 S3 버킷에 업로드된 각 이

docs.aws.amazon.com

해당 내용을 기반으로 썸네일 자동 생성 기능을 만들어 봅니다.

 

순서는 다음과 같습니다.

1. AWS CLI 설치

2. 버킷 생성

3. IAM 역할(Role) 생성

4. 리사이즈용 프로그램 개발(Python)

5. 프로젝트 빌드

6. 배포

7. S3 트리거 생성

8. 테스트

 

1. AWS CLI 설치

간단한 파이썬 코드를 작성할 경우에는 AWS 콘솔에서도 파이썬 라이브러리가 포함되어 있기 때문에 작업이 가능하지만,

이미지 썸네일을 만드는 경우에는 pillow라는 라이브러리를 사용해야 하므로 콘솔에서는 처리가 어렵습니다.

따라서 로컬에서 라이브러리를 다운받아 서버에 배포하는 과정이 필요합니다.

 

로컬에서 람다 패키지를 만들어 서버에 배포하기 위해서는 AWS CLI를 사용합니다.

다음 URL에 각OS별 설치 방법에 따라 설치를 합니다.

https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/getting-started-install.html

 

최신 버전의 AWS CLI 설치 또는 업데이트 - AWS Command Line Interface

이전 버전에서 업데이트하는 경우 unzip 명령을 실행하면 기존 파일을 덮어쓸지 묻는 메시지가 표시됩니다. 스크립트 자동화와 같은 경우에 이러한 프롬프트를 건너뛰려면 unzip에 대한 -u 업데이

docs.aws.amazon.com

 

2. 버킷 생성

AWS 콘솔에 로그인해서 S3 서비스에서 버킷을 만들어 줍니다. (기존 버킷을 사용해도 됨)

 

저는 다음과 같이 버킷을 생성하였습니다.

  • codegear-slider-bucket

 

다음과 같이 폴더를 2개 생성합니다.

  • images : 이미지 업로드용 폴더
  • resized-images : 썸네일 자동 생성 이미지 저장용 폴더

 

3. IAM 역할(Role) 생성

AWS 콘솔의 IAM으로 이동.

액세스 관리 - 역할(Role) 메뉴로 이동하여 "역할 만들기"를 클릭.

  • Role Name : S3_Image_Resize

권한 정책에는 다음 3가지를 추가합니다.

  • AmazonS3FullAccess (S3 Access 권한)
  • AWSLambdaBasicExecutionRole (Clowd Watch 로그 작성 권한)
  • AWSLambda_FullAccess (Lambda Access 권한)

 

4. 리사이즈용 프로그램 개발(Python)

로컬환경에서 이미지 리사이즈용 파이썬 프로젝트를 생성합니다.

lambda-s3-python 폴더를 생성하고 생성된 폴더로 이동합니다.

  • lambda_function.py로 파이썬 소스 파일을 생성합니다.

다음과 같이 코드를 생성합니다.

import boto3
import os
import sys
import uuid
from urllib.parse import unquote_plus
from PIL import Image
import PIL.Image

s3_client = boto3.client('s3')

def resize_image(image_path, resized_path):
  base_width = 300
  with Image.open(image_path) as image:
    w_percent = (base_width/float(image.size[0]))
    h_size = int((float(image.size[1])*float(w_percent)))
    image = image.resize((base_width,h_size), Image.ANTIALIAS)
    image.save(resized_path)

def lambda_handler(event, context):
  for record in event['Records']:
    bucket = record['s3']['bucket']['name']
    key = unquote_plus(record['s3']['object']['key'])
    tmpkey = key.replace('/', '')
    download_path = '/tmp/{}{}'.format(uuid.uuid4(), tmpkey)
    upload_path = '/tmp/resized-{}'.format(tmpkey)
    s3_client.download_file(bucket, key, download_path)
    resize_image(download_path, upload_path)
    s3_client.upload_file(upload_path, '{}'.format(bucket), 'resized-{}'.format(key))

pillow 파이썬 라이브러리를 package 폴더에 설치합니다.

pip install --target ./package pillow

template.yaml 파일을 루트폴더에 생성합니다.

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  CreateThumbnail:
    Type: AWS::Serverless::Function
    Properties:
      Handler: lambda_function.lambda_handler
      Runtime: python3.9
      Timeout: 10
      Policies: AWSLambdaExecute
      Events:
        CreateThumbnailEvent:
          Type: S3
          Properties:
            Bucket: !Ref SrcBucket
            Events: s3:ObjectCreated:*

  SrcBucket:
    Type: AWS::S3::Bucket

requirements.txt 파일을 루트폴더에 생성합니다.

Pillow == 9.2.0

 

5. 프로젝트 빌드

다음 명령어로 배포용 패키지를 빌드 합니다.

sam build --use-container

 

6. 배포

서버에 람다 함수를 배포합니다.

sam deploy --guided

 

 

7. S3 트리거 생성

AWS의 Lambda 서비스로 이동.

생성된 Lambda 함수를 클릭 후 함수명 클릭.

함수 개요에서 "트리거 추가"를 클릭합니다.

트리거 구성 아래의 소스 선택에 "S3"를 입력한 후 나타나는 S3를 선택합니다.

버킷을 선택하고, 접두어에는 버킷의 폴더명을, 체크박스를 체크하고 추가를 선택합니다.

아래와 같이 트리거가 추가 된걸 볼 수 있습니다.

8. 테스트

버킷의 images 폴더에 이미지를 업로드 합니다.

resized-images 폴더에 아래와 같이 이미지가 생성된것 볼 수 있습니다.

이미지를 다운받아 속성을 보면 크기가 "300 X 168 픽셀"로 만들어졌음을 볼 수 있습니다.

 

이상으로 AWS의 람다 기능을 이용해서 S3에 업로드된 이미지의 썸네일을 자동으로 만들어 보았습니다.

반응형
반응형

지난 글에 이어 Github Desktop 사용법에 대해 조금 더 알아보겠습니다.

 

다음은 이글의 동영상 강좌입니다.

https://youtu.be/n77Jtz1iP_M

 

순서

  • Private 프로젝트 만들기
  • Github desktop에서 github.com 계정으로 로그인
  • Branch 개념 이해하기
  • Branch 생성
  • Branch Merge

 

Private 프로젝트 만들기

외부에 공개되지 않는 자신만의 프로젝트를 만들기 위해서는 private으로 프로젝트를 만듭니다.

  • www.Github.com 에서 Repository 메뉴로 이동합니다.
  • 우측 상단의 [New] 버튼을 클릭합니다.

  • [프로젝트명]을 입력합니다.(예: test)
  • [public / private] 항목에서 private를 선택합니다.

  • [Add a README file] 이라고 된 부분을 체크하고, [Create repository] 버튼을 클릭하여 프로젝트를 생성합니다.

  • readme 파일이 하나 추가된 [test repository]가 아래와 같이 생성됩니다.

Github Desktop에서 github.com 로그인 하기

private로 만들어진 프로젝트는 로그인을 해야만 사용이 가능합니다. github desktop에서는 github 로그인 기능을 제공하므로, 이것을 알아보겠습니다.

  • github desktop을 실행합니다.
  • 상단의 [Github Desktop] 메뉴에서 [Preferences]를 클릭합니다.

 

  • [Accounts] 메뉴에 들어가면 Github.com 항목의 [Sign In]을 클릭합니다.

  • Sign in Using Your Browser
    - 현재 github.com에 로그인한 브라우저를 통해서 로그인을 할 수 있습니다.

 

레파지토리 추가하기

  • Repository명 옆의 버튼을 클릭합니다.

  • clone repository를 선택합니다.
  • github.com tab을 클릭한 후 test repository를 선택하고 clone 버튼을 클릭하면 소스가 다운로드 됩니다.

 

Branch 만들기

  • 화면에서 main branch 옆의 화살표를 클릭합니다.

  • New Branch를 선택합니다.

  • 브랜치명을 "develop" 이라고 입력하고 "Create Branch"를 클릭합니다.

  • "Publish branch"를 클릭하여 github.com에 share 합니다.

  • github.com에서 새로고침해보면 branch가 2개가 된것을 확인할 수 있습니다.

 

Branch 개념 이해하기

  • 한개의 Branch만 사용할 경우 (Main Branch)
    • Main Branch에 push될때 운영 배포가 이루어지게 설정을 해 놓았다면,
    • 소스를 push 할때마다 운영서비스에 반영이 됩니다.
    • 소스에 대한 검증이 제대로 안될 경우 장애가 발생할 수 있습니다.

  • 두개의 Branch를 사용할 경우 (Develop Branch)
    • Sub Branch를 활용해서 개발기에 배포를 하고 소스를 검증한 후
    • Main Branch에 Merge 하여 안전하게 운영 서버에 배포를 할 수 있습니다.

Merge 하기

develop branch의 소스를 변경한 후 main에 merge 하는 방법입니다.

  • develop branch를 선택합니다.
  • 소스를 수정합니다. 

  • develop branch에 commit과 push를 합니다.

  • main branch로 변경합니다.

  • 상단 메뉴에서 "Branch"-"Merge Into Current Branch"를 선택합니다.

  • Merge할 브랜치를 선택하는 화면에서 "develop" branch를 선택하고 "Create a merge commit" 버튼을 클릭합니다.

  • "Push origin" 버튼을 클릭하면 Merge가 완료됩니다.

 

 

반응형
반응형

이전 글 배포자동화(CI/CD) - Github Action/Nuxtjs/Docker/EC2에서는 Github Action을 활용한 배포자동화를 중점적으로 다루었습니다.

 

아래는 이 글의 동영상 강의입니다.

https://youtu.be/eyFO57ZkJaI

 

이걸 조금 더 발전시켜 컨테이너를 2중화 시키고 순차적으로 배포를 해서, 시스템의 중단 없이 배포하는 방법에 대해 알아봅니다.

구성도는 다음과 같습니다.

환경은 이전과 동일합니다.

다만 분산처리를 위해 nginx proxy만 추가 되었습니다.

그리고 docker instance를 2개를 생성합니다.

환경

  • 프론트 : Vuejs (Nuxt)
  • 형상관리 : Git (Github)
  • 빌드 : Docker (Github Action)
  • 서버 : Linux (AWS EC2 micro)
  • 프록시 : nginx

이전 글에서 이미 Docker Image등의 구성이 완료되었으므로, 프로젝트 폴더의 .github/workflow/main.yml 파일을 수정하여 2중화를 구성할 수 있습니다.

 

.github/workflows/main.yml

name: CI/CD Docker

# 트리거를 수행할 브랜치를 지정합니다.
on:
  push:
    branches: [ main ]

# 환경설정
env:
  DOCKER_IMAGE: ghcr.io/${{ github.actor }}/nuxt-auto-deploy
  VERSION: ${{ github.sha }}
  CONTANIER_NAME1: nuxt-auto-deploy1
  CONTANIER_NAME2: nuxt-auto-deploy2
  DOMAIN_NAME: domain or ip
  NAME: prod

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      # github repository에서 checkout
      - uses: actions/checkout@v2
      # docker build 수행
      - name: Set up docker buildx
        id: buildx
        uses: docker/setup-buildx-action@v1
      - name: Cache docker layers
        uses: actions/cache@v2
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-buildx-${{ env.VERSION }}
          restore-keys: |
            ${{ runner.os }}-buildx-
      # GitHub 컨테이너 레지스트리에 로그인 후 빌드 & 푸시
      - name: Login to ghcr
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Build and push
        id: docker_build
        uses: docker/build-push-action@v2
        with:
          builder: ${{ steps.buildx.outputs.name }}
          push: true
          tags: ${{ env.DOCKER_IMAGE }}:${{ env.VERSION }}
  # 배포 Job
  deploy:
    needs: build  # build 후에 실행되도록 정의
    name: Deploy
    runs-on: [ self-hosted, label-go ] # AWS ./configure에서 사용할 label명
    steps:
      - name: Login to ghcr
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Docker run
        run: |
          docker ps -q --filter "name=${{ env.CONTANIER_NAME1 }}" | grep -q . && docker stop ${{ env.CONTANIER_NAME1 }} && docker rm -fv ${{ env.CONTANIER_NAME1 }}
          docker run -d \
                -e VIRTUAL_HOST=${{ env.DOMAIN_NAME }} \
                -e CONTANIER_NAME=${{ env.CONTANIER_NAME1 }} \
                --name ${{ env.CONTANIER_NAME1 }} \
                --restart always ${{ env.DOCKER_IMAGE }}:${{ env.VERSION }}
          docker ps -q --filter "name=${{ env.CONTANIER_NAME2 }}" | grep -q . && docker stop ${{ env.CONTANIER_NAME2 }} && docker rm -fv ${{ env.CONTANIER_NAME2 }}
          docker run -d \
                -e VIRTUAL_HOST=${{ env.DOMAIN_NAME }} \
                -e CONTANIER_NAME=${{ env.CONTANIER_NAME2 }} \
                --name ${{ env.CONTANIER_NAME2 }} \
                --restart always ${{ env.DOCKER_IMAGE }}:${{ env.VERSION }}
          docker image prune -af

env: 아래에 컨테이너 명을 다음과 같이 추가합니다.

  CONTANIER_NAME1: nuxt-auto-deploy1
  CONTANIER_NAME2: nuxt-auto-deploy2
  DOMAIN_NAME: domain or ip

deploy -> steps -> -name: Docker run

아래에 컨테이너 실행 명령을 다음과 같이 입력합니다.

- name: Docker run
run: |
  docker ps -q --filter "name=${{ env.CONTANIER_NAME1 }}" | grep -q . && docker stop ${{ env.CONTANIER_NAME1 }} && docker rm -fv ${{ env.CONTANIER_NAME1 }}
  docker run -d \
        -e VIRTUAL_HOST=${{ env.DOMAIN_NAME }} \
        -e CONTANIER_NAME=${{ env.CONTANIER_NAME1 }} \
        --name ${{ env.CONTANIER_NAME1 }} \
        --restart always ${{ env.DOCKER_IMAGE }}:${{ env.VERSION }}
  docker ps -q --filter "name=${{ env.CONTANIER_NAME2 }}" | grep -q . && docker stop ${{ env.CONTANIER_NAME2 }} && docker rm -fv ${{ env.CONTANIER_NAME2 }}
  docker run -d \
        -e VIRTUAL_HOST=${{ env.DOMAIN_NAME }} \
        -e CONTANIER_NAME=${{ env.CONTANIER_NAME2 }} \
        --name ${{ env.CONTANIER_NAME2 }} \
        --restart always ${{ env.DOCKER_IMAGE }}:${{ env.VERSION }}
  docker image prune -af

이렇게 하면 컨테이너가 순차적으로 2개 구동이 됩니다.

 

배포시에 1개 서버 배포가 완료되어야 다음 단계를 진행하게 되므로, 사용자는 중단 없이 서비스를 이용할 수 있습니다.

 

이제 서버를 분배할 nginx proxy를 설정합니다. 

우리는 jwilder/nginx-proxy 도커 이미지를 사용합니다.

https://hub.docker.com/r/jwilder/nginx-proxy

 

Docker Hub

 

hub.docker.com

EC2에 로그인한 후 vhost.d 폴더를 생성합니다.

/home/ec2-user/vhost.d

 

vhost.d 폴더로 이동한 후,

ec2의 domain명으로 파일을 생성하고 아래 내용을 작성합니다.

- 이 옵션은 nginx의 보안을 위해 버전을 표시하지 않게 합니다.

server_tokens off;

 

docker를 실행합니다.

docker run -d -p 80:80 -p 443:443 
 -v /home/ec2-user/vhost.d:/etc/nginx/vhost.d:ro 
 -v /var/run/docker.sock:/tmp/docker.sock:ro 
 jwilder/nginx-proxy:alpine

 

반응형
반응형

다음은 이 글의 유튜브 영상입니다.

https://youtu.be/E3i9qt0SS-I

 

프로젝트를 진행할때 많은 시간을 들여야 하는 것 중에 하나가 바로 배포입니다.

형상관리(Git)에 커밋을 하고, 서버에 파일을 업로드 하고, 서버를 리스타트 하는 과정들을 수작업으로 반복하다 보면 여간 불편한게 아니죠.

이럴때 자동 배포 기능을 만들면 개발 PC에서 커밋하는 것만으로도 배포를 할 수 있습니다. 그럼 나머지 시간들은 다시 개발을 하거나 조금 쉴 수 있는 여유가 생기겠죠?

 

우선 전체적인 구성은 다음과 같습니다.

  1. 로컬 PC에서 개발을 한 후 Github에 Push를 합니다.
  2. Github Repository 특정 branch에 push가 되면 Github Action이 동작을 시작합니다.
  3. Github Actions가 Github Container Registry에 소스를 받은 후 Docker 이미지로 빌드를 합니다.
  4. 빌드된 이미지를 EC2에 등록된 Runner가 복사합니다.
  5. 기존 이미지를 삭제하고 새로운 이미지로 실행을 합니다.

환경

  • 프론트 : Vuejs (Nuxt)
  • 형상관리 : Git (Github)
  • 빌드 : Docker (Github Action)
  • 서버 : Linux (AWS EC2 micro)

* nodejs, git, docker는 기본적으로 설치되어 있어야 합니다.

순서

  • Github 저장소 생성
  • 프로젝트 원격 저장소 클론
  • Nuxt 프로젝트 생성
  • Docker로 로컬 테스트
  • Github Actions
  • AWS EC2 생성 및 Docker 설치
  • 자동 배포 테스트

Github 저장소 생성 및 연결

www.github.com 에서 아래와 같이 저장소를 만듭니다.

  • Repository name은 프로젝트명과 동일하게 생성합니다.
  • Repository는 아무나 사용할 수 없도록 private으로 만듭니다.
  • 주의하실 점은 Owner명에 대문자가 들어가 있으면 안됩니다.
  • Github Action에서 도커빌드시에 대문자를 쓸 수 없다는 오류가 납니다.

프로젝트 원격 저장소 클론

원격 저장소를 local PC로 클론합니다.

  • 저는 github desktop을 이용했습니다.
  • git 명령어 또는 다른 프로그램을 사용하셔도 됩니다.

  • 우측 상단의 아래 화살표를 클릭합니다.

  • 우측 상단의 Add 버튼을 누르고 clone repository를 선택합니다.

 

 

  • Repository를 선택하고 Clone 버튼을 클릭하면 로컬PC에 폴더가 생성됩니다.

 

Vue (Nuxt) 프로젝트 생성

Clone 받은 폴더로 이동한 후 다음과 같이 Nuxt 프로젝트를 생성합니다. 

  • 선택항목은 모두 자동으로 선택합니다.
npx create-nuxt-app nuxt-auto-deploy

프로젝트 생성이 완료되면 생성된 모든 파일을 상위 폴더로 옮겨줍니다.

cd nuxt-auto-deploy
mv * ..

다시 상위 폴더로 이동하여 비어있는 nuxt-auto-deploy 폴더를 삭제합니다.

cd ..
rm -Rf nuxt-auto-deploy

 

다음과 같이 프로젝트를 실행합니다.

npm run dev 또는 yarn dev

실행이 완료되면 브라우저에서 http://localhost:3000으로 실행 화면을 확인할 수 있습니다.

 

확인이 되었으면 ctrl+C 키를 눌러 프로젝트 실행을 종료합니다.

 

Docker로 로컬 테스트

Docker 이미지를 만들기 위해 프로젝트 루트에 Dockerfile을 아래와 같이 생성합니다.

FROM node:14.19.0

RUN mkdir -p /app
WORKDIR /app
ADD . /app/

RUN rm yarn.lock || true
RUN rm package-lock.json || true
RUN yarn
RUN yarn build

ENV HOST 0.0.0.0
EXPOSE 3000

CMD [ "yarn", "start"]
  • FROM node:14.19.0 : nodejs 14.19.0 버전의 이미지를 받아서 docker image를 생성합니다.
  • RUN mkdir -p /app : app 폴더를 생성합니다.
  • ADD . /app/ : 현재 폴더의 모든것을 생성된 app 폴더에 복사합니다.
  • RUN rm ... || true : 파일 삭제. 뒤의 "|| true" 는 파일이 없을 경우 오류로 인해 실행이 중단되지 않게 하기 위해 추가합니다.
  • RUN yarn build : nuxt 프로젝트를 빌드합니다.
  • ENV HOST 0.0.0.0 : 모든 IP를 개방합니다.
  • EXPOSE 3000 : 3000번 포트를 개방합니다.
  • CMD ["yarn", "start"] : yarn start 명령을 실행합니다.

Docker 이미지 생성시 불필요한 파일을 제외하도록 루트 폴더에 .dockerignore 파일을 생성합니다.

node_modules/
dist/

Dockerfile을 저장하고 다음 명령으로 이미지를 생성 합니다.

docker build --tag nuxt-auto-deploy:0.0.1 .

Docker 이미지를 실행합니다.

docker run --name nuxt-auto-deploy -d -p 3000:3000 nuxt-auto-deploy:0.0.1
  • --name 뒤의 이름(nuxt-auto-deploy)은 도커 컨테이너명이고,
  • 뒤의 nuxt-auto-deploy:0.0.1은 docker image명과 tag명입니다.

localhost:3000으로 접속하면 아까와 동일한 화면을 확인할 수 있습니다.

Docker 테스트가 모두 완료되었으므로 코드를 github에 push 합니다.

 

Github Actions 

Github Access Token 발급
github에 접속한 후 계정에서 settings 메뉴로 이동합니다.

왼쪽 메뉴 하단의 Developer settings를 선택합니다.

왼쪽 메뉴에서 Personal access tokens를 선택하고, Generate new token을 선택합니다.

토큰의 유효기간과 권한을 설정합니다.

  • 유효기간은 최대 1년까지 가능합니다.
  • 권한은 workflow, write:packages, delete:packages를 선택합니다.

하단의 generate 버튼을 클릭하면 토큰이 생성됩니다.

생성된 토큰을 복사하여 Repository-Settings-Secret-Actions에 등록합니다.

 

 

레파지토리의 Actions 탭으로 이동하여 "set up a workfolow yourself"를 클릭합니다.

아래와 같이 workflow 파일을 작성합니다.

이것은 Github Container Registry를 이용해서 docker를 빌드하고 서버에 푸쉬해주는 역할을 합니다.

 

Github Actions으로 AWS EC2에 CI/CD 구축하기

AWS EC2에 CI/CD 구축하기

velog.io

다음은 workflow 파일입니다.( .github/workflows/main.yml)

name: CI/CD Docker

# 트리거를 수행할 브랜치를 지정합니다.
on:
  push:
    branches: [ main ]

# 환경설정
env:
  DOCKER_IMAGE: ghcr.io/${{ github.actor }}/nuxt-auto-deploy
  VERSION: ${{ github.sha }}
  NAME: go_cicd

jobs:
  # 빌드 Job
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      # github repository에서 checkout
      - uses: actions/checkout@v2
      # docker build 수행
      - name: Set up docker buildx
        id: buildx
        uses: docker/setup-buildx-action@v1
      - name: Cache docker layers
        uses: actions/cache@v2
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-buildx-${{ env.VERSION }}
          restore-keys: |
            ${{ runner.os }}-buildx-
      # GitHub 컨테이너 레지스트리에 로그인 후 빌드 & 푸시
      - name: Login to ghcr
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Build and push
        id: docker_build
        uses: docker/build-push-action@v2
        with:
          builder: ${{ steps.buildx.outputs.name }}
          push: true
          tags: ${{ env.DOCKER_IMAGE }}:latest
  # 배포 Job
  deploy:
    needs: build  # build 후에 실행되도록 정의
    name: Deploy
    runs-on: [ self-hosted, label-go ] # AWS ./configure에서 사용할 label명
    steps:
      - name: Login to ghcr
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
      # 3000 -> 80 포트로 수행하도록 지정
      - name: Docker run
        run: |
          docker stop ${{ env.NAME }} && docker rm ${{ env.NAME }} && docker rmi ${{ env.DOCKER_IMAGE }}:latest
          docker run -d -p 80:3000 --name go_cicd --restart always ${{ env.DOCKER_IMAGE }}:latest

commit 버튼을 클릭하면 다음과 같이 파일이 생성됩니다.

.github/workflows/main.yml

 

AWS EC2 생성 및 Docker 설치

이제 자동 배포가 적용될 서버를 만듭니다.

AWS console에 로그인 한 후 EC2 서비스로 이동합니다.

인스턴스 시작 버튼을 클릭합니다.

무료로 사용할 수 있는 Amazon Linux 2 AMI를 선택합니다.

t2.micro를 선택하고 검토및시작 버튼을 클릭합니다.

보안그룹 편집을 선택합니다.

규칙추가 버튼을 누르고 80번 port를 추가한 후 검토및시작 버튼을 클릭합니다.

인스턴스 실행이 완료되면 해당 인스턴스를 체크하고 연결을 클릭합니다.

SSH 클라이언트를 클릭하면 접속 방법이 나옵니다.

터미널을 이용해 ssh로 접속을 합니다.

 

AWS에 Docker 설치

아래 내용을 참조해서 Docker를 설치합니다.

https://docs.aws.amazon.com/ko_kr/AmazonECS/latest/developerguide/create-container-image.html#create-container-image-install-docker

 

Amazon ECS용 Docker 기본 사항 - Amazon Elastic Container Service

Amazon ECS용 Docker 기본 사항 Docker는 사용자가 Linux 컨테이너를 기반으로 하는 분산 애플리케이션을 구축, 실행, 테스트 및 배포할 수 있는 도구를 제공합니다. Amazon ECS는 태스크 정의에 Docker 이미

docs.aws.amazon.com

AWS에 Github Runner 설치

github repository의 settings 탭에서 Runner를 선택합니다.

Runners / Create self-hosted runner를 선택하고, Linux를 선택합니다.

Architecture는 x64로 하고 Download 항목을 한라인씩 복사해서 EC2에서 실행합니다.

./config.sh 문을 실행하면 다음과 같이 입력을 요청합니다.

  • Enter the name of the runner group to add this runner to : 엔터
  • Enter the name of runner : 엔터
  • Enter any additional label : label-go (워크플로우 yml에 작성했던 라벨명
  • Enter name of work folder : 엔터

./run.sh는 다음과 같이 백그라운드로 실행을 합니다.

nohup ./run.sh &
  • tail -f nohup.out 명령을 실행하면 ec2상의 빌드 로그를 확인할 수 있습니다.

Runner 셋팅이 끝나면 github의 Settings - Actions - Runner 메뉴에서 다음과 같이 등록된것을 확인할 수 있습니다.

 

자동 배포 테스트

이제 소스를 수정하고 push를 하면 다음과 같이 빌드가 실행이 됩니다. 

해당 빌드를 클릭하면 세부 정보를 확인할 수 있습니다.

build와 Deploy가 나타나고, 실행되는 것을 확인 할 수 있습니다.

Build 또는 Deploy를 누르면 세부 실행 내역을 볼 수 있습니다.

Deploy가 완료되면 다음과 같은 화면을 볼 수 있습니다.

EC2 인스턴스의 공인 IP를 확인합니다.

브라우저에 아이피를 입력하면 다음과 같은 결과를 확인할 수 있습니다.

 

이제 Push를 하면 서버에 자동 배포가 되는 것을 확인할 수 있습니다.

 

branch를 하나 더 만들어서 (예 : develop) 개발시에 사용하고,
main으로 merge 할 때 자동으로 배포되도록 하는 것도 가능합니다.

반응형
반응형

AWS의 Route53에서 서브 도메인을 생성하는 방법입니다.

기존에 www.mycodegear.com이라는 도메인이 있을 경우, blog.mycodegear.com과 같은 서브 도메인을 추가할 수 있습니다.

 

- AWS 콘솔에 접속 후 Route53으로 이동합니다.

- 호스팅영역을 클릭합니다.

- 서브도메인을 추가할 도메인 이름을 클릭합니다.

- 레코드 생성을 클릭합니다.

- 레코드 이름에 서브도메인의 이름을 입력합니다. (blog.mycodegear.com의 경우 blog만 입력)

- 레코드 유형은 CNAME을 선택합니다.

- 값은 AWS 리소스의 Alias값을 입력합니다.

- TTL은 default 값인 300초로 합니다.

- 라우팅 정책은 default 값인 단순 라우팅으로 합니다.

 

이렇게 하고 레코드 생성을 클릭하면 작성한 레코드가 추가되고,

생성된 domain을 브라우저에 입력하면 연결을 확인할 수 있습니다.

반응형
반응형

다음은 이 글의 동영상 강의입니다.

https://youtu.be/0YsMEPxi_wc

Github Desktop 5분컷 사용법

 

 

GIT 개념

여러곳에서 다른 컴퓨터로 개발을 하다보면 서로 소스가 맞지 않은 상황이 발생합니다.

소스 불일치

이때 GIT을 사용하면 소스를 여러곳에서 동기화 시킬수가 있습니다.

 

git 개념

여러사람이 동일한 프로젝트를 개발할 때도 Git을 통해 이런 문제를 해결할 수 있습니다.

 

github 초보자도 쉽게 사용할 수 있는 github desktop의 사용법을 알아보겠습니다.

 

Github 가입

우선 Git을 사용하시려면 아래 github 사이트에 가입을 해야합니다.

https://github.com/

 

GitHub: Where the world builds software

GitHub is where over 73 million developers shape the future of software, together. Contribute to the open source community, manage your Git repositories, review code like a pro, track bugs and feat...

github.com

회원 로그인 후 Repository를 만들기 위해 Your repositories로 이동합니다.

Your repositories

New 버튼을 클릭하고 새로운 Repository를 만듭니다.

New Repository

Repository 이름 "test"로 입력하고 하단의 "Create Repository" 버튼을 클릭합니다.

Create a new repository

아래와 같이 test repository가 만들어졌습니다.

test repository

 

Github Desktop 설치

 

아래 사이트에서 github desktop을 download 합니다.

https://desktop.github.com/

 

GitHub Desktop

Simple collaboration from your desktop

desktop.github.com

다운로드 버튼을 클릭합니다.

download

설치가 완료되면 아래와 같이 github desktop이 실행됩니다.

github desktop

소스 clone

github.com의 repository에서 code 버튼을 클릭

repository code

clone에서 url을 copy합니다.

clone

github desktop에서 add 버튼을 클릭하고 clone repository를 선택합니다.

clone repository

URL 탭을 클릭하고, github.com에서 복사한 주소를 붙여넣기 한 후, clone 버튼을 클릭합니다.

이때 local path 변경도 가능합니다.

clone a repository

test repository가 로컬에 clone 되었습니다.

 

소스를 수정하고 commit 하고 push하기

Open in Visual Studio Code를 선택하면 VSCode가 실행됩니다.

clone된 test repository

README.md 파일을 수정하고 저장합니다.

README.md

github desktop에 가시면 변경된 파일이 아래와 같이 표시됩니다.

중간에 변경내용 요약해서 작성해 주시고 ("update README.md"),

아래 commit 버튼을 클릭합니다.

commit

push origin을 클릭하시면 서버에 소스가 upload 됩니다.

push origin

github.com에 가시면 변경된 내용을 확인 할 수 있습니다.

github.com 변경내역확인

변경 소스 받기

이번에는 다른쪽에서 소스가 수정되었을 경우 테스트를 진행합니다.

github.com에서 파일을 하나 추가하기 위해 Add file 버튼을 클릭합니다.

Add file

파일 내용을 입력 후 Commit 버튼을 클릭합니다.

edit text

test.txt 파일이 생성된 것을 확인할 수 있습니다.

test.txt

github desktop에서 fetch origin을 선택합니다.

fetch origin

1개의 파일이 commit 되었음을 표시해줍니다. Pull origin 버튼을 클릭해서 소스를 pull(땡겨옴) 합니다.

Pull

VSCode를 열면 새로 추가된 test.txt 파일을 확인할 수 있습니다.

test.txt

이상으로 github desktop의 기본적인 사용법을 알아보았습니다.

반응형

+ Recent posts