DevOps
Git
Git Submodule 완전정복 (실전편): 실제 프로젝트에 적용하기

들어가며

이번 글에서는 이미 Git으로 관리 중인 프로젝트에 서브모듈을 적용한 실제 과정을 정리해 보겠습니다.
단순히 개념 설명이 아닌, 로컬 테스트부터 GitHub Actions 자동화까지 전 과정을 기록한 실전 가이드입니다.


1. 기존 프로젝트에서 서브모듈로 분리하기

테스트 환경으로 아래와 같은 폴더 구조를 구성했습니다.


D:\dev\submodule_test
├── test1/
├── test2/     # 이 디렉터리를 서브모듈로 분리할 예정
├── test3/

처음엔 submodule_test 전체를 Git으로 초기화하고 커밋했습니다.

cd D:\dev\submodule_test
git init
git add .
git commit -m "Initial commit"

2. 서브모듈용 저장소 생성 및 푸시

test2 폴더를 별도 저장소로 관리하기 위해 브랜치 분리를 수행했습니다.

git subtree split --prefix=test2 -b split-test2

그다음 새로운 bare 저장소를 만들고 해당 브랜치를 푸시했습니다.

mkdir D:\dev\subrepo
cd D:\dev\subrepo
git init --bare
cd D:\dev\submodule_test
git push D:\dev\subrepo split-test2:main

이후 GitHub에 test2 전용 원격 저장소를 새로 만들고, bare repo의 내용을 그대로 복사했습니다.

cd D:\dev\subrepo
git remote add origin https://github.com/2nan22/test2.git
git push origin --mirror

3. 메인 프로젝트에 서브모듈로 추가

기존 test2 폴더를 제거하고, 방금 만든 GitHub 원격 저장소를 서브모듈로 등록했습니다.

cd D:\dev\submodule_test
git rm -r test2
git commit -m "Remove test2 folder for submodule replacement"
 
git submodule add https://github.com/2nan22/test2.git test2
git commit -m "Add test2 as submodule"

이후 .gitmodules 파일이 생성되며 다음과 같이 구성되었습니다.

[submodule "test2"]
  path = test2
  url = https://github.com/2nan22/test2.git

4. GitHub Actions을 통한 자동 반영 설정

서브모듈의 main 브랜치에 변경이 생기면 메인 프로젝트(submodule_test)의 서브모듈 참조를 자동으로 업데이트하도록 GitHub Actions을 구성했습니다.

(1) 메인 레포: .github/workflows/update_submodule.yml

name: Auto Update Submodule
 
on:
  repository_dispatch:
  push:
    branches:
      - main
 
jobs:
  update-submodule:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout main repo
        uses: actions/checkout@v4
        with:
          submodules: true
          token: ${{ secrets.GITHUB_TOKEN }}
 
      - name: Update submodule reference
        run: |
          git submodule update --remote --merge
          git add test2
          git commit -m "Auto-update submodule test2"
          git push

(2) 서브모듈 레포: .github/workflows/notify_main.yml

name: Notify main repo on push
 
on:
  push:
    branches:
      - main
 
jobs:
  trigger-main-update:
    runs-on: ubuntu-latest
    steps:
      - name: Trigger update on main repo
        run: |
          curl -X POST \
            -H "Accept: application/vnd.github+json" \
            -H "Authorization: Bearer ${{ secrets.PAT_TOKEN }}" \
            https://api.github.com/repos/2nan22/submodule_test/dispatches \
            -d '{"event_type":"update_submodule"}'

🔐 PAT_TOKENworkflow 권한이 포함된 Personal Access Token을 사용해야 합니다.


5. Docker Compose와 서브모듈 반영

test2는 FastAPI 기반 모델 서비스로, docker-compose.yml에서 볼륨으로 연결되어 있습니다.

services:
  model_service:
    build: ./test2
    volumes:
      - ./test2:/app/model_service
    command: uvicorn model_service.main:app --host 0.0.0.0 --port 8001

따라서 GitHub Actions이나 서브모듈 업데이트 후, 코드 변경 사항을 반영하려면 단순히 컨테이너만 재시작하면 됩니다.

docker compose restart model_service

이미 볼륨으로 연결되어 있으므로, 이미지 재빌드(--build)는 불필요합니다.


6. 협업 브랜치 전략

서브모듈을 직접 수정하는 동료에게는 다음 규칙을 적용했습니다.

  1. feature/* 브랜치를 따서 개발
  2. 충분히 검증된 뒤에만 main 브랜치로 merge
  3. main으로 push 시 GitHub Actions이 자동으로 메인 프로젝트를 갱신

이렇게 하면 서브모듈과 메인 레포 간의 동기화가 자동으로 이뤄집니다.


7. 정리

항목요약
서브모듈 경로test2
서브모듈 원격https://github.com/2nan22/test2.git
자동 반영GitHub Actions (update_submodule.yml)
반영 후 동작Docker Compose restart만 필요
협업 플로우feature → main merge 시 자동 반영

이렇게 해서 기존 프로젝트를 깨끗하게 서브모듈 구조로 분리하고, 코드 변경 시 자동으로 반영되도록 GitHub Actions와 연동했습니다. 볼륨 마운트 기반의 Docker 환경에서는 컨테이너 재시작만으로 즉시 반영이 가능하므로, CI/CD 파이프라인이 단순하면서도 안정적으로 유지됩니다.