Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- express
- NextJs
- SSR
- 리액트 훅
- 모던자바스크립트
- 초기마운트
- lazy()
- docker
- Database
- key
- react-hook-form
- 리액트
- react-hook
- react
- useEffect
- msw
- 리액트훅
- 클래스
- Firebase
- reactquery
- next-cookies
- ErrorBoundary
- CSR
- useLayoutEffect
Archives
- Today
- Total
한우의 개발일기
[Next.js]next 프로젝트에 도커 적용기 본문
트러블 슈팅
도커 빌드시 환경변수를 읽어 오지 못하는 오류가 생겼다
yml파일
# docker-compose.yml
services:
web:
build:
context: .
dockerfile: Dockerfile
args:
NEXT_PUBLIC_API_MOCKING: ${NEXT_PUBLIC_API_MOCKING}
NEXT_PUBLIC_BASE_URL: ${NEXT_PUBLIC_BASE_URL}
NEXT_PUBLIC_KAKAOMAP_KEY: ${NEXT_PUBLIC_KAKAOMAP_KEY}
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- NEXT_PUBLIC_API_MOCKING=${NEXT_PUBLIC_API_MOCKING}
- NEXT_PUBLIC_BASE_URL=${NEXT_PUBLIC_BASE_URL}
- NEXT_PUBLIC_KAKAOMAP_KEY=${NEXT_PUBLIC_KAKAOMAP_KEY}
env_file:
- .env
restart: always
이런식으로 설정을 해주고 docker compose config 명령어를 치면 환경변수가 잘 담기는데 빌드 과정에서 api 사용 부분에서 환경변수를 찾지 못하는 오류가 발생했다
이유는 우리 프로젝트는 fetch 함수를 커스텀 해서 사용중인데
/* eslint-disable @typescript-eslint/no-explicit-any */
import { ApiError, NotFoundError } from "@/custom-error";
import getBrowserCookie from "@/utils/browser-cookies";
import { getCookie } from "@/utils/next-cookie";
const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL;
if (!BASE_URL) throw new NotFoundError("base url이 없습니다.");
class CustomFetch {
baseURL: string;
accessToken?: string;
constructor(baseURL: string) {
this.baseURL = baseURL;
}
async getAccessToken() {
if (typeof window !== "undefined") {
this.accessToken = getBrowserCookie("accessToken");
} else {
this.accessToken = await getCookie("accessToken");
}
}
// 공통 fetch 메서드
async fetchWithAuth<T>(
endpoint: string,
options: RequestInit = {},
): Promise<{ data: T }> {
await this.getAccessToken();
const headers = {
...options.headers,
Authorization: `Bearer ${this.accessToken}`,
"Content-Type": "application/json",
};
const config = {
...options,
headers,
};
const response = await fetch(`${this.baseURL}${endpoint}`, config);
if (!response.ok) {
const errorData = await response.json();
const error = new ApiError(
errorData.message || "요청에 실패했습니다",
response.status,
);
throw error;
}
return { data: await response.json() }; // Automatically return parsed JSON
}
// GET 메서드
get<T>(endpoint: string, options: RequestInit = {}) {
return this.fetchWithAuth<T>(endpoint, { ...options, method: "GET" });
}
// POST 메서드
post<T>(endpoint: string, body: any, options: RequestInit = {}) {
return this.fetchWithAuth<T>(endpoint, {
...options,
method: "POST",
body: JSON.stringify(body),
});
}
// PUT 메서드
put<T>(endpoint: string, body: any, options: RequestInit = {}) {
return this.fetchWithAuth<T>(endpoint, {
...options,
method: "PUT",
body: JSON.stringify(body),
});
}
// DELETE 메서드
delete<T>(endpoint: string, options: RequestInit = {}) {
return this.fetchWithAuth<T>(endpoint, { ...options, method: "DELETE" });
}
}
const instance = new CustomFetch(BASE_URL);
export default instance;
API를 사용 하는 부분에서
export async function getShowsDetails(popupId: number): Promise<Show> {
const { data } = await instance.get<Show>(`/api/popups/${popupId}`);
return data;
}
NEXT_PUBLIC_BASE_URL를 찾지 못하는 오류가 발생했다
오류가나는 이류가 2가지 정도 있었는데
도커는 .env만 기본적으로 읽는다 .env.local 과 같은것들은 따로 설정을 해줘야 한다
const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL;
if (!BASE_URL) throw new NotFoundError("base url이 없습니다.");
그래서 커스텀 fetch 부분에서 baseUrl이 없다고 판단하여 에러를 던진다(빌드전에 파일을 한바퀴 돌고 baseUrl이 없다고 판단한다)
그래서 바꾼 방법은 .env.local을 .env 로 바꾸고
const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL;
if (!BASE_URL) throw new NotFoundError("base url이 없습니다.");
class CustomFetch {
baseURL: string;
accessToken?: string;
constructor(baseURL: string) {
this.baseURL = baseURL;
}
이거를
class CustomFetch {
private baseURL: string;
accessToken?: string;
constructor() {
const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL;
if (!BASE_URL) {
throw new NotFoundError("base url이 없습니다.");
}
this.baseURL = BASE_URL;
}
async getAccessToken() {
if (typeof window !== "undefined") {
this.accessToken = getBrowserCookie("accessToken");
} else {
this.accessToken = await getCookie("accessToken");
}
}
이렇게 클래스 안에서 Url 확인을 런타임 이후에 진행을 해준 다음 다시 빌드를 해주었다
성공 !!
'NextJS' 카테고리의 다른 글
Nextjs 프로젝트에 express를 분리 한 이유!! (0) | 2025.03.06 |
---|---|
[Next.js]next 프로젝트 도커 빌드하기(2) (0) | 2024.11.11 |
[Next.js]Nextjs 프로젝트 도커로 빌드하기 (0) | 2024.11.11 |
[Next.js] next-cookies(서버/클라이언트 쿠키 사용기) (0) | 2024.11.11 |
[Next.js] ReactQuery 적용기 (1) | 2024.11.11 |