Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
515817e
feat: 서브도메인 통일위해 cors 설정 수정
TwoMuchSilver Feb 3, 2026
ceec595
Merge remote-tracking branch 'origin/main' into dev
Pokbab Feb 3, 2026
e44efdf
[Feature] 게이트웨이 서버 거치도록 변경 및 docker로 배포 방식 변경 (#60)
imeasy99 Feb 23, 2026
2ae80c1
feat: 쿠키 기반 인증 기능 추가 및 기존 토큰 처리 방식 개선 (#61)
imeasy99 Feb 26, 2026
e388a92
[Fix] 토큰 재발급 로직 변경 (#62)
imeasy99 Mar 5, 2026
9b2825c
Revert "[Fix] 토큰 재발급 로직 변경 (#62)" (#63)
imeasy99 Mar 5, 2026
c5f627f
[Fix] 토큰 재발급 로직 변경 및 로그인 시 토큰 쿠키에 담는 것으로 변경 (#64)
imeasy99 Mar 9, 2026
564b2ce
[Deploy] 알파 서버 분리 및 서버 이전 (#65)
imeasy99 Mar 24, 2026
3531c9a
feat: EC2 배포 환경 설정 개선 및 워크플로 업데이트
imeasy99 Mar 24, 2026
8dcd6fc
feat: 배포 워크플로 환경 변수 설정 추가
imeasy99 Mar 24, 2026
c686035
feat: 배포 워크플로 EC2 기본 경로 수정
imeasy99 Mar 24, 2026
4d9afce
feat: GitHub Actions 배포 워크플로 운영 이미지 태그 변경
imeasy99 Mar 24, 2026
1af7c12
feat: 배포 워크플로 docker-compose 명령어를 docker compose로 변경
imeasy99 Mar 24, 2026
408ac84
feat: 배포 워크플로 docker compose 명령어 업데이트
imeasy99 Mar 24, 2026
1deeb96
feat: 소셜 로그인 응답 데이터 필드 기본값 추가
imeasy99 Mar 24, 2026
34c6487
feat: Google OAuth `verifiedEmail` 필드 기본값 추가
imeasy99 Mar 24, 2026
72a198e
feat: 프로젝트 환경 설정 및 의존성 업데이트
imeasy99 Mar 29, 2026
8e2f3f0
feat: 로깅 및 Hibernate 설정 업데이트
imeasy99 Mar 30, 2026
48e3c54
feat: 환경 설정 및 배포 워크플로 업데이트
imeasy99 Apr 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Build output and caches
build/
.gradle/

# Git and IDE
.git/
.gitignore
.idea/
*.iml

# Documentation (not needed in image)
*.md
docs/

# Local env and secrets
.env
.env.*

# OS and misc
.DS_Store
*.log
*.hprof

# Test and dev
src/test/
23 changes: 23 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
SPRING_PROFILES_ACTIVE=
DB_HOST=
DB_PORT=
DB_NAME=
DB_USERNAME=
DB_PASSWORD=
JWT_SECRET=
JWT_ACCESS_TOKEN_EXPIRATION=
JWT_REFRESH_TOKEN_EXPIRATION=
MAIL_USERNAME=
MAIL_PASSWORD=
SWAGGER_PATH=
APP_DEFAULT_ZONE=Asia/Seoul
CORS_ALLOWED_ORIGINS=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REDIRECT_URI=
KAKAO_CLIENT_ID=
KAKAO_CLIENT_SECRET=
KAKAO_REDIRECT_URI=
NAVER_CLIENT_ID=
NAVER_CLIENT_SECRET=
NAVER_REDIRECT_URI=
137 changes: 84 additions & 53 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -1,66 +1,97 @@
name: Deploy to EC2
name: Deploy (auth-BE)

# ---------------------------------------------------------------------------
# EC2 원격 경로 (아래 deploy job 의 env.PROJECT_ROOT 만 수정)
# PROJECT_ROOT … 배포 기준 루트. 예: ~, ~/myapp (끝 슬래시 없음)
# 환경변수 파일은 항상 {PROJECT_ROOT}/env/ 아래 (이름 고정: env)
# 배포는 EC2의 PROJECT_ROOT 에서 docker compose (서비스명: auth-be, V2 기준)
# ---------------------------------------------------------------------------

on:
push:
branches:
- main # main에 push될 때만 실행
- main
- dev

jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'alpha' }}
env:
PROJECT_ROOT: '~/apps'

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

- name: Set image tag and Spring profile
run: |
if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
echo "IMAGE_TAG=prod" >> $GITHUB_ENV
echo "SPRING_PROFILE=prod" >> $GITHUB_ENV
else
echo "IMAGE_TAG=alpha" >> $GITHUB_ENV
echo "SPRING_PROFILE=alpha" >> $GITHUB_ENV
fi

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
push: true
secrets: |
"GITHUB_TOKEN=${{ secrets.GIT_TOKEN }}"
build-args: |
GITHUB_ACTOR=${{ github.actor }}
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/auth-server:${{ env.IMAGE_TAG }}
${{ secrets.DOCKERHUB_USERNAME }}/auth-server:${{ github.sha }}

- name: Setup SSH
run: |
set -euo pipefail
mkdir -p ~/.ssh
echo "${{ secrets.EC2_KEY }}" > ~/.ssh/ec2_key.pem
printf '%s' "${{ secrets.EC2_KEY }}" > /tmp/ec2_key_src
if [[ ! -s /tmp/ec2_key_src ]]; then
echo "::error::EC2_KEY secret is empty" >&2
exit 1
fi
if head -n 1 /tmp/ec2_key_src | grep -q '^[[:space:]]*-----BEGIN'; then
cp /tmp/ec2_key_src ~/.ssh/ec2_key.pem
else
tr -d '\n\r \t' < /tmp/ec2_key_src | base64 --decode > ~/.ssh/ec2_key.pem || {
echo "::error::EC2_KEY is not PEM and base64 decode failed" >&2
exit 1
}
fi
rm -f /tmp/ec2_key_src
chmod 600 ~/.ssh/ec2_key.pem

- name: Create env file and copy to EC2
run: |
printf '%s\n' "${{ secrets.AUTH_BE_ENV_FILE }}" > auth-be.env
ssh -o StrictHostKeyChecking=no -i ~/.ssh/ec2_key.pem ${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }} 'mkdir -p ${{ env.PROJECT_ROOT }}/env'
scp -o StrictHostKeyChecking=no -i ~/.ssh/ec2_key.pem auth-be.env ${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }}:${{ env.PROJECT_ROOT }}/env/auth-be.env

- name: Deploy to EC2
run: |
ssh -o StrictHostKeyChecking=no -i ~/.ssh/ec2_key.pem ${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }} << 'EOF'
cd /home/${USER}/app
git pull origin main
./gradlew build -x test

# systemd 서비스 파일에 모든 환경변수 포함
sudo tee /etc/systemd/system/authBE.service > /dev/null << 'SERVICEEOF'
[Unit]
Description=AuthBE Spring Boot App
After=network.target

[Service]
Type=simple
User=ec2-user
WorkingDirectory=/home/ec2-user/app
ExecStart=/usr/bin/java -jar /home/ec2-user/app/build/libs/demo-0.0.1-SNAPSHOT.jar
Environment="DB_NAME=${{ secrets.DB_NAME }}"
Environment="DB_USER=${{ secrets.DB_USER }}"
Environment="DB_PASSWORD=${{ secrets.DB_PASSWORD }}"
Environment="DB_HOST=${{ secrets.DB_HOST }}"
Environment="DB_PORT=${{ secrets.DB_PORT }}"
Environment="GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }}"
Environment="GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }}"
Environment="GOOGLE_REDIRECT_URI=${{ secrets.GOOGLE_REDIRECT_URI }}"
Environment="KAKAO_CLIENT_ID=${{ secrets.KAKAO_CLIENT_ID }}"
Environment="KAKAO_CLIENT_SECRET=${{ secrets.KAKAO_CLIENT_SECRET }}"
Environment="KAKAO_REDIRECT_URI=${{ secrets.KAKAO_REDIRECT_URI }}"
Environment="NAVER_CLIENT_ID=${{ secrets.NAVER_CLIENT_ID }}"
Environment="NAVER_CLIENT_SECRET=${{ secrets.NAVER_CLIENT_SECRET }}"
Environment="NAVER_REDIRECT_URI=${{ secrets.NAVER_REDIRECT_URI }}"
Environment="JWT_ACCESS_TOKEN_EXPIRATION=${{ secrets.JWT_ACCESS_TOKEN_EXPIRATION }}"
Environment="JWT_REFRESH_TOKEN_EXPIRATION=${{ secrets.JWT_REFRESH_TOKEN_EXPIRATION }}"
Environment="JWT_SECRET=${{ secrets.JWT_SECRET }}"
Environment="MAIL_USERNAME=${{ secrets.MAIL_USERNAME }}"
Environment="MAIL_PASSWORD=${{ secrets.MAIL_PASSWORD }}"
Environment="SWAGGER_PATH=${{ secrets.SWAGGER_PATH }}"
Environment="USER=${{ secrets.USER }}"
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
SERVICEEOF

sudo systemctl daemon-reload
sudo systemctl restart authBE
sudo systemctl enable authBE
EOF
ssh -o StrictHostKeyChecking=no -i ~/.ssh/ec2_key.pem ${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }} '
set -e
export PATH="/usr/bin:/usr/local/bin:$PATH"
export DOCKERHUB_USERNAME="${{ secrets.DOCKERHUB_USERNAME }}"
export IMAGE_TAG="${{ env.IMAGE_TAG }}"
export SPRING_PROFILES_ACTIVE="${{ env.SPRING_PROFILE }}"
echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login -u "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin
cd ${{ env.PROJECT_ROOT }}
docker compose stop auth-be || true
docker compose rm -f auth-be || true
docker compose pull auth-be
docker compose up -d --no-deps --force-recreate auth-be
docker logout
'
34 changes: 34 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# ================================
# Stage 1: Build
# ================================
FROM eclipse-temurin:25-jdk-alpine AS builder

# GITHUB_ACTOR는 빌드 시점에 일반 ARG로 넘겨받습니다.
ARG GITHUB_ACTOR=easyappfactory

WORKDIR /workspace

# Gradle wrapper and source
COPY gradle gradle
COPY gradlew build.gradle.kts settings.gradle.kts ./
COPY src src

# mount 기능을 사용하여 빌드 시점에만 GITHUB_TOKEN을 안전하게 사용합니다.
RUN --mount=type=secret,id=GITHUB_TOKEN \
GITHUB_TOKEN=$(cat /run/secrets/GITHUB_TOKEN) \
GITHUB_ACTOR=${GITHUB_ACTOR} \
./gradlew bootJar --no-daemon -x test

FROM eclipse-temurin:25-jre-alpine

RUN adduser -D -h /app appuser

WORKDIR /app

COPY --from=builder /workspace/build/libs/auth-be-0.0.1-SNAPSHOT.jar app.jar

USER appuser

EXPOSE 9000

ENTRYPOINT ["java", "-Xmx256m", "-jar", "/app/app.jar"]
37 changes: 33 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# GrowGrammers Auth-BE
# Auth-BE

Spring Boot 기반의 인증/소셜 로그인 및 계정 연동(링크) 백엔드입니다.

## 목차
- [주요 기능](#주요-기능)
- [기술 스택](#기술-스택)
- [빠른 시작](#빠른-시작)
- [배포 (EC2 Docker)](#배포-ec2-docker)
- [환경 변수 설정](#환경-변수-설정)
- [API 엔드포인트](#api-엔드포인트)
- [인증 플로우](#인증-플로우)
Expand Down Expand Up @@ -51,6 +52,19 @@ Spring Boot 기반의 인증/소셜 로그인 및 계정 연동(링크) 백엔
java -jar build/libs/auth-be-0.0.1-SNAPSHOT.jar
```

## 배포 (EC2 Docker)

배포는 **Docker** 방식으로 수행하며, systemd/JAR 직접 실행은 사용하지 않습니다.

- **main** 브랜치 push 시 GitHub Actions가 Docker 이미지를 빌드·푸시한 뒤 EC2에 SSH로 접속해 컨테이너를 갱신합니다.
- EC2에서는 env를 **단일 파일**로만 사용합니다. GitHub Secret **`ENV_FILE`**(전체 .env 내용)을 CI가 **`~/env/auth-be.env`** 에 복사하고, 컨테이너는 `--env-file ~/env/auth-be.env` 로 실행합니다. (다른 도커 서비스와 구분을 위해 패키지명.env 형식 사용.)

실행 예:

```bash
docker run -d --restart unless-stopped --name auth-be -p 9000:9000 --env-file ~/env/auth-be.env <DOCKERHUB_USERNAME>/auth-server:latest
```

## 환경 변수 설정

환경 변수는 다음 파일에 매핑됩니다:
Expand Down Expand Up @@ -116,15 +130,30 @@ MAIL_PASSWORD=your-app-password
| POST | `/api/v1/auth/link/kakao` | Kakao 계정 연동 | **필요** |
| POST | `/api/v1/auth/link/naver` | Naver 계정 연동 | **필요** |

**요청 바디 필드 (Provider별)**
- **Google/Kakao**: `authCode`, `codeVerifier` (필수). `redirectUri`는 서버 환경변수 사용.
- **Naver**: `authCode`, `state`, `codeVerifier` (세 필수 모두 필요). 인가 요청 시 사용한 `state`와 동일한 값 전달.

**요청 예시** (Google 로그인):
```json
POST /api/v1/auth/google/login
Content-Type: application/json

{
"code": "4/0AfJohXmx...",
"codeVerifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk",
"redirectUri": "http://localhost:5173/auth/google/callback"
"authCode": "4/0AfJohXmx...",
"codeVerifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
}
```

**요청 예시** (Naver 로그인):
```json
POST /api/v1/auth/naver/login
Content-Type: application/json

{
"authCode": "네이버에서_받은_인가코드",
"state": "인가_요청시_사용한_state_값과_동일",
"codeVerifier": "PKCE_코드_검증자"
}
```

Expand Down
Loading
Loading