2026.08.16 - [프로젝트(스마트 휴먼 라이프)] - AI를 ‘쓰는 것’에서 ‘잘 쓰는 것’으로: 소제동 인터랙티브 지도 개발기
AI를 ‘쓰는 것’에서 ‘잘 쓰는 것’으로: 소제동 인터랙티브 지도 개발기
그동안 무언가를 개발할 때나, 해야 할 때 AI를 편하게 쓰고는 있었지만 "잘" 쓰지 못하고 있다는 걸 깨달았다... 이제 프로젝트를 할 때는 기본적으로 뼈대를 잡고 어떻게 만들지 AI한테 더 숙지
devheo.tistory.com
이전 글과 이어서 작성해보겠다
먼저 프로젝트 기술 구성은 다음과 같은 모노레포 구조를 사용했다
여기서 모노레포란??
둘 이상의 연관된 프로젝트나 패키지 코드를
하나의 저장소(Repository)에서 통합해 관리하는 소프트웨어 개발 방식
soje-map/
├── app/ # React 프론트엔드
├── public/ # 사진 및 정적 파일
├── backend/ # Spring Boot 백엔드
├── deployment/ # Raspberry Pi 및 Nginx 문서
├── Dockerfile # 프론트엔드 이미지
├── docker-compose.yml
├── next.config.ts
└── package.json
사용한 기술은 다음과 같다
프론트엔드
- React
- TypeScript
- Leaflet
- OpenStreetMap
- vinext/Vite
백엔드
- Java 21
- Spring Boot
- Maven
- Actuator 상태 확인 기능
배포
- Raspberry Pi 5
- Ubuntu Server
- Docker
- Docker Compose
- 외부 Nginx 리버스 프록시
- GitHub
현재 프론트엔드는 백엔드 API를 호출하지 않는다. Spring Boot는 추후 장소 정보 관리, 관리자 기능, 사진 업로드 등의 기능이 필요할 때 확장할 예정이다
4. 포트 구성
처음에는 프론트 개발 서버에서 3000 포트를 사용했다. 하지만 Raspberry Pi에서 이미 점유되어 있을 가능성이 있어 외부 공개 포트를 18080으로 변경했다.
프론트엔드
Raspberry Pi 18080 -> 컨테이너 3000
백엔드
Raspberry Pi 18081 -> 컨테이너 8080
백엔드는 아직 프론트에서 사용하지 않기 때문에 외부 네트워크에는 노출하지 않고 서버 내부에서만 접근할 수 있도록 했다
전체 요청 흐름은 다음과 같다

5. 로컬에서 Docker로 확인하기
Raspberry Pi에 바로 배포하지 않고 먼저 로컬에서 Docker 이미지가 정상적으로 실행되는지 확인했다
docker compose up -d
컨테이너 상태는 다음 명령으로 확인한다
docker compose ps
로그는 다음과 같이 확인할 수 있다
docker compmose logs --tail=100 frontend backend
프론트엔드 확인:
curl -I http://127/..
백엔드 상태 확인:
curl http://127.~/actuator/health
정상이라면 백엔드는 다음과 비슷한 응답을 반환한다
{
"status": "UP"
}
테스트가 끝난 후에도 다음 명령으로 컨테이너를 종료했다
docker compose down
내가 Codex한테 배포하기전 요청한 것
이대로 라즈베리파이에 배포해보려고해. 라즈베리파이는 Ubuntu Server로 동작하고 있고, 이 안에 설치된 Docker에서 만든 작품을 배포하려고해. 이때, 사용한 3000 포트는 점유중일 수 있으니, 다른 포트로 변경 필요함. 결론적으로 raspberry pi에서 docker compose up -d 로 했을 때, 정상적으로 서버에 베포될 수 있도록 세팅까지 완료해야함. 완료된거 확인하면 git에 push하고, ubuntu server에 가서 pull로 다 가져오는 식으로 할게. commit하고 push 전상태까지 만들면 됨. git init은 진행.
6. GitHub에 소스 올리기
프로젝트 디렉터리에서 Git 저장소를 생성했다
git init
git add .
git commit -m "feat: add Soje memory map"
원격 저장소를 연결한 후 푸시한다
git remote add origin <GitiHub 저장소 주소>
git branch -M main
git push -u origin main
이수 수정사항은 다음과 같이 올린다
git add .
git commit -m "수정 내용"
git push origin main
7. Raspberry Pi 최초 배포
당연히 라즈베리파이 환경에서 작업해야 한다^^
Raspberry Pi에는 Ubuntu Server와 Docker가 설치되어 있다고 가정한다
먼저 시스템 아키텍처를 확인한다
uname -m
Raspberry Pi 5의 64비트 Ubuntu Server라면 일반적으로 다음 중 하나가 나온다
aarch64
arm64
GitHub 저장소를 내려받는다
docker compose ps
git clone <GitHub 저장소 주소> soje-map
cd soje-map
Docker Compose로 이미지를 빌드하고 실행한다
docker compose up -d
상태를 확인한다
프론트엔드를 Raspberry Pi 내부에서 직접 확인한다
curl -I http://127.~/
백엔드 상태를 확인한다
curl http://127.0.0.1:18081/actuator/health
8. 이후 소스 업데이트 방법
cd ~/soje-map
git pull --ff-only
docker compose build frontend
docker compose up -d --force-recreate --remove-orphans
Docker 캐시 문제를 확실히 배제해야 한다면 다음과 같이 프론트 이미지를 다시 빌드한다
docker compose build --no-cache frontend
docker compose up -d --force-recreate --remove-orphans
--ff-only를 사용하는 이유
--ff-only 는 Fast-forward가 가능한 경우에만 원격 변경사항을 가져오도록 하는 옵션이다
배포 서버에서는 직접 코드를 수정하지 않고 GitHub의 코드를 그대로 받아 사용하는 것이 일반적이다
저 명령을 사용하면 Raspberry Pi의 Git 기록과 GitHub 기록이 갈라진 경우 Git이 자동으로 병합하지 않고 중단한다
덕분에 배포 서버에 예상하지 못한 병합 커밋이 생기는 것을 방지할 수 있다
다음 장에서는 내가 배포를 하는 과정에서 겪었던 문제를 작성해보겠다
'프로젝트(스마트 휴먼 라이프)' 카테고리의 다른 글
| Docker는 정상인데 CSS가 안 나온다? Nginx 404 오류 해결기 (0) | 2026.08.16 |
|---|---|
| AI를 ‘쓰는 것’에서 ‘잘 쓰는 것’으로: 소제동 인터랙티브 지도 개발기 (0) | 2026.08.16 |