🦁멋쟁이사자처럼 백엔드 부트캠프 13기 🦁
TIL 회고 - [101]일차
🚀101일차에는 프로젝트의 방향성을 확정하고 그 프로젝트에 맞게 기획서 및 정의서, ERD 설계 방법을 배움 (2025.05.08)
💡프로젝트명은 LoCo 프로젝트 - Location (공간) + Connect (연결)로 확정.
"공간을 잇고, 가치를 나누다"
도심 속 유휴 공간과 이를 필요로 하는 사용자들을 매칭하는 공간 기반 공유 서비스
ERD 수정내역 (v1 -> v2)


ERD 플랫폼 변경
ERDCloud.com ➡️ dbdiagram.io

서비스 배포에 사용되는 기술
- 주로 프론트엔드 Vercel
- 백엔드 AWS EC2 등 사용
프론트엔드 배포 기술
- Vercel: Next.js 개발팀이 만든 서비스로, Next.js 프로젝트 배포에 최적화
➡️서버리스 함수, 자동 스케일링 등을 편리하게 사용 - Netlify: Vercel과 유사하게 프론트엔드 배포에 특화된 서비스
➡️정적 사이트, SPA, 서버리스 기능 등을 지원 - AWS S3 + CloudFront: 정적 웹사이트 호스팅에 적합
➡️S3에 빌드된 파일을 올리고 CloudFront를 통해 CDN(Content Delivery Network)을 구성하여 빠르게 서비스 - AWS Amplify: 프론트엔드 및 모바일 앱 개발/배포를 위한 통합 서비스
➡️CI/CD, 백엔드 기능(인증, API 등) 연동까지 편리하게 지원 - AWS EC2 또는 컨테이너 서비스 (ECS, EKS): 전통적인 서버 방식
➡️EC2 인스턴스에 직접 Node.js 환경을 설정하고 Next.js 앱을 실행하거나, Docker 컨테이너화하여 ECS나 EKS에 배포 ➡️Vercel이나 Netlify보다 설정 및 관리가 복잡하지만, 더 많은 제어권을 가짐
백엔드 배포 기술
- Spring Boot와 관련하여 백엔드 애플리케이션은 AWS EC2 외에도 다른 옵션들도 존재
- AWS EC2: 가장 기본적인 가상 서버 인스턴스
➡️OS를 선택하고 직접 미들웨어(Java, Spring Boot 등)를 설치하여 애플리케이션을 실행 - AWS Elastic Beanstalk: 웹 애플리케이션 배포 및 관리를 자동화해주는 서비스
➡️코드만 올리면 환경 설정, 로드 밸런싱, 오토 스케일링 등을 자동으로 처리, EC2 위에 추상화된 형태 - AWS ECS (Elastic Container Service): 도커 컨테이너를 관리하고 배포하는 서비스
➡️EC2 인스턴스 클러스터 위에서 도커 컨테이너를 실행 - AWS EKS (Elastic Kubernetes Service): AWS에서 제공하는 관리형 쿠버네티스 서비스
➡️쿠버네티스 클러스터를 쉽게 구축하고 관리할 수 있으며, 대규모 컨테이너화된 애플리케이션 배포 및 관리에 용이 - AWS Lambda: 서버리스 함수 서비스
➡️짧게 실행되는 백엔드 로직을 함수 형태로 배포하고, 요청이 있을 때만 실행되어 비용이 효율적
Spring Boot 애플리케이션 전체를 Lambda로 배포하기에는 구조 변경 필요
❓백엔드 AWS EC2 배포 시 도커/쿠버네티스(무중단배포) 사용은 필수적인지
AWS EC2에 백엔드 애플리케이션을 배포할 때 도커나 쿠버네티스를 반드시 사용해야 하는 것은 아님
🔧도커나 쿠버네티스를 사용하지 않을때는 EC2 인스턴스에 접속하여 직접 Java, Spring Boot 실행 환경을 설치하고,
빌드된 Spring Boot JAR 또는 WAR 파일을 업로드하여 java -jar your-app.jar 와 같은 명령어로 직접 실행
Nginx나 Apache와 같은 웹 서버를 앞에 두고 리버스 프록시 설정도 가능 ➡️기본적인 배포 형태
🔧도커나 쿠버네티스를 사용할때는
➡️ 도커 사용 : 애플리케이션과 그 종속성을 컨테이너라는 독립적인 환경에 패키징하여 환경 일관성을 확보하고 배포를 표준화 가능, 여러 애플리케이션을 하나의 서버에 배포할 때 충돌을 방지하는데에 유용
➡️쿠버네티스: 도커와 같은 컨테이너화된 애플리케이션을 자동화된 방식으로 배포, 스케일링, 관리해주는 오케스트레이션 플랫폼
,여러 대의 서버(EC2 인스턴스 클러스터)에 걸쳐 애플리케이션을 효율적으로 분산시키고, 서비스 디스커버리, 로드 밸런싱, 자동 복구 등을 제공하여 안정성과 확장성을 향상
➡️소규모 프로젝트나 학습 목적으로는 EC2에 도커 없이 직접 배포하는 것도 가능하지만 프로젝트 규모가 커지고, 여러 대의 서버를 사용하며, 안정적인 운영과 확장이 중요해진다면 도커와 쿠버네티스를 사용하는 것이 권장
CI/CD (Continuous Integration / Continuous Deployment (or Delivery))
- 코드를 지속적으로 관리하고 배포하는 것의 약자
- 소프트웨어 개발 및 제공 과정을 자동화하여, 변경된 코드를 신속하고 빈번하게 테스트하고 프로덕션 환경에 배포하는 DevOps 방법론
- '지속적 통합(CI)' : 여러 개발자의 코드를 자동으로 병합하고 검증
- '지속적 배포(CD)' : 테스트가 완료된 코드를 자동으로 운영 환경에 릴리스하는 과정을 포함
때때로 '지속적인 제공'이라는 의미로 'Continuous Delivery' 라고 씀
Tailwind CSS
- 미리 정의된 유틸리티(Utility) 클래스들을 사용하여 HTML 코드 내에서 직접 스타일을 적용할 수 있게 해주는 CSS 프레임워크

- 이처럼 클래스명에 스타일을 정의하는 방법을 “테일윈드 tailwind” 기법
ex. grid, grid-rows, items-center ...
목적 :
- Tailwind는 특히 디자인 시스템을 빠르게 구축하거나, UI를 유연하게 커스터마이징해야 하는 프론트엔드 프로젝트에서 많이 사용
- 복잡한 UI를 직접 구현해야 할 때나, 기존의 컴포넌트 라이브러리 디자인이 마음에 들지 않을 때 유용
- CSS 파일을 관리하는 대신, HTML 파일에서 직접 스타일을 제어하여 개발 속도와 생산성을 크게 향상
CSS 프레임워크와 Tailwind CSS의 차이점
➡️일반적인 CSS 프레임워크(ex. Bootstrap)가 미리 만들어진 컴포넌트(버튼, 카드 등)를 제공하는 것과 달리,
➡️ Tailwind CSS는 flex, pt-4, text-center, bg-blue-500과 같은 원자 단위의 CSS 클래스를 제공
또한 Tailwind CSS는 CSS 파일을 직접 작성하는 대신, HTML 클래스 속성 안에 유틸리티 클래스들을 나열하는 방식으로 사용
1. HTML + 일반 CSS 방식
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<button class="my-button">버튼</button>
</body>
</html>
.my-button {
display: flex;
align-items: center;
justify-content: center;
padding: 1rem 2rem;
border-radius: 0.5rem;
background-color: #3b82f6;
color: #ffffff;
font-size: 1rem;
}
2. Tailwind CSS 사용
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<button class="flex items-center justify-center p-4 rounded-lg bg-blue-500 text-white text-base">
버튼
</button>
</body>
</html>
- button class = "flex items-center..." 처럼 사용
Git에서 일반 Merge와 Squash Merge의 차이점
🔄️일반 Merge의 Git Flow

1. main 브랜치의 흐름에서 기능을 개발할 feature/#1 브랜치를 생성
2. feature/#1 의 커밋 내역들 F1, F2, F3, F3(수정) 등 이 각각 존재
2-1) 예를들어
feature/#1 브랜치에서 첫번째 기능을 개발 (F1) - 첫번째 커밋 : "feat: add a button" = 버튼 추가
두번째 기능을 개발 (F2) - 두번째 커밋 : "fix: fix button style" = 버튼 스타일 수정
세번째 기능을 개발 (F3) - 세번째 커밋 : "refactor: modify button logic: = 버튼 로직 정리
3. 이제 이 F1, F2, F3 기능 개발한 것들이 feature/#1 브랜치에서는 내역이 실려있는데 main 브랜치에는 반영이 되지 않은 상태
4. 이 경우 Pull Request를 통해 feature/#1 브랜치의 작업 내역을 main 브랜치에 병합해도되는지에 대한 요청
5. 이 PR (Pull Request)가 승인되면 일반 Merge가 실행되는데 이때 main 브랜치에 Merge Commmit (M4)가 새로 생성되는 흐름
장점 : 개발 과정의 완전한 기록과 원본 브랜치 복원 용이
단점 : 히스토리가 복잡해지고 불필요한 커밋이 많아질 수 있음
.
🔄️SquashMerge의 Git Flow
- feature/#1의 각각의 커밋내역들이 하나로 뭉쳐져서 병합되는 것이 Squash Merge
- Squash Merge의 장점은 깔끔해지는 것
- feature/#1 같은 브랜치는 “하나의 기능”을 커밋한 것이기때문에 하나로 합쳐서 병합하는 것이 좋다고 느낄때 사용

1. 브랜치 생성 및 작업: feature/#1 브랜치가 main 브랜치에서 생성되고, 그 위에서 F1, F2, F3 커밋이 순차적으로 발생
(공통점 : 일반 Merge와 동일한 브랜치 생성 및 작업)
2. Pull Request (PR): 작업 완료 후 PR을 생성하여 통합을 요청
3. Squash Merge: PR이 승인되고 Squash Merge가 실행
- feature/#1의 모든 커밋 F1, F2, F3이 하나의 새로운 커밋 S1으로 통합
- 이후 이 단일 커밋 S1이 main 브랜치에 추가
4. 히스토리 결과: main 브랜치의 히스토리에는 F1, F2, F3의 개별 흔적 없이, 오직 하나의 깔끔한 커밋 S1만 남음
(차이점 : Merge Commit이 생성되지 않음. (단일 커밋으로 처리))
장점 : main 브랜치 히스토리가 깔끔하고 이해하기 쉬움
단점 : 세부 작업 과정을 잃어버리고 원본 브랜치 히스토리가 main 브랜치와 분리됨
❓일반 Merge vs Squash Merge 명령어 비교
| 구분 | 일반 (Standard) Merge | Squash Merge |
| 명령어 | git merge <브랜치명> |
git merge --squash <브랜치명>
|
| 결과 | Merge Commit 생성 |
변경 사항이 Staged 상태로 들어옴
|
| 커밋 필요 여부 | 자동으로 커밋됨 (별도 git commit 불필요) |
수동으로 커밋해야 함 (필수)
|
| 히스토리 | feature 브랜치의 모든 커밋을 남기고 Merge Commit 추가 |
feature 브랜치 커밋들을 하나로 합쳐 새 커밋으로 추가
|
일반 Merge 로직
# main 브랜치로 이동
git checkout main
# feature 브랜치를 main에 병합 (Merge Commit 자동 생성)
git merge feature/#1
Squash Merge 로직
# main 브랜치로 이동
git checkout main
# feature 브랜치의 모든 변경사항을 하나의 작업으로 가져와 Staged 상태로 만듦
git merge --squash feature/#1
# 수동으로 커밋 (이 때 하나의 커밋이 생성됨)
git commit -m "feat: feature/#1 커밋이 Squash Merge"
- main 브랜치의 히스토리는 '누가', '어떤 기능'을 넣었는지에 대한 '요약'만으로 충분
- 복잡한 개발 과정의 세부 내용은 해당 PR 페이지나 feature 브랜치에 남겨두고,
- main 브랜치는 오직 중요한 기능 단위로만 깔끔하게 기록
결론 :
- 오픈 소스 프로젝트, 라이브러리에서는 Squash Merge 또는 Rebase Merge가 선호
>> main 브랜치의 히스토리를 깔끔하고 선형적으로 유지하여 추적에 용이
- 규모가 크고 복잡한 엔터프라이즈 앱에서는 일반 Merge (Merge Commit)가 선호
>> 특정 릴리스 브랜치나 버그 픽스의 병합 시점 자체를 중요하게 기록하고, 히스토리의 완전한 복원이 필수적일 때 사용
💡Rebase Merge
- GitHub에서 제공하는 'Rebase and Merge' 옵션을 사용하여 main 브랜치에 통합이 가능
(자동으로 Rebase를 처리하고 Fast-forward Merge를 수행)

- feature/#1 브랜치 커밋들 F1, F2, F3을 main 브랜치의 최신 커밋 M4 위에 재배치(Rebase)
- 이 과정에서 새로운 커밋 ID를 가진 커밋들 F1', F2', F3'이 생성
- 이후 main 브랜치는 Fast-forward 방식으로 통합되어 선형 히스토리를 만듦
Rebase Merge 로직
# 1. 브랜치 이동 후 Rebase
git checkout feature/#1
git rebase main
# 2. 병합 (Merge) - Fast-forward
git checkout main
git merge feature/#1
- 결과
- main 브랜치의 끝에 feature 브랜치의 모든 커밋(F1', F2', F3')이 합쳐짐
- Merge 단계에서 자동으로 커밋 (Fast-forward)
- Merge Commit 없이, feature의 모든 커밋이 선형적으로 이어진 히스토리
장점 : 선형 히스토리의 장점과 세부 커밋 보존의 장점을 모두 갖추고 있어, 핵심 브랜치(main/master) 통합 전략으로 매우 선호
단점 :
- Rebase 시 커밋 ID가 모두 바뀌어, 이미 원격 저장소에 푸시된 브랜치에 적용하면 협업자들에게 심각한 문제 야기
- 충돌 해결의 어려움: 병합 시 발생할 충돌을 각 커밋이 Rebase될 때마다 해결해야 함
⚠️주의사항 :
- 이미 다른 사람이 작업하는 공용 브랜치에 로컬 git rebase 명령 직접 사용하지 않기
- PR단계에서 Github 플랫폼의 기능을 이용하는 방식 권장
❓Squash Merge vs Rebase Merge
| 특징 | Squash Merge | Rebase Merge |
| 최종 커밋 개수 | 단 하나의 커밋 (압축/요약) |
원본 커밋 개수 (F1′,F2′,F3′)
|
| 히스토리 형태 | 선형적 (하나의 커밋으로 인해) |
선형적 (모든 커밋이 순차적으로 이어짐)
|
| 원본 커밋 보존 | main 브랜치에서 사라짐 (단일 커밋으로 요약) |
main 브랜치에서 보존됨 (새 ID로 재생성)
|
| 커밋 ID 변경 | 새로운 단일 커밋 ID 생성 |
Rebase 시 모든 커밋 ID가 변경됨
|
git fetch
- 로컬(IDE 환경)에서 원격 환경(GitHub 등)의 최신 변경 사항을 확인하고 비교하는 데 사용되는 핵심 명령어
- 즉 로컬 저장소를 훼손하지 않고 원격 저장소(origin 등)의 최신 정보를 조회하고 다운로드하는 명령어
(= 원격 저장소의 최신 브랜치, 커밋, 태그 등의 정보만 가져와서 로컬에 업데이트) - 병합(Merge)기능이 아니므로 로컬 작업 공간(Working Directory)이나 로컬 브랜치의 내용은 전혀 변경되지 않음
- git fetch를 실행하면, 로컬 저장소는 원격 저장소의 최신 상태를 알게되는 것
git fetch origin
- 명령어를 실행하게되면 로컬의 remotes/origin/main 브랜치가 GitHub의 main 브랜치 최신 커밋을 가리키게됨
- 로컬 IDE나 CLI 명령(git log, git status)을 통해 현재 작업 중인 로컬 브랜치와 원격의 최신 상태인 원격 추적 브랜치 간의
차이점(ex. 몇 개의 커밋이 뒤처져 있는지)을 쉽게 비교 가능
장점 : 병합 충돌이나 작업 내용 유실 없이 안전하게 최신 정보만 확인 가능
fetch --prune 옵션
git fetch --prune
- 원격에서만 지우고 로컬의 브랜치는 지우지 못했을때 원격의 지워진 브랜치를 로컬도 동기화시켜주는 기능 (로컬자동삭제)
- 즉 두 브랜치를 맞춰주는 명령어
❓git fetch vs git pull
| 명령어 | 기능 | 결과 (로컬 브랜치) |
| git fetch | 가져오기만 수행 (정보 다운로드) | 변경 없음 (origin/<branch>만 업데이트) |
| git pull | 가져오기 + 병합 수행 (정보 다운로드 후 로컬 브랜치에 통합) |
업데이트 및 변경 (원격 내용이 로컬 브랜치에 병합됨) |
따라서 로컬 브랜치와 원격 브랜치의 작업을 비교/확인 하는 방법이 3가지
1. 최신 정보 확인만 수행
git fetch
2. 확인 후 로컬 브랜치에 병합
# (fetch + merge와 동일)
git pull
3. fetch 후 수동으로 병합 (안전한 통합)
git fetch
git merge origin/main # 또는 git rebase origin/main
git branch
- 브랜치 관련 역할을 수행할 수 있는 Git 명령어
git branch -D feature/#1
- -D 옵션 : 브랜치 지우는 명령어
❓원격과 로컬의 브랜치를 맞춰주는 방법

1. 원격 브랜치가 삭제되었을때 로컬에서도 삭제하려면 (⭐권장)
git fetch --prune
2. 원격 브랜치는 삭제하지 않았지만 로컬에서 로컬 브랜치 삭제 후 원격 저장소에 push하게되면
로컬에서 로컬 브랜치가 삭제된 것이 원격 저장소의 원격 브랜치에 반영
🚀회고 결과 :
Git 명령어에 대해 흐름에 따라 공부하여 협업 환경에서의 원활한 프로젝트 구현에 도움이 될 수 있도록 노력했다.
git 명령어의 fetch, merge, pull, branch 등에 대해 개념을 제대로 이해하고 팀 프로젝트를 시작하는 것이 중요할 것 같았다.
'Recording > 멋쟁이사자처럼 BE 13기' 카테고리의 다른 글
| [멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_103일차_"Git Projects 이슈 관리 및 게시판 Board" (0) | 2025.11.18 |
|---|---|
| [멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_102일차_"Git 협업 및 CI 구축" (0) | 2025.11.06 |
| [멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_100일차_"2차 팀 프로젝트 시작" (0) | 2025.05.22 |
| [멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_99일차_"1차 블로그 프로젝트 마무리" (0) | 2025.05.22 |
| [멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_96일차_"블로그 프로젝트의 에디터 도입" (2) | 2025.05.21 |