마지막 강의이다.
실습 전 설정
실습 디렉토리 : last (강의에서는 그대로 ex09에서하심)
- db
- product
- docker-compose.yml
- my-react-app-auto-build
실습 전에 해당 파일들을 ex09에서 last로 복사해놓자.
[강사님 GIT에서 nginx.conf 퍼오기]
https://github.com/codingspecialist/docker-study/blob/main/ex09/my-app/nginx/nginx.conf
여기서 nginx.conf 퍼오자. 설명은 나중에 해준다고 하심.
[Nginx 설정하기 및 설명]
위치 : last / my-react-app-auto-build / nginx 생성!
방금 퍼온 nginx.conf를 방금 생성한 nginx디렉토리에 넣어주자.
upstream backend {
server backend: 8080;
}
upstream backend -> 변수를 하나 지정한다고 생각하자.
backend에 요청이 들어오면 backend:8080으로 가게 하겠다.
여기서 server backend:8080; 에서 backend는 도커 컴포즈의 서비스명이다. 이는 10.10.1.1로 치환된다고 생각하면된다.
#server_name metacoding.site www.metacoding.site;
실제로 도메인이 있으면 써야하는데 도메인이 없기 때문에 주석처리한다.
location / {
root /usr/share/nginx/html;
index index.html index.htm;
'/' 로 요청이 오면 /usr/share/nginx/html 안에 있는 index.html 파일을 전달해줄 것이다.
여기에서 index.html은 react가 build된 파일이다.
이는 도커 입문 30강 - 도커컴포즈 Dockerfile로 빌드와 nginx실행 한번에 하기
여기에서 한번 했었다.
저기에서 사용한 Dockerfile의 내용을 보면
FROM node:alpine as build
WORKDIR /app
COPY package.json /app
RUN npm install --silent
COPY . /app
RUN npm run build
FROM nginx
#--from=build는 위에있는 FROM으로 부터 이미지가 구워지는데 그 결과로 나온 것을 의미한다.
# 위에서 나온 결과물인 /app/build 를 /usr/share/nginx/html로 복사하라는 의미이다.
COPY --from=build /app/build /usr/share/nginx/html
ENTRYPOINT ["nginx","-g","daemon off;"]
여기에서 마지막에서 2번째 줄에 있는 것을 보면 build한 것을 /usr/share/nginx/html로 넣어주게 되는 것을 볼 수 있다.
location /api/ {
proxy_pass http://backend;
rewrite ^/api(/.*)$ $1 break; # /api/ 제거가 되요!!
/api로 왔을 때의 설정인데 가장 중요한 것을 proxy_pass이다. http://, https:// 는 고정인데 backend 이부분이 docker 내부 IP는 컨테이너가 실행될 때 동적으로 바뀌게 되니까 미리 적어 놓을 수가 없다. 그래서 저렇게 backend라고 적어놓으면 upstream backend {
server backend:8080;
}
여기 upstream의 backend를 찾아간다. 근데 여기 적힌 server backend:8080은 도커 서비스명이다.
2번째 줄인
rewrite ^/api(/.*)$ $1 break; # /api/ 제거가 되요!!
이 부분은 스프링에 Controller는 /api/ 로 시작되는 부분이 없으니까 nginx단에서 제거 해주는 것이다.
밑에 proxy_http_version~ 헤더 들은 다음 시간에 따로 알려주신다고 하심...
이제 해당 설정파일을 가진 nginx가 올라가서 nginx와 통신을 하면 [ 도커 입문 31강 - 도커컴포즈 React와 SpringDB포함 직접연결하기] 강의에서 설정한 cross origin은 필요가 없어진다.
왜냐면,
React에서 /api/ ---▶ nginx (/api를 없애주고 Spring에게 전달) ---▶ Spring
이렇게 React에서 직접적으로 Spring에 요청한 것이 아니고 프록시 서버를 경유하는 요청이기 때문에 Cross Origin 에러에 걸리지 않게 된다.
[my-react-app-auto-build]
my-react-app-auto-build 디렉토리에 있는 Dockerfile에서 nginx를 띄우는데 그것을 수정해야한다.
FROM node:alpine as build
WORKDIR /app
COPY package.json /app
RUN npm install --silent
COPY . /app
RUN npm run build
FROM nginx
#--from=build는 위에있는 FROM으로 부터 이미지가 구워지는데 그 결과로 나온 것을 의미한다.
# 위에서 나온 결과물인 /app/build 를 /usr/share/nginx/html로 복사하라는 의미이다.
COPY --from=build /app/build /usr/share/nginx/html
#내가 커스텀한 nginx.conf파일로 넢어씌운다.
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
ENTRYPOINT ["nginx","-g","daemon off;"]
모두 똑같은데 마지막 COPY 하는 부분에서 위에서 설정한 nginx.conf 파일을 실제로 가동될 nginx 컨테이너로 덮어 씌우는 부분을 추가했다.
그리고 소스코드도 변경해야하는데 onLoad 함수의 fetch에서 요청하는 주소만 변경하면된다.
async function onLoad(){
//let response = await fetch('http://localhost:8080/products');
let response = await fetch('/api/products');
let responseBody = await response.json();
console.log("onLoad",responseBody);
setProducts(responseBody);
}
http://192.168.0.3/products ----▶ /api/products 로 변경하면 된다.
[product] : 딱히 변경점이 없다. 굳이 있다면 cross origin 설정 코드를 지우는 것?
[db] : 딱히 변경점이 없다.
※우리는 db의 데이터 파일들을 모두 외부 볼륨(store 디렉토리)로 연결시켜놨기 때문에 컨터이너 종료와 상관없이 계속 누적된다.
※ docker-compose.yml은 실제 배포할 때는 필요가 없다. 로컬에서 테스트 용으로만 사용하고, AWS같은 곳에 배포할 때는 Dockerfile만 잘 써두면 된다.
[docker-compose.yml]
server -> backend로 변경
frontend 추가
backend:
build:
context: ./product
dockerfile: Dockerfile
restart: always
ports:
- 8080:8080
depends_on:
- db #db가 먼저 구축되고 나서 다 되면 server를 실행시키는 것을 의미한다.
environment: #해당 값들은 application-prod.yml에서 ${SPRING_DATASOURCE_URL} 에서 사용한다.
SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/metadb?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false&allowPublicKeyRetrieval=true
SPRING_DATASOURCE_DRIVER: com.mysql.cj.jdbc.Driver
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: root1234
networks: #동일 네트워크로 잡아주어야 datasource url에서 jdbc:mysql://db 로 쓸수있는 것이다. ip로 안쓰고..
- network
frontend:
build:
context: ./my-react-app-auto-build
dockerfile: Dockerfile
restart: always
ports:
- 80:80
depends_on:
- backend
networks:
- network
db, netowork 부분은 변경점이 없다.
docker-compose.yml 전체코드
version: '3'
services:
db:
build:
context: ./db #Dockerfile의 위치-이걸 안잡아주면 COPY할 때 init.sql위치를 ex08(docker-compose.yml이 있는 곳)으로 봐버리는 문제가 생긴다.
dockerfile: Dockerfile
ports:
- 3306:3306
volumes:
- ./db/store:/var/lib/mysql
networks:
- network
backend:
build:
context: ./product
dockerfile: Dockerfile
restart: always
ports:
- 8080:8080
depends_on:
- db #db가 먼저 구축되고 나서 다 되면 server를 실행시키는 것을 의미한다.
environment: #해당 값들은 application-prod.yml에서 ${SPRING_DATASOURCE_URL} 에서 사용한다.
SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/metadb?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false&allowPublicKeyRetrieval=true
SPRING_DATASOURCE_DRIVER: com.mysql.cj.jdbc.Driver
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: root1234
networks: #동일 네트워크로 잡아주어야 datasource url에서 jdbc:mysql://db 로 쓸수있는 것이다. ip로 안쓰고..
- network
frontend:
build:
context: ./my-react-app-auto-build
dockerfile: Dockerfile
restart: always
ports:
- 80:80
depends_on:
- backend
networks:
- network
networks:
network:
[product(backend)] Dockerfile 전체코드
FROM openjdk:11-jdk-slim
WORKDIR /app
# COPY만 docker-compose 파일의 위치를 기반으로 작동함
COPY . .
# 개행문자 오류 해결 [unix와 window 시스템 차이]
RUN sed -i 's/\r$//' gradlew
# RUN은 현재 파일을 위치를 기반으로 작동함
RUN chmod +x ./gradlew
RUN ./gradlew clean build
ENV JAR_PATH=/app/build/libs
RUN mv ${JAR_PATH}/*.jar /app/app.jar
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=prod", "app.jar"]
[db] Dockerfile전체코드
FROM mysql:8.0
COPY init.sql /docker-entrypoint-initdb.d
ENV MYSQL_ROOT_PASSWORD=root1234
ENV MYSQL_DATABASE=metadb
ENV MYSQL_HOST=%
CMD ["--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci"]
[React] Dockerfile전체코드
FROM node:alpine as build
WORKDIR /app
COPY package.json /app
RUN npm install --silent
COPY . /app
RUN npm run build
FROM nginx
#--from=build는 위에있는 FROM으로 부터 이미지가 구워지는데 그 결과로 나온 것을 의미한다.
# 위에서 나온 결과물인 /app/build 를 /usr/share/nginx/html로 복사하라는 의미이다.
COPY --from=build /app/build /usr/share/nginx/html
#내가 커스텀한 nginx.conf파일로 넢어씌운다.
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
ENTRYPOINT ["nginx","-g","daemon off;"]
'코딩이야기 > Spring' 카테고리의 다른 글
도커 입문 25강 도커컴포즈 React 앱 만들어보기 (0) | 2024.07.20 |
---|---|
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured. 에러 회피방법 (0) | 2023.05.03 |