이 글은 LG CNS AM Camp 1기에서 수강한 내용을 정리한 글입니다.
리액트 앱의 엔드포인트 수정
const rest_api_host = import.meta.env.VITE_REST_API_HOST;
const rest_api_port = import.meta.env.VITE_REST_API_PORT;
console.log({rest_api_host, rest_api_port});
...
axios
.get(`http://${rest_api_host}:${rest_api_port}/api/v2/board`, ... )
개발 PC에서 동작 확인
c:\lgcns\board-app> set VITE_REST_API_HOST=127.0.0.1
c:\lgcns\board-app> set VITE_REST_API_PORT=8080c:\lgcns\board-app> npm run dev빌드
c:\lgcns\board-app> npm run build
Nginx 컨테이너를 이용해서 빌드 결과가 서비스되는 것을 확인
c:\lgcns\board-app> docker container run -d -p 8888:80 --name web --rm -v c:\lgcns\board-app\dist:/usr/share/nginx/html nginx
c:\lgcns\board-app\dist: 빌드 결과/usr/share/nginx/html: nginx 웹 루트 디렉토리http://localhost:8888 접속하면 정상적으로 동작하는 것을 확인
파일 작성
FROM node:22.13.1 AS builder
ENV VITE_REST_API_HOST=192.168.0.221 # 스프링부트가 실행되고 있는 서버의 주소 (내 PC 주소)
ENV VITE_REST_API_PORT=8080
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
FROM nginx
COPY --from=builder /app/dist /usr/share/nginx/html
이미지 빌드
c:\lgcns\board-app> docker image build -t board-app:v1 .
c:\lgcns\board-app> docker image ls
c:\lgcns\board-app> docker container run -d -p 80 --name my-react-app --rm board-app:v1
c:\lgcns\board-app> docker container ls
컨테이너로 접속했을 때 CORS 오류가 발생 ⇒ 스프링부트의 WebMvcConfiguration 파일에 Origin을 추가
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/api/**")
.allowedOrigins("http://localhost:5173", "http://localhost:59142", "http://localhost:8888")
.allowedMethods("GET", "POST", "PUT", "DELETE");
registry
.addMapping("/loginProc")
.allowedOrigins("http://localhost:5173", "http://localhost:59142", "http://localhost:8888")
.allowedMethods("POST");
}
게시판 목록 데이터 요청 주소가 Dockerfile에 ENV 지시어로 정의한 값으로 설정된 것을 확인
파일 수정
FROM node:22.13.1 AS builder
ARG SPRINGBOOT_ADDRESS=192.168.0.221
ARG SPRINGBOOT_PORT=8080
ENV VITE_REST_API_HOST=${SPRINGBOOT_ADDRESS}
ENV VITE_REST_API_PORT=${SPRINGBOOT_PORT}
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
FROM nginx
COPY --from=builder /app/dist /usr/share/nginx/html
이미지 빌드 및 컨테이너 실행
c:\lgcns\board-app> docker image build --build-arg SPRINGBOOT_ADDRESS=localhost -t board-app:v2 .
c:\lgcns\board-app> docker container ls
이전 컨테이너와 같은 포트를 사용하기 위해서 컨테이너를 중지, 삭제 (스프링부트 서버의 CORS 설정을 동일하게 가져가기 위해서)
c:\lgcns\board-app> docker container stop my-react-app
c:\lgcns\board-app> docker container run -d -p 59142:80 --name my-react-app --rm board-app:v2
c:\lgcns\board-app> docker container ls
게시판 목록 정보를 조회하는 주소가 --build-arg 옵션에 설정한 값을 사용하는 것을 확인
c:\lgcns\board-app> docker image tag board-app:v2 myanjini/board-app:v2
c:\lgcns\board-app> docker image ls
c:\lgcns\board-app> docker image push myanjini/board-app:v2
c:\lgcns\board-app> docker container run -d -p 4406:3306 --name mysql -e MYSQL_ROOT_PASSWORD=p@ssw0rd -e MYSQL_DATABASE=springbootdb -e MYSQL_USER=springboot -e MYSQL_PASSWORD=p@ssw0rd -v c:\temp\mysql_data:/var/lib/mysql mysql
c:\lgcns\board-app> docker container ls
application-prod.properties
spring.datasource.url=jdbc:mysql://mysql:3306/springbootdb?useUnicode=true&characterEncoding=utf-8&serverTimeZone=Asia/Seoul
mysql:3306의 'mysql': mysql 컨테이너와 연결되는 별칭HOSTIP:4406application.properties
spring.profiles.active=prod
spring.servlet.multipart.location=/uploads
WebMvcConfiguration
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/api/**")
.allowedOrigins("http://localhost:5173", "http://localhost:90")
.allowedMethods("GET", "POST", "PUT", "DELETE");
registry
.addMapping("/loginProc")
.allowedOrigins("http://localhost:5173", "http://localhost:90")
.allowedMethods("POST");
}
프로젝트 루트 디렉토리로 이동
c:\lgcns\board> dir
c:\lgcns\board> gradlew clean build bootBuildImage -x test
c:\lgcns\board> docker image ls
c:\lgcns\board> docker container run -d -p 9090:8080 --name springboot --link mysql:mysql board:0.0.1-SNAPSHOT
c:\lgcns\board> docker container ls
--link mysql:mysql: <컨테이너명>:<별칭>파일 수정
FROM node:22.13.1 AS builder
ARG SPRINGBOOT_ADDRESS=192.168.0.221
ARG SPRINGBOOT_PORT=9090
ENV VITE_REST_API_HOST=${SPRINGBOOT_ADDRESS}
ENV VITE_REST_API_PORT=${SPRINGBOOT_PORT}
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
FROM nginx
COPY --from=builder /app/dist /usr/share/nginx/html
이미지 빌드 및 컨테이너 실행
c:\lgcns\board-app> docker image build --build-arg SPRINGBOOT_ADDRESS=localhost -t board-app:v3 .
c:\lgcns\board-app> docker image ls
c:\lgcns\board-app> docker container run -d -p 90:80 --name react board-app:v3
워크벤치를 이용해서 사용자 등록
insert into `springbootdb`.`t_jpa_user`
(`email`, `name`, `password`, `role`, `username`)
values
('hong@test.com', '홍길동', '$2a$10$3uNr2G/ZPqPKAbwzZnHb7.AVrdYa6JhwPvrklp3rtwZsKO5ks20Fe', 'ROLE_USER', 'hong')
브라우저를 이용해서 리액트 컨테이너로 접근
docker-compose.yaml 파일을 생성
services:
mysql:
image: mysql
ports:
- 4406:3306
environment:
- MYSQL_ROOT_PASSWORD=p@ssw0rd
- MYSQL_DATABASE=springbootdb
- MYSQL_USER=springboot
- MYSQL_PASSWORD=p@ssw0rd
volumes:
- c:\temp\mysql_data:/var/lib/mysql
springboot:
depends_on:
- mysql
image: board:0.0.1-SNAPSHOT
ports:
- 9090:8080
react:
depends_on:
- springboot
image: board-app:v3
ports:
- 90:80
기존 컨테이너 모두 삭제 후 docker compose up
c:\lgcns\board-app> docker compose up -d
c:\lgcns\board-app> docker container ls
동작 테스트
단일 호스트에 여러 컨테이너가 실행되는 경우

여러 호스트에 컨테이너가 실행되는 경우
