배포 환경 설정

 

안정적이고 효율적인 배포를 위해 환경 설정, 배포 계획, 버전 관리, 자동화, 배포 전략, 모니터링 및 롤백 계획 등을 포함한

소프트웨어를 운영 환경에 배포하는 과정과 관련된 설정 및 관리 절차이다. 


  • 환경 정의: 개발, 테스트, 스테이징, 운영 등 각 환경의 목적과 역할을 명확히 한다. 각 환경은 소프트웨어 개발과 배포의 다른 단계에서 사용헌다. 예를 들어, 개발 환경에서는 새로운 기능을 시험하고, 테스트 환경에서는 기능의 안정성을 검증하며, 스테이징 환경에서는 운영 환경과 유사한 조건에서 최종 테스트를 수행한다.
  • 환경 구성: 각 환경에 필요한 서버, 데이터베이스, 네트워크 설정 등을 정의한다. 서버 사양, 데이터베이스 버전, 네트워크 대역폭 등도 포함된다. 이러한 설정은 각 환경이 예상대로 작동하도록 보장한다.
  • 환경 차별화: 환경 간의 설정이나 데이터가 다를 수 있으며, 이를 효과적으로 관리하기 위해 환경별로 설정 파일이나 변수를 구분하여 관리한다. 예를 들어, 데이터베이스의 접속 정보나 API 키가 각 환경에 맞게 다를 수 있다.

배포 계획

배포 계획은 소프트웨어를 실제 환경에 배포하는 방법과 절차를 설정하는 것이다.

  • 배포 일정: 배포가 이루어질 날짜와 시간을 계획한다. 정기적인 배포 일정(예: 매월 첫 번째 월요일)과 특정 이벤트(예: 주요 기능 출시) 등에 맞춰 배포 일정을 수립한다.
  • 배포 방법: 자동 배포와 수동 배포 중 적절한 방법을 선택한다. 자동 배포는 자동화된 도구를 통해 배포를 수행하며, 수동 배포는 수동으로 파일을 전송하고 설정을 변경하는 방식이다.
  • 배포 절차: 배포 단계별로 필요한 작업을 정의한다. 데이터베이스 마이그레이션, 애플리케이션 재시작, 캐시 무효화, 로그 분석 등 배포 후 해야 할 작업을 포함한다.

버전 관리

버전 관리는 소프트웨어의 버전을 체계적으로 관리하여, 배포와 유지보수 과정에서 혼란을 줄이는 것이다.

  • 버전 번호: 각 배포에 대한 고유한 버전 번호를 설정하여, 소프트웨어의 특정 버전을 추적하고 관리한다. 메이저, 마이너, 패치 번호를 포함한 형식(예: 1.0.0, 1.1.0, 1.1.1 등)을 사용한다.
  • 릴리즈 노트: 새로운 버전에서의 주요 변경 사항, 버그 수정, 기능 추가 등을 문서화하여 팀원과 사용자들에게 전달한다. 릴리즈 노트는 사용자 문서화, 기술 문서화 두 가지로 나뉜다.
  • 버전 호환성: 새로운 버전이 이전 버전과 호환되는지 검토한다. 필요한 경우 데이터베이스 스키마 변경, API 수정 등을 포함한 데이터 변환 작업을 수행한다.

자동화 및 도구

자동화된 배포와 관리 도구는 배포 과정의 효율성을 높이고 오류를 크게 줄일 수 있다.

  • CI/CD 도구: Jenkins, GitLab CI/CD, CircleCI 등과 같은 도구를 사용하여 자동화된 배포 파이프라인을 구축한다. 이 도구들은 코드 변경 시 자동으로 빌드, 테스트, 배포를 수행한다.
  • 배포 스크립트: 배포 작업을 자동으로 수행하기 위해 스크립트를 작성한다. 예를 들어, 배포 스크립트는 서버에 소프트웨어를 설치하고 구성하는 작업을 포함할 수 있다.
  • 컨테이너 오케스트레이션: Docker와 Kubernetes를 사용하여 애플리케이션을 컨테이너화하고 관리한다. 컨테이너는 소프트웨어의 종속성과 환경을 일관되게 유지할 수 있다.

배포 전략

배포 전략은 새로운 버전을 기존 시스템에 도입하는 방법을 정의한다.

  • 블루-그린 배포: 두 개의 환경(블루와 그린)을 사용하여, 현재 운영 중인 환경(블루)과 새로운 버전이 배포된 환경(그린)을 구분한다. 새로운 버전이 준비되면 트래픽을 새로운 환경으로 전환한다. 이 방법은 배포 과정 중 시스템 중단을 최소화한다.
  • 롤링 업데이트: 시스템의 일부 인스턴스씩 점진적으로 업데이트하여 전체 시스템의 가용성을 유지한다. 이 방법은 새로운 버전이 모든 인스턴스에 걸쳐 점진적으로 배포된다.
  • 카나리 배포: 새로운 버전을 소수의 사용자에게 먼저 배포하여 안정성을 검토한 후, 전체 사용자에게 배포한다. 초기 사용자로부터 피드백을 받아 문제가 없는지 확인하는 데 유용하다.

모니터링과 롤백 계획

배포 후 시스템 상태를 모니터링하고, 문제가 발생할 경우 신속하게 대응할 수 있는 계획을 세운다.

  • 모니터링: 배포 후 시스템의 성능, 오류 로그, 사용자 피드백 등을 실시간으로 모니터링한다. 이를 통해 배포 후 문제가 발생하는 경우 조기에 발견하고 대응할 수 있다.
  • 롤백: 문제가 발생했을 때 신속하게 이전 버전으로 되돌릴 수 있는 절차와 도구를 마련한다. 롤백은 자동화된 스크립트와 수동 절차가 포함된다.
  • 비상 대응 계획: 배포 실패나 문제 발생 시 신속히 대응할 수 있는 비상 대응 절차를 준비한다. 이 절차는 문제를 해결하기 위한 단기 및 장기 계획을 포함한다.

테스트 및 검증

배포 전후에 소프트웨어의 품질과 기능을 검증하여 문제가 없는지 확인한다.

  • 유닛 테스트: 개별 코드 단위의 기능을 테스트하여 코드의 정확성과 안정성을 검증한다. 유닛 테스트는 코드의 각 구성 요소가 예상대로 작동하는지 확인한다.
  • 통합 테스트: 여러 시스템 모듈이 함께 작동하는지 확인하여 시스템 전체의 상호작용과 호환성을 검증한다. 통합 테스트는 시스템 간의 상호작용과 데이터 흐름을 테스트한다.
  • 사용자 수용 테스트(UAT): 실제 사용자가 소프트웨어를 사용해보고 요구 사항을 충족하는지 확인한다. UAT는 소프트웨어가 사용자 기대를 충족하는지 확인하는 중요한 단계이다.

문서화

배포 과정과 설정을 문서화하여 팀원들이 이해하고 따를 수 있도록 한다.

  • 배포 문서: 배포 계획, 절차, 변경 사항 등을 상세히 문서화하여 팀원들과 이해 관계자들이 참고할 수 있게 한다. 이 문서화 과정은 나중에 문제 해결이나 배포 복구에 유용하다.
  • 문서 업데이트: 배포가 완료된 후, 모든 변경 사항과 배포 결과를 문서화하여 이후 참고할 수 있도록 한다. 문서 업데이트는 배포 결과를 기록하고 미래의 배포에 대한 교훈을 제공하는 데 도움을 준다.

'CS > DEPLOY' 카테고리의 다른 글

MicroService Architecture MSA  (0) 2024.08.14
git flow 전략  (0) 2024.08.14
도커 사용해보기  (0) 2024.07.17

모놀리식 아키텍처의 한계

모놀리식 아키텍처(monolithic architecture)는 소프트웨어 개발에서 사용하는 전통적인 아키텍처 스타일 중 하나로, 애플리케이션의 모든 기능이 하나의 단일 코드베이스와 실행 환경에서 통합되어 있는 구조이다. 여기서 "모놀리식"은 "하나로 되어 있는"이라는 뜻으로, 애플리케이션의 모든 구성 요소가 단일한 단위로 묶여 있다는 의미이다.

 

모놀리식 애플리케이션은 서버, 클라이언트, 데이터베이스로 구성된다. 서버는 클라이언트 요청을 처리하고, 비즈니스 로직을 구현하며, 데이터베이스에 데이터를 저장하거나 수집하고, 클라이언트에게 응답한다. 이는 하나의 실행 파일 애플리케이션 시스템으로, 모든 변경은 시스템의 새로운 버전을 초래한다.

 

처음 개발하고 배포할때는 WAR 파일만 배포하면 되기 때문에 간단하지만, 모든 기능이 하나의 프로젝트에 통합되어 있어

시스템을 유지보수하기가 어렵고 의존성이 높다는 문제점이 있었다.

 

 

  • 스케일링의 어려움: 모놀리식 애플리케이션은 모든 기능이 단일 코드베이스와 프로세스에서 실행된다.
  • 이로 인해 시스템이 커지면서 스케일링이 어렵고, 전체 애플리케이션을 재배포해야 하는 불편이 있다.
  • 서비스 안정성: 모놀리식 아키텍처에서는 하나의 서비스 장애가 전체 시스템에 영향을 미칠 수 있다.
  • CI/CD 도입: 지속적인 통합 및 지속적인 배포(CI/CD)와 같은 지원하기 위해 서비스 단위로 배포하고 업데이트하는 방식이 필요해졌다.

클라우드 환경과 컨테이너 기술(Docker, Kubernetes 등)의 발전은 서비스의 독립적인 배포와 관리, 스케일링을 더 용이하게 만들어 MSA를 도입시켰다.

마이크로서비스 아키텍처(MicroService Architecture, MSA)

소프트웨어 개발에서 애플리케이션을 작은 독립적인 서비스들로 나누어 구성하는 아키텍처 스타일이다.

단일 전체 서버 프로그램과 전용 데이터 저장소를 만드는 대신, 여러 개의 마이크로 프로그램이 특정 서비스를 제공하며 이를 마이크로서비스라고 한다. 각 서비스는 특정 비즈니스 기능을 수행하며 독립적으로 배포되고 운영된다.

 

독립적인 서비스 애플리케이션을 여러 개의 작은 서비스로 나누어
각 서비스가 특정 비즈니스 기능이나 도메인에 초점을 맞춤. 독립적으로 개발, 배포, 확장, 관리 가능.
서비스 간 통신 서비스 간에는 API(주로 RESTful API, gRPC 등)를 통해 통신하며
각 서비스는 정의된 인터페이스를 사용하여 상호작용한다
자율적 배포 각 서비스는 독립적으로 배포할 수 있어, 서비스 업데이트와 배포가
전체 애플리케이션에 영향을 미치지 않고 진행됨.
데이터 관리 각 서비스는 독립적인 데이터 저장소를 가지며, 데이터 관리와 접근이 서비스 단위로 이루어짐.

 

각 서비스는 자체 실행 프로세스를 갖고, 독립적인 데이터 저장소를 가질 수 있다.

서로 다른 마이크로서비스는 서로 다른 프로그래밍 언어와 데이터베이스 접근 방식을 사용할 수 있으며,

독립적으로 배포될 수 있다.

 

다양한 팀이 특정 서비스에 대해 작업하며, 업데이트는 전체 시스템이 아닌 영향을 받은

마이크로서비스에 대해서만 이루어진다. 오류가 발생하더라도 영향을 받은 서비스만 실패하고

나머지 프로그램은 정상적으로 작동한다.


 특징

모듈화 애플리케이션이 독립적인 서비스로 나뉘어 각 서비스가 특정 기능을 담당함.
자율성 각 서비스는 독립적으로 개발, 배포, 운영 가능.
기술 다양성 각 서비스가 서로 다른 기술 스택과 도구를 사용할 수 있음.
스케일링 개별 서비스는 필요에 따라 독립적으로 스케일링 가능.
장애 격리 서비스가 독립적으로 운영되어 장애가 전체 시스템에 미치는 영향 최소화.
기민한 대응 서비스 단위로 빠르게 업데이트 및 배포 가능.

단점

 
복잡한 관리 많은 서비스와 상호작용을 관리해야 하며, 시스템 복잡성이 증가
서비스 간 통신 비용 네트워크를 통한 서비스 간 통신으로 성능 오버헤드와 지연이 발생
데이터 관리의 복잡성 각 서비스가 독립적인 데이터 저장소를 사용하므로 데이터 일관성 유지가 어렵다
배포 및 테스트의 복잡성 여러 서비스를 동시에 배포하고 테스트하는 과정이 복잡하다
일관된 보안 관리 서비스가 독립적으로 운영되기 때문에 일관된 보안 정책 적용이 어렵다
  • 레거시 애플리케이션 리팩토링: 기업은 레거시 코드를 리팩토링하거나 새로운 기술로 이동할 필요가 있다. 마이크로서비스는 시스템을 재구성하거나 새로운 기능을 추가하거나 새로운 기술 스택으로 이동할 때 선호되는 아키텍처이다.
  • 빅데이터, AI/ML: 빅데이터, 인공지능, 머신러닝 등과 같은 기술을 사용하는 애플리케이션은 복잡한 데이터 파이프라인이 필요하다. 이러한 경우, 모놀리식 설계는 시스템을 무겁고 관리하기 어렵게 만들 수 있기 때문에 분산 시스템 아키텍처가 더 나은 옵션이다.
  • 실시간 데이터 처리: Netflix와 같은 스트리밍 플랫폼, Twitter와 같은 게시-구독 패턴 앱은 비동기 통신과 실시간 데이터 분석을 제공하기 위해 마이크로서비스 아키텍처를 사용한다.
  • DevOps: DevOps와 마이크로서비스를 함께 사용할 때, 매우 효율적이다. 개발과 운영에 동일한 도구 세트를 채택함으로써 DevOps 팀이 더 효율적으로 작업할 수 있다.

마이크로서비스 개발 도구와 기술

마이크로서비스 아키텍처의 인기가 높아짐에 따라, 이를 지원하고 개발자 경험을 개선하기 위한 다양한 도구와 기술이 등장했다.

 

컨테이너화

마이크로서비스는 독립적으로 운영되며, 자체 런타임 환경을 가진 격리된 환경에서 유지되어야 한다. Docker, AWS BottleRocket 등의 컨테이너화 서비스가 이를 가능하게 한다.

 

API 관리

마이크로서비스의 수가 많아지면서, 안전한 연결을 설정하는 데 어려움이 있었다. AWS API Gateway, Azure API Management 등은 API 연결을 구축하고 관리하는 데 도움이 된다

 

지속적 통합 및 배포 (CI/CD)

마이크로서비스 아키텍처를 채택하면, 각 팀이 대기하지 않고도 빠르게 배포할 수 있어야 한다. Jenkins, AWS CodePipeline 등의 CI/CD 플랫폼이 자동화된 고속 배포를 제공한다.

 

애플리케이션 성능 모니터링 (APM) 도구

시스템 성능을 모니터링하여 사용자 유지와 시스템의 결함 및 병목 현상을 개선할 수 있다.

AWS Cloudwatch, Kibana 등의 솔루션이 있다.

 

클라우드 제공자

여러 마이크로서비스를 관리하기 위해 많은 컨테이너, API 관리 도구, 데이터베이스, CI/CD, 성능 모니터링 도구 등이 필요하다. AWS, Azure, IBM 등의 클라우드 서비스 제공자가 이를 통합하여 제공한다.

마이크로서비스를 구축하기 위한 일반적인 패턴

마이크로서비스를 구축하기 위해 다양한 디자인 패턴이 있으며, 각 패턴은 서로 다른 문제를 해결한다.

 

데이터베이스 아키텍처

각 서비스에 대해 별도의 데이터베이스를 만드는 것이 현실적인 해결책이며, 이는 확장성을 개선한다.

그러나 여러 서버의 데이터를 연결하는 검색은 복잡할 수 있다.

 

API 게이트웨이

클라이언트 애플리케이션에 마이크로서비스를 제공하는 것은 어렵다.

API 게이트웨이를 사용하여 모든 클라이언트 요청을 적절한 마이크로서비스로 라우팅할 수 있다.

 

액세스 토큰

API 게이트웨이를 통해 클라이언트 요청을 전달할 때, 요청자의 신원을 엑세스 토큰을 사용하여 서비스에 전달하는 것이 필요하다. 

 

로그 집계

요청이 여러 서비스 인스턴스에 걸쳐 있을 때, 중앙 집중식 로깅 서버가 각 서비스 인스턴스의 로그를 수집하는 것이 좋다. 이를 통해 오류를 더 쉽게 디버깅할 수 있다.

 

헬스 체크 API

서비스 인스턴스가 요청을 처리할 수 있는지 확인하기 위해 헬스 체크 API 엔드포인트를 포함하는 것이 중요하다.

 

 

'CS > DEPLOY' 카테고리의 다른 글

Release Deployment Configuration (소프트웨어 배포)  (0) 2024.08.15
git flow 전략  (0) 2024.08.14
도커 사용해보기  (0) 2024.07.17

Git Flow 전략

  • 메인 브랜치 (Main Branch)
    • main 또는 master 브랜치라고도 하며, 프로덕션에 배포된 안정적인 코드가 포함된다.
  • 개발 브랜치 (Develop Branch)
    • develop 브랜치는 개발 중인 기능이 통합되는 브랜치로, 새로운 기능 개발이 완료된 후 main 브랜치에 병합된다.
  • 기능 브랜치 (Feature Branch)
    • feature/ 접두사를 사용하여 생성되며, 새로운 기능 개발을 위한 브랜치이다. develop 브랜치에서 파생되어 작업이 완료된 후 develop 브랜치에 병합된다.
  • 릴리즈 브랜치 (Release Branch)
    • release/ 접두사를 사용하여 생성되며, 릴리즈 준비를 위한 브랜치이다. 기능이 완료된 후 릴리즈 브랜치를 통해 최종 버그 수정과 테스트를 수행하며, 완료되면 develop 및 main 브랜치에 병합된다.
  • 핫픽스 브랜치 (Hotfix Branch)
    • hotfix/ 접두사를 사용하여 생성되며, 프로덕션 환경에서 발견된 긴급한 문제를 수정하기 위한 브랜치이다.
    • 수정이 완료되면 main 및 develop 브랜치에 병합된다.

뭔가를 배포하거나 개발을 할때는 Develop이 Baseline이 되고
운영 중에 뭔가 급하게 고쳐야될 때 Master 브랜치에서 Hotfix 브랜치로

개발이 완료 된 후에는 release 브랜치에서 QA를 거쳐서 문제가 없을 경우 main 브랜치에 배포

 

Epic Branch

  • Epic Branch는 여러 기능(Feature Branch)을 포함하는 큰 작업 단위이다.
  • 특정 프로젝트나 큰 기능을 나타내며, 여러 개의 기능 브랜치를 포함하여 작업을 진행한다.
  • 생성: Epic Branch는 일반적으로 epic/ 접두사를 사용하여 생성된다.
  • 예를 들어, epic/user-authentication이라는 브랜치를 생성한다.

1. 주요 기능 또는 큰 작업이 정의되면 develop 브랜치에서 Epic Branch를 생성한다.

git checkout develop
git checkout -b epic/user-authentication

 

2. Epic Branch에서 필요한 여러 기능을 구현하기 위해 기능 브랜치를 생성한다.

예를 들어, epic/user-authentication 브랜치에서 feature/login과 feature/registration 브랜치를 생성하여

각각의 기능을 개발한다.

git checkout epic/user-authentication
git checkout -b feature/login
git checkout epic/user-authentication
git checkout -b feature/registration

 

3. 각 기능 브랜치에서 작업이 완료되면 Epic Branch로 병합한다.

# 기능 브랜치에서 작업 후
git checkout epic/user-authentication
git merge feature/login
git merge feature/registration

 

4. Epic Branch에서 모든 기능이 완료되면, Epic Branch를 develop 브랜치에 병합하여 전체 기능을 통합한다. 

git checkout develop
git merge epic/user-authentication

 

5. 이후, 릴리즈 준비가 완료되면 develop 브랜치에서 릴리즈 브랜치를 생성한다.

git checkout develop
git checkout -b release/1.0

 

 

 

 

 

 

'CS > DEPLOY' 카테고리의 다른 글

Release Deployment Configuration (소프트웨어 배포)  (0) 2024.08.15
MicroService Architecture MSA  (0) 2024.08.14
도커 사용해보기  (0) 2024.07.17

springboot 프로젝트를 Docker로 내보내 실행시켜보자!

도커(Docker) 는 컨테이너 기반 가상화 플랫폼으로
응용 프로그램과 그 종속성을 컨테이너로 패키징하여 실행하는 기술이다.
이를 통해 응용 프로그램을 서로 다른 환경에서도 
(ex) mac, window, linux... 같은 다른 운영체제 같은 경우에도 실행할 수 있고
개발 환경과 운영 환경 사이의 차이로 인한 문제를 줄일 수 있다.
도커 컨테이너는 가볍고 빠르며 확장성이 좋아 개발 및 배포 프로세스를 간소화하는데 사용된다.

 

!!우선 기본적으로 dockerHub 가입과 Docker 설치가 되어있어야 함!!

1. 배포하고싶은 springboot파일에 Dockerfile을 작성한다

(확장자는 없어도 된다)

 

스크린샷 2024-07-13 235003스크린샷 2024-07-13 235012

//jdk 17기반
FROM openjdk:17

//Docker 이미지가 빌드될때마다 프로젝트를 빌드하여 최신 코드로 업데이트
CMD ["./gradlew", "clean", "build"]

//build.libs 경로에 있는 모든 JAR 파일 들을 도커에 빌드
ARG JAR_FILE_PATH=build/libs/*.jar 

//build/libs에 있는 JAR 파일을 Docker 이미지의 app.jar로 복사
COPY ${JAR_FILE_PATH} app.jar

//Docker 컨테이너가 실행되면 java -jar app.jar 명령어 실행하여 spring boot 실행
ENTRYPOINT ["java", "-jar", "app.jar"]

Maven Wrapper, Gradle Wrapper

기존에는 Maven 과 Gradle을 로컬에 설치해서 사용했다. 
하지만 이런 방식으론 시스템의 버전과 프로젝트의 요구 버전이 다른 경우 충돌이 나기 때문에
프로젝트에 내장된 gradle, maven wrapper을 사용하는 것이다.

비슷한 예로, 톰캣 같은 경우엔 예전에 JSP, SERVLET 같은 웹 프로젝트에서 외장 톰캣을 사용했다면 (war) 
설치에 번거로움이 있어 자유도를 포기하는 대신 JRE만 있어도 구동 가능한 내장 톰캣(jar)을 사용하기 시작했다.

마음대로 골라 만들 수 있는 레시피 ---> 밀키트 같은 거라고 이해하고 있다...

2. docker image에 담을 spring boot .jar 파일을 생성한다.

스크린샷 2024-07-14 001725

 

bootJar 실행이 완료되면 build/libs 폴더에 jar 파일이 생성된다.

 

스크린샷 2024-07-14 001749

bootJar과 jar의 차이

jar: 일반적인 jar 파일. Gradle 또는 Maven 프로젝트에서 만들 수 있으며 
	자바 클래스 파일과 리소스 파일을 포함한다.
      이 JAR 파일은 실행 가능한 형태가 아니기 때문에 
      pom.xml 이나 gradle.build에 메인 클래스를 명시해야한다.

bootJar: 스프링 부트에서 제공하는 JAR 파일. 
	내장 서버(Tomcat, Jetty, Undertow.. 등) 를 사용하여 실행 가능한 JAR 파일이다.
        이 JAR 파일은 스프링 부트의 자동 설정 기능을 통해 
        실행 가능한 형태로 패키징되기 때문에
        별도의 서버 설치 없이도 애플리케이션을 실행할 수 있다.

3. Dockerhub에 repository를 만든다

https://hub.docker.com/

스크린샷 2024-07-14 002415

4. cmd로 dockerfile이 있는 경로에 들어가 도커 이미지를 build 한다

윈도우 기준이므로 맥은 조금 다를 수 있음

1. 해당 dockerfile이 있는 springboot 프로젝트로 들어가기

스크린샷 2024-07-14 003323

cd (본인 dockerfile이 있는 경로)

2. 도커 이미지 build

스크린샷 2024-07-14 003327

docker build -t dockerId/dockerHubRepository이름 .

3. 만들어놓은 도커 허브 repository에 이미지 push

스크린샷 2024-07-14 003336

docker push dockerId/dockerHubRepository이름

4. 도커 허브에서 이미지 가져와서 컨테이너 구동

docker run -p 8080:8080 도커허브ID/이미지이름

로컬에서 설정된 포트로 접근하기 위해 포트 매핑 후 컨테이너를 구동시켜준다.
포트번호 8080은 기본 포트번호기 때문에 만약 포트번호를 따로 설정해주었다면 바꿔줘야한다.
만약 만든 도커 이미지가 있을 경우 삭제
docker rmi 이미지ID/이미지이름

5. 성공!!

스크린샷 2024-07-13 234833

'CS > DEPLOY' 카테고리의 다른 글

Release Deployment Configuration (소프트웨어 배포)  (0) 2024.08.15
MicroService Architecture MSA  (0) 2024.08.14
git flow 전략  (0) 2024.08.14

+ Recent posts