R&D
개발현황
제 컴퓨터서는 잘 동작하는데요?
- 관리자
- 2025.04.30
제 컴퓨터서는 잘 동작하는데요?
안녕하세요. 크레플 개발팀입니다.
오늘은 개발 후 테스트 및 배포 환경 구성, 각 환경에서의 프론트엔드에서 API 요청을 보낼때 구성에 대한 이야기를 해보려합니다.
로컬에서는 잘 동작하던 코드가 다른 PC나 서버에서는 에러가 발생하거나 아예 동작하지 않기도 합니다.
이럴때는 내 PC에서는 잘 동작하는데 ?..?라는 생각이 들곤 합니다. 하지만 컴퓨터는 거짓말을 하지 않죠...
이번 글에서는 환경 차이로 인하여 발생했던 문제와 어떻게 구성을 하였는지에 대한 이야기를 해보려합니다.
프론트엔드 개발 환경
- framwork: Next.js
서비스 운영 환경
일반적으로 서비스는 4단계의 서버 환경으로 운영됩니다.
- 로컬(Local): 개발자 개인 환경에서 개발 및 테스트를 수행하는 로컬 환경
- 개발(Dev): 여러 명의 개발자가 작업한 코드를 통합하여 테스트하는 환경
- 스테이징(Staging): 운영 서버와 동일한 환경을 구성하여 운영 서버 반영 전 최종 검증을 진행하는 환경
- 운영(Production): 실제 사용자에게 서비스가 제공되는 환경
저희 EQ0 서비스는 개발 서버와 스테이징 서버를 통합 운영하여
"로컬 → 개발/스테이징 → 운영"의 단계를 거쳐 배포가 이루어집니다.
개발 및 서비스 환경
초기 개발 단계에서는 클라우드에 배포된 백엔드 서버에 API 요청을 보내는 방식으로 개발을 진행했습니다.
하지만 실제 서비스 배포가 진행되며 운영 환경에 대하여 민감한 데이터가 생기면서, 로컬 환경에서 운영 서버로 API 요청을 보내는 방식은 적절하지 않다는 판단을 하게 되었습니다.
이유는 다음과 같습니다:
- 운영 서버의 데이터는 실제 서비스 중인 민감한 데이터이기 때문에 보안 이슈가 발생할 수 있음
- 클라우드 환경에서는 API 요청 하나하나가 비용으로 연결됨
따라서 개발 환경과 서비스 환경을 분리하기로 하였고, 사내 개발 서버로 구축된 백엔드 서버에 API 요청을 보내는 방식으로 개발을 진행하였습니다.
그런데 이 개발 서버는 사내 사무실에 위치하고 있어 다른 사무실 등 외부에서 접근이 불가능한 구조였습니다.
따라서 개발 중에는 로컬에 백엔드 서버를 구성하여 사용하고 개발 후 실제 서비스 환경과 동일한 구성에서 검증 후 코드를 배포하도록 하였습니다.
도커(Docker) 환경에서의 개발
실제 서비스에서는 프론트엔드 서버, 백엔드 서버가 각각 도커로 실행되기 때문에 동일한 환경을 구성하였습니다.
그런데 문제가 생겼습니다.
- 프론트엔드가 로컬에서 실행될 경우: localhost를 통해 도커 백엔드 서버에 API 요청 시 정상 동작
- 프론트엔드, 백엔드 서버 모두 도커로 실행 시:
- 서버 사이드 랜더링(SSR) 시 API 요청이 실패
- 먼저, CSR(Client Side Rendering), SSR(Server Side Rendering)에 대한 이해가 필요합니다.
Client Side Rendering vs Server Side Rendering
CSR (Client Side Rendering)
웹 서버는 요청을 받으면 클라이언트에 HTML과 JS를 보내줍니다.
클라이언트(브라우저)는 HTML과 JS를 받아서 화면을 랜더링 합니다.
- 요청 주체: 브라우저
- 네트워크 기준: 개발자의 컴퓨터(호스트) 기준
- Javascript 코드가 브라우저에서 실행되어 API 요청을 직접 보냄
- localhost 사용 가능
SSR (Server Side Rendering)
웹 서버는 요청을 받으면 HTML을 랜더링하여 클라이언트에 HTML을 보내줍니다.
- 요청 주체: Next.js 서버(Node.js)
- 네트워크 기준: 프론트엔드 Docker 컨테이너 내부
- API 요청이 컨테이너 내부에서 보냄
- localhost 사용 시 도커 컨테이너 내부의 localhost를 가리킴
네트워크 구성
- CSR: 브라우저에서는 개발 컴퓨터 기준으로 네트워크를 바라고브로, localhost로 요청 가능
- SSR: 도커 컨테이너 내부에서 Node.js가 API 요청을 보내기 때문에, 도커 네트워크 상의 주소를 사용해야함
해결 방법
1. 컨테이너 간 통신은 Docker 네트워크 이름 사용
Docker Compose를 사용
services:
backend:
container_name: backend
ports:
- "port:port"
frontend:
container_name: frontend
depends_on:
- backend
environment:
- API_BASE_URL=http://backend:port
2. CSR과 SSR을 분리하여 처리
const API_URL =
typeof window === 'undefined'
? process.env.API_URL
: process.env.NEXT_PUBLIC_API_URL; // CSR
환경 변수 예시:
.env
:API_URL=http://backend:port
.env.local
:NEXT_PUBLIC_API_URL=http://localhost:port
마무리하며
로컬 개발 환경에서는 잘 동작하였기 때문에 배포하였으나 실제 서비스 서버 또는 다른 환경에서 문제가 발생하곤 합니다.
이번 문제는 도커 네트워크 구성과, CSR/SSR에 대한 이해가 부족으로 비롯된 구조적인 이슈였으며 다음과 같은 내용을 알게 되었습니다.
- CSR과 SSR의 내부 구성에 대한 이해
- 도커 환경에서 컨테이너 간 통신은 반드시 Docker Network로 구성해주어야 함