Backend
home
🕛

2024. 9. 25 (Docker, CI/CD)

생성일
2025/01/24 05:52
태그

Dockerfile 생성

# Node 이미지 FROM node:20 AS build # 컨테이너 내 작업 디렉토리 설정 WORKDIR /app # package.json 과 package-lock.json 파일 복사 COPY package*.json ./ # 의존성 설치 RUN npm update RUN npm install # 모든 소스 코드를 컨테이너로 복사 COPY . . # REACT 앱 빌드 RUN npm run build # Nginx 이미지 FROM nginx:alpine # Nginx 설정 파일 복사 COPY nginx.conf /etc/nginx/conf.d/default.conf # Nginx 기본 파일 삭제 RUN rm -rf /usr/share/nginx/html/* # 빌드 결과물을 Nginx 디렉토리로 복사 COPY --from=build /app/build /usr/share/nginx/html # 포트를 외부로 노출 EXPOSE 80 # nginx 서버 실행 CMD ["nginx", "-g", "daemon off;"]
Shell
복사

Nginx.conf 생성

server { listen 80; server_name localhost; root /usr/share/nginx/html; index index.html; location / { try_files $uri $uri/ /index.html; } }
Shell
복사

docker 액세스 토큰 만들기

react 빌드하기 위한 명령어 실행

docker build -t music-image ./music_react/ docker ps docker images docker run -d --name music-container -p 80:80 music-image docker ps curl localhost:80
Shell
복사

JPA 프로젝트 실행

Dockerfile
# 빌드 FROM gradle:7.5.1-jdk17-alpine AS build # 작업 디렉토리 설정 WORKDIR /app # Gradle 파일만 복사 COPY build.gradle settings.gradle gradlew ./ # 프로젝트 전체 파일 복사 COPY . . # gradlew 파일 실행 권한 부여 RUN chmod +x gradlew # 빌드 실행 (테스트 제외) RUN ./gradlew clean build -x test # 런타임 openjdk 이미지 FROM openjdk:17-jdk-alpine # 작업 디렉토리 WORKDIR /app # 빌드 단계에서 생성된 jar 파일을 복사 COPY --from=build /app/build/libs/*.jar /app/app.jar # 포트 노출 EXPOSE 8080 # 애플리케이션 실행 ENTRYPOINT [ "java", "-jar", "/app/app.jar" ]
Shell
복사
Git global settings
hms@ubuntu:~/Desktop/2024-docker-repository$ git config --global user.name codesche hms@ubuntu:~/Desktop/2024-docker-repository$ git config --global user.email codesche@gmail.com hms@ubuntu:~/Desktop/2024-docker-repository$ git config credential.helper store
Shell
복사
docker 이미지 실행 및 스프링부트 실행
docker build -t jpa-image . docker run --name jpa-container -p 8080:8080 jpa-image
Shell
복사
hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker build -t jpa-image . DEPRECATED: The legacy builder is deprecated and will be removed in a future release. Install the buildx component to build images with BuildKit: https://docs.docker.com/go/buildx/ Sending build context to Docker daemon 107.5kB Step 1/11 : FROM gradle:7.5.1-jdk17-alpine AS build ---> d627daef538e Step 2/11 : WORKDIR /app ---> Using cache ---> ed43e381b5fb Step 3/11 : COPY build.gradle settings.gradle gradlew ./ ---> Using cache ---> 6309460bd527 Step 4/11 : COPY . . ---> 7930e9331255 Step 5/11 : RUN chmod +x gradlew ---> Running in df2f40794c09 Removing intermediate container df2f40794c09 ---> f9adc9cb29d5 Step 6/11 : RUN ./gradlew clean build -x test ---> Running in ea04c7031846 Downloading https://services.gradle.org/distributions/gradle-8.8-bin.zip .............10%.............20%.............30%.............40%.............50%.............60%..............70%.............80%.............90%.............100% Welcome to Gradle 8.8! Here are the highlights of this release: - Running Gradle on Java 22 - Configurable Gradle daemon JVM - Improved IDE performance for large projects For more details see https://docs.gradle.org/8.8/release-notes.html Starting a Gradle Daemon (subsequent builds will be faster) > Task :clean UP-TO-DATE > Task :compileJava > Task :processResources > Task :classes > Task :resolveMainClassName > Task :bootJar > Task :jar > Task :assemble > Task :check > Task :build BUILD SUCCESSFUL in 57s 6 actionable tasks: 5 executed, 1 up-to-date Removing intermediate container ea04c7031846 ---> 0c78f6f42361 Step 7/11 : FROM openjdk:17-jdk-alpine ---> 264c9bdce361 Step 8/11 : WORKDIR /app ---> Using cache ---> 8ca8833264e0 Step 9/11 : COPY --from=build /app/build/libs/jpa_proj-0.0.1-SNAPSHOT.jar /app/app.jar ---> 60864c5d0a3b Step 10/11 : EXPOSE 8080 ---> Running in ff197342336c Removing intermediate container ff197342336c ---> 6c12d09eddca Step 11/11 : ENTRYPOINT [ "java", "-jar", "/app/app.jar" ] ---> Running in 0972f0c681a8 Removing intermediate container 0972f0c681a8 ---> af8f08f79ac6 Successfully built af8f08f79ac6 Successfully tagged jpa-image:latest hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bc85b6db7d90 music-image "/docker-entrypoint.…" 56 minutes ago Up 56 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp music-container hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE jpa-image latest af8f08f79ac6 57 seconds ago 384MB <none> <none> 0c78f6f42361 58 seconds ago 647MB <none> <none> 94e8fdf8e92d 5 minutes ago 647MB <none> <none> a5ad326e9d17 10 minutes ago 647MB <none> <none> acfefaaec89f 14 minutes ago 647MB music-image latest cbe0f740d7c6 59 minutes ago 43.8MB <none> <none> 544f78446b34 59 minutes ago 1.78GB <none> <none> b41a05284092 About an hour ago 1.78GB <none> <none> c2e939b5b247 About an hour ago 1.78GB node 20 dd223fd5024d 4 weeks ago 1.1GB nginx alpine c7b4f26a7d93 5 weeks ago 43.2MB gradle 7.5.1-jdk17-alpine d627daef538e 22 months ago 589MB openjdk 17-jdk-alpine 264c9bdce361 3 years ago 326MB hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker run --name jpa-container -p 8080:8080 jpa-image
Shell
복사
none 이미지 확인
docker images -q -f "dangling=true" # none 이미지 전부 삭제 docker rmi $(docker images -q -f "dangling=true")
Shell
복사
mysql 설치
# 최신 버전 받아오기 docker pull mysql # container 실행 hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker run -d \ > --name mysql-container \ > -e MYSQL_ROOT_PASSWORD=1234 \ > -e MYSQL_DATABASE=jpa_db \ > -e MYSQL_USER=minsung \ > -p 3306:3306 \ > -e TZ=Asia/Seoul \ > mysql hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 07407594e304 mysql "docker-entrypoint.s…" 11 seconds ago Up 10 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql-container bc85b6db7d90 music-image "/docker-entrypoint.…" About an hour ago Up About an hour 0.0.0.0:80->80/tcp, :::80->80/tcp music-container hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 07407594e304 mysql "docker-entrypoint.s…" 16 seconds ago Up 15 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql-container b68d392ca033 jpa-image "java -jar /app/app.…" 23 minutes ago Exited (1) 22 minutes ago jpa-container bc85b6db7d90 music-image "/docker-entrypoint.…" About an hour ago Up About an hour 0.0.0.0:80->80/tcp, :::80->80/tcp music-container hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker run \ > -p 8080:8080 \ > --name jpa-container \ > -e SPRING_DATASOURCE_URL=jdbc:mysql://localhost:3306/jpa_db \ > -e SPRING_DATASOURCE_USERNAME=root \ > -e SPRING_DATASOURCE_PASSWORD=1234 \ > jpa-image
Shell
복사
통신을 위한 네트워크 브릿지 생성 후 실행 (백그라운드 실행 X)
docker run -d --name mysql-container -e MYSQL_ROOT_PASSWORD=1234 -e MYSQL_DATABASE=jpa_db -e MYSQL_USER=inkyu -p 3306:3306 -e TZ=Asia/Seoul --network jpa-network mysql docker run -p 8080:8080 --name jpa-container -e SPRING_DATASOURCE_URL=jdbc:mysql://mysql-container:3306/jpa_db -e SPRING_DATASOURCE_USERNAME=root -e SPRING_DATASOURCE_PASSWORD=1234 --network jpa-network jpa-image
Shell
복사
백그라운드 실행 (-d 추가)
hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker rm jpa-container jpa-container hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker run -p 8080:8080 --name jpa-container -e SPRING_DATASOURCE_URL=jdbc:mysql://mysql-container:3306/jpa_db -e SPRING_DATASOURCE_USERNAME=root -e SPRING_DATASOURCE_PASSWORD=1234 --network jpa-network -d jpa-image eb052d2bf7af7a6e987759d2fa6b9a6783e05b436ece9f5477b2f6874aa43212 hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES eb052d2bf7af jpa-image "java -jar /app/app.…" 2 seconds ago Up 1 second 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp jpa-container 6632d264ad8c mysql "docker-entrypoint.s…" 7 minutes ago Up 7 minutes 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql-container bc85b6db7d90 music-image "/docker-entrypoint.…" 2 hours ago Up 2 hours 0.0.0.0:80->80/tcp, :::80->80/tcp music-container
Shell
복사

다시 리셋

hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker stop jpa-container jpa-container hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker stop mysql-container mysql-container hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker rm jpa-container mysql-container jpa-container mysql-container hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE jpa-image latest af8f08f79ac6 56 minutes ago 384MB music-image latest cbe0f740d7c6 2 hours ago 43.8MB node 20 dd223fd5024d 4 weeks ago 1.1GB nginx alpine c7b4f26a7d93 5 weeks ago 43.2MB mysql latest c757d623b190 2 months ago 586MB gradle 7.5.1-jdk17-alpine d627daef538e 22 months ago 589MB openjdk 17-jdk-alpine 264c9bdce361 3 years ago 326MB hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker rmi mysql:latest jpa-image:latest Untagged: mysql:latest Untagged: mysql@sha256:92dc869678019f65d761155dacac660a904f6245bfe1b7997da0a73b2bfc68c9 Deleted: sha256:c757d623b1901eeba266f635e7e99cac9ae52bf30ab2056efa09219038dfcc1b Deleted: sha256:b5bc0c3e9adfa6e1541329a87af5cc2b24e86a0af3fc9936174aab8551574eeb Deleted: sha256:20b8c1562e07bf85ef98d73b57fa00ede8ca66919202650c1d29e14af7403b09 Deleted: sha256:64a842e084b1d7aaa261fe8032ecc3e86c962462fde38b0e47e5bbc42b074201 Deleted: sha256:51db1c8300ac6e0504cc2029f2be6a05ad15d5c9041874e2c62d98ba6050a4d0 Deleted: sha256:a2f616941660bf2adca993ace01f71bc6f75b0aa21c2c7431a5e17c483b5fe18 Deleted: sha256:4f01f7d3cadf4f3120f1543a6eedcd5e7204a5c8601c51bca1fd497f4a26e13e Deleted: sha256:6082fb9b6e5f6aa21f2f26fe6781b863d4e58d8b425f8674e8e02ba11c0ea8d8 Deleted: sha256:79a33bf591be05d818d23f67898d5faa5fe253ffe96bf858c76c8566bf835715 Deleted: sha256:327789e29057642f5133a238ab5d5c4ae8cc1a5ed2e3af076f0477ab76cce9f8 Deleted: sha256:664144bd1f243d56de6413950a57ce17fd9d25e925a8e06c4771cc4fb2fdbb50 Untagged: jpa-image:latest Deleted: sha256:af8f08f79ac69a04f72792f85f7b267bdf9538a79420a9b87918c6358421cbeb Deleted: sha256:6c12d09eddca2811cec74ff8393c397fd5f314923d28c617c8f9dc3e0754f49f Deleted: sha256:60864c5d0a3bc5664868d2bb84be1071a927b6257348e76dd603e730f4d1b130 Deleted: sha256:e94b29ed4310f157962d9262c663ac1b8759fe8ebd3a1418a3d4821f3c12af37 Deleted: sha256:8ca8833264e052e387de13cb554d6fda4941256c057072e2a64be7e4db531113 Deleted: sha256:680fe331d030590b0f6832239047d9a8b4c09329563a7df5ceac6ebecf74cafb hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE music-image latest cbe0f740d7c6 2 hours ago 43.8MB node 20 dd223fd5024d 4 weeks ago 1.1GB nginx alpine c7b4f26a7d93 5 weeks ago 43.2MB gradle 7.5.1-jdk17-alpine d627daef538e 22 months ago 589MB openjdk 17-jdk-alpine 264c9bdce361 3 years ago 326MB hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ # Docker 네트워크 쪽 정리 hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker network ls NETWORK ID NAME DRIVER SCOPE 81e2e1ded856 bridge bridge local a801247236dd host host local fc5689946292 none null local f905d657aec3 wordpress-compose_default bridge local hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker network rm f9 f9 hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker network ls NETWORK ID NAME DRIVER SCOPE 81e2e1ded856 bridge bridge local a801247236dd host host local fc5689946292 none null local
Shell
복사

docker-compose.yml 생성

# Docker-compose : 다수의 컨테이너를 일괄적으로 정의하고 실행하는 도구 # Docker-compose는 YAML 형태로 작성해서 Docker 명령으로 해석된다. # 버전에 따라 문법이 다르다. (불편...) version: '3' services: mysql: image: mysql:latest container_name: mysql-container environment: - MYSQL_ROOT_PASSWORD=1234 - MYSQL_DATABASE=jpa_db - MYSQL_USER=codesche - MYSQL_PASSWORD=1234 - TZ=Asia/Seoul ports: - "3306:3306" networks: - jpa-network jpa-app: image: jpa-image container_name: jpa-container build: context: . ports: - "8080:8080" environment: - SPRING_DATASOURCE_URL=jdbc:mysql://mysql-container:3306/jpa_db - SPRING_DATASOURCE_USERNAME=root - SPRING_DATASOURCE_PASSWORD=1234 networks: - jpa-network restart: always networks: jpa-network: driver: bridge
Shell
복사
참고로 build 진행하기에 앞서 로컬에서 해당 명령어 실행하여 build 폴더 생성해주어야 함
./gradlew clean buildlo
Shell
복사
docker-compose up -d —build 명령어 입력
hms@ubuntu:~/Desktop/2024-docker-repository/jpa_proj$ docker-compose up -d --build Creating network "jpa_proj_jpa-network" with driver "bridge" Pulling mysql (mysql:latest)... latest: Pulling from library/mysql eba3c26198b7: Pull complete fc6c33853069: Pull complete f1fa3ee22bea: Pull complete 5b8b24615ae8: Pull complete cded0449fb1a: Pull complete 095378692b4a: Pull complete 110d87e5d2a3: Pull complete bd1dbbbda514: Pull complete 982f92841ea3: Pull complete de34c1fda3aa: Pull complete Digest: sha256:92dc869678019f65d761155dacac660a904f6245bfe1b7997da0a73b2bfc68c9 Status: Downloaded newer image for mysql:latest Building jpa-app Step 1/11 : FROM gradle:7.5.1-jdk17-alpine AS build ---> d627daef538e Step 2/11 : WORKDIR /app ---> Running in 8c7a9052667d Removing intermediate container 8c7a9052667d ---> 6a3670627287 Step 3/11 : COPY build.gradle settings.gradle gradlew ./ ---> 98e3aa43a5c1 Step 4/11 : COPY . . ---> df880cf6566b Step 5/11 : RUN chmod +x gradlew ---> Running in 0053c33b8e35 Removing intermediate container 0053c33b8e35 ---> 2afea322d709 Step 6/11 : RUN ./gradlew clean build -x test ---> Running in 51a7fe0a4902 Downloading https://services.gradle.org/distributions/gradle-8.8-bin.zip .............10%.............20%.............30%.............40%.............50%.............60%..............70%.............80%.............90%.............100% Welcome to Gradle 8.8! Here are the highlights of this release: - Running Gradle on Java 22 - Configurable Gradle daemon JVM - Improved IDE performance for large projects For more details see https://docs.gradle.org/8.8/release-notes.html Starting a Gradle Daemon (subsequent builds will be faster) > Task :clean UP-TO-DATE > Task :compileJava > Task :processResources > Task :classes > Task :resolveMainClassName > Task :bootJar > Task :jar > Task :assemble > Task :check > Task :build BUILD SUCCESSFUL in 56s 6 actionable tasks: 5 executed, 1 up-to-date Removing intermediate container 51a7fe0a4902 ---> 6f86ba7154f6 Step 7/11 : FROM openjdk:17-jdk-alpine ---> 264c9bdce361 Step 8/11 : WORKDIR /app ---> Running in c69aa75f58fc Removing intermediate container c69aa75f58fc ---> c0d0ed70f404 Step 9/11 : COPY --from=build /app/build/libs/jpa_proj-0.0.1-SNAPSHOT.jar /app/app.jar ---> 619b19092a70 Step 10/11 : EXPOSE 8080 ---> Running in fa47282eadf0 Removing intermediate container fa47282eadf0 ---> f5b55c214039 Step 11/11 : ENTRYPOINT [ "java", "-jar", "/app/app.jar" ] ---> Running in 3fecdb12d22b Removing intermediate container 3fecdb12d22b ---> f87211135d91 Successfully built f87211135d91 Successfully tagged jpa-image:latest Creating jpa-container ... done Creating mysql-container ... done
Shell
복사
잘못입력한 경우
# 삭제까지 깔끔하게 진행됨 - 해당 명령어 입력 후 위 과정 재진행 docker-compose down
Shell
복사
로그 입력
docker logs -f jpa-container
Shell
복사

다시 리셋

docker ps docker stop jpa-container docker stop mysql-container ls cd rest_shopping/ docker-compose down docker ps -a docker rm bc85 docker stop bc85 docker rm bc85 docker images # 이미지 전체 삭제 docker rmi $(docker images -q)
Shell
복사

다시 빌드

hms@ubuntu:~/Desktop/2024-docker-repository/rest_shopping$ docker-compose up --build
Shell
복사

Docker Tag 관련

docker info # 이미지가 없어도 기존 jpa-image를 살아있는 태그 통해 불러올 수 있음 docker tag jpa-image:latest codesche/shopping docker images docker push codesche/shopping docker rmi $(docker images -q) docker ps -a docker rm jpa-container mysql-container docker rmi $(docker images -q) docker ps -a docker images docker images; docker rmi -f $(docker images -q) docker images # docker pull (당겨 당겨~~) docker pull codesche/shopping
Shell
복사

리소스 제한 (성능 테스트)

도커 명령어를 통해서 제한할 수 있는 리소스
CPU, Memory, DISK I/O
메모리 리소스 제한
-m 또는 —memory 옵션 : 최대 메모리 지정
해당 명령어 실행 - docker run -d -m 512m nginx
bash 쉘 접속
# 기존에 생성된 bold_hugle 라는 컨테이너를 가지고 bash 쉘 접속하기 docker exec -it bold_hugle /bin/bash # 업데이트 apt-get update # 부하 테스트 위해 stress 설치 apt-get install -y stress # container 현황 - bash shell이 아인 다른 터미널(별도의 터미널)에서 실행 docker stats bold_hugle # 5초 동안 400M 부하를 주기 root@a0d20b1a8a2e:/# stress --vm 1 --vm-bytes 400M --timeout 5s
Shell
복사
nginx run (image는 살아있음) → /bin/bash 접속 후 stress 재설치한 다음 테스트
hms@ubuntu:~$ docker run -d --cpus=".5" --name stress nginx root@a0d20b1a8a2e:/# stress --vm 1 --vm-bytes 400M --timeout 5s ## 다른 터미널에서 해당 명령어 실행 docker stats stress
Shell
복사
읽기 / 쓰기 속도 테스트
ubuntu
# read, write 속도 조정하여 명령어 입력 docker run -it --rm --device-write-bps /dev/sda:10mb --device-read-bps /dev/sda:10mb nginx /bin/bash # container 현황 확인 docker stats modest_keldysh
Shell
복사
/bin/bash
apt-get update & apt-get install -y stress # 강제로 부하 생성 root@00f4a5d05ef4:/# dd if=/dev/zero of=/tmp/testfile bs=1M count=10 oflag=direct
Shell
복사

blog repository 생성 (소셜 로그인 기능 관련 프론트, 백엔드 배포)

git 절차 생략 (아이디 / 비밀번호)
git config credential.helper store
Shell
복사
소셜 로그인의 원활한 절차 위해 카카오 개발자 사이트에서 Redirect URI 수정

배포 작업 (front + back)

env 상세 정보 수정
env 파일 REACT_APP_REST_SERVER=http://192.168.233.128/api REACT_APP_SERVER=http://192.168.233.128 REACT_APP_GOOGLE_ID=530115480345-84amh51vqf0h8iq9h06o9qu3g8e0s9np.apps.googleusercontent.com REACT_APP_GOOGLE_REDIRECT_URI=http://192.168.233.128/oauth/google REACT_APP_KAKAO_ID=4657494a26f9593e1ccf9a48e85c25ca REACT_APP_KAKAO_REDIRECT_URI=http://192.168.233.128/oauth/kakao
Shell
복사
yml 파일
spring: application: name: rest_blog datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/rest_blog_db username: root password: 1234 jpa: generate-ddl: true show-sql: true open-in-view: false sql: init: mode: never upload: location: /home/hms/image jwt: issuer: kosta-hms secret_key: mysecrethmsmysecrethmsmysecrethmsmysecrethmsmysecrethms access_duration: 5000 # 1800000 # 30분 (30 * 60 * 1000) refresh_duration: 8640000 # 24시간 (24 * 60 * 60 * 1000) oauth2: clients: google: client-id: client-secret: redirect-uri: token-uri: user-info-request-uri: kakao: client-id: client-secret: redirect-uri: token-uri: user-info-request-uri:
YAML
복사
WebMvcConfig, SecurityConfig 수정
package com.kosta.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration @EnableWebMvc public class WebMvcConfig implements WebMvcConfigurer { // application.yml 파일의 location 정보 가져오기 @Value("${spring.upload.location}") private String uploadPath; @Override public void addCorsMappings(CorsRegistry registry) { registry .addMapping("/**") .allowedOrigins("http://localhost:3000", "http://172.30.1.30:3000", "http://192.168.233.128") .allowedMethods("OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE"); } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry .addResourceHandler("/img/**") .addResourceLocations("file:"+ uploadPath + "\\"); } }
Java
복사
package com.kosta.config; import com.kosta.repository.UserRepository; import com.kosta.security.*; import com.kosta.util.TokenUtils; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.annotation.web.configurers.HttpBasicConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfigurationSource; import java.util.Collections; @Configuration @EnableWebSecurity @RequiredArgsConstructor public class WebSecurityConfig { private final UserDetailsService userDetailsService; private final UserRepository userRepository; private final JwtProperties jwtProperties; // JWT Provider private JwtProvider jwtProvider() { return new JwtProvider(jwtProperties, userDetailsService); } private TokenUtils tokenUtils() { return new TokenUtils(jwtProvider()); } private JwtAuthenticationService jwtAuthenticationService() { return new JwtAuthenticationService(tokenUtils(), userRepository); } @Bean // 인증 관리자 (AuthenticationManager) 설정 AuthenticationManager authenticationManager() { DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); authProvider.setUserDetailsService(userDetailsService); authProvider.setPasswordEncoder(bCryptPasswordEncoder()); return new ProviderManager(authProvider); } // 암호화 빈 @Bean BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); } // HTTP 요청에 따른 보안 구성 @Bean SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // 경로 권한 설정 http.authorizeHttpRequests(auth -> // 특정 URL 경로에 대해서는 인증 없이 접근 가능 auth.requestMatchers( new AntPathRequestMatcher("/api/oauth/**"), // oAuth 처리 (20240919) new AntPathRequestMatcher("/api/auth/signup"), // 회원가입 new AntPathRequestMatcher("/api/auth/duplicate"), // 이메일 중복체크 new AntPathRequestMatcher("/img/**"), // 이미지 new AntPathRequestMatcher("/api/auth/refresh-token"), // 토큰 재발급 new AntPathRequestMatcher("/api/post/**", "GET") ).permitAll() // AuthController 중 나머지들은 "ADMIN"만 가능 .requestMatchers( new AntPathRequestMatcher("/api/auth/") // "ADMIN"만 가능 ).hasRole("ADMIN") // 그 밖의 다른 요청들은 인증을 통과한(로그인한) 사용자라면 모두 접근할 수 있도록 한다. .anyRequest().authenticated() ); // 무상태성 세션 관리 http.sessionManagement((sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))); // 특정 경로(로그인)에 대한 필터 추가 http.addFilterBefore(new LoginCustomAuthenticationFilter(authenticationManager(), jwtAuthenticationService()), UsernamePasswordAuthenticationFilter.class); // (토큰을 통해 검증할 수 있도록) 필터 추가 http.addFilterBefore(new JwtAuthenticationFilter(jwtProvider()), UsernamePasswordAuthenticationFilter.class); // HTTP 기본 설정 http.httpBasic(HttpBasicConfigurer::disable); // CSRF 비활성화 http.csrf(AbstractHttpConfigurer::disable); // CORS 비활성화 (나중에 변경) // http.cors(AbstractHttpConfigurer::disable); // CORS 설정 http.cors(corsConfig -> corsConfig.configurationSource(corsConfigurationSource())); return http.getOrBuild(); } @Bean CorsConfigurationSource corsConfigurationSource() { return request -> { CorsConfiguration config = new CorsConfiguration(); config.setAllowedHeaders(Collections.singletonList("*")); config.setAllowedMethods(Collections.singletonList("*")); config.setAllowedOriginPatterns(Collections.singletonList("http://192.168.233.128")); config.setAllowCredentials(true); return config; }; } }
Java
복사