diff --git a/.github/workflows/backend-dev-ci-cd.yml b/.github/workflows/backend-dev-ci-cd.yml index e6de46050..f0e17ae60 100644 --- a/.github/workflows/backend-dev-ci-cd.yml +++ b/.github/workflows/backend-dev-ci-cd.yml @@ -7,12 +7,12 @@ on: - "backend/**" - ".github/workflows/backend-dev-ci-cd.yml" - "Dockerfile" - # pull_request: - # branches: [ "chongdae" ] - # paths: - # - "backend/**" - # - ".github/workflows/backend-dev-ci-cd.yml" - # - "Dockerfile" +# pull_request: +# branches: [ "develop" ] +# paths: +# - "backend/**" +# - ".github/workflows/backend-dev-ci-cd.yml" +# - "Dockerfile" jobs: @@ -80,5 +80,5 @@ jobs: steps: - name: Switch from old to new container run: | - bash switch_blue_green_container.sh + bash switch_blue_green_container.sh dev.default.conf working-directory: backend/deploy diff --git a/.github/workflows/backend-prod-ci-cd.yml b/.github/workflows/backend-prod-ci-cd.yml index 83b353135..1abcf213a 100644 --- a/.github/workflows/backend-prod-ci-cd.yml +++ b/.github/workflows/backend-prod-ci-cd.yml @@ -7,12 +7,12 @@ on: - "backend/**" - ".github/workflows/backend-prod-ci-cd.yml" - "Dockerfile" - # pull_request: - # branches: [ "develop" ] - # paths: - # - "backend/**" - # - ".github/workflows/backend-prod-ci-cd.yml" - # - "Dockerfile" +# pull_request: +# branches: [ "develop" ] +# paths: +# - "backend/**" +# - ".github/workflows/backend-prod-ci-cd.yml" +# - "Dockerfile" jobs: @@ -62,28 +62,23 @@ jobs: docker push ${{ secrets.BE_DOCKERHUB_USERNAME }}/${{ secrets.BE_DOCKER_IMAGE_NAME_PROD }}:${GITHUB_SHA::7} deploy-new-container: - needs: build-and-test - strategy: - matrix: - runner: [prod-a, prod-b] - runs-on: [ self-hosted, ${{ matrix.runner }} ] + needs: build-and-test + runs-on: [ self-hosted, prod ] steps: - name: Checkout repository uses: actions/checkout@v4 - - name: Deploy new container on ${{ matrix.runner }} + - name: Deploy new container run: | bash launch_next_container.sh ${GITHUB_SHA::7} prod ${{ secrets.BE_DOCKERHUB_USERNAME }} ${{ secrets.BE_DOCKER_IMAGE_NAME_PROD }} working-directory: backend/deploy switch-new-container: needs: deploy-new-container - strategy: - matrix: - runner: [prod-a, prod-b] - runs-on: [ self-hosted, ${{ matrix.runner }} ] + runs-on: [ self-hosted, prod ] + steps: - - name: Switch from old to new container on ${{ matrix.runner }} + - name: Switch from old to new container run: | - bash switch_blue_green_container.sh - working-directory: backend/deploy \ No newline at end of file + bash switch_blue_green_container.sh default.conf + working-directory: backend/deploy diff --git a/Dockerfile b/Dockerfile index c676ab6ec..9306571fc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=linux/arm64 amazoncorretto:17 +FROM --platform=linux/amd64 amazoncorretto:17 ENV TZ=Asia/Seoul diff --git a/backend/deploy/default.conf b/backend/deploy/default.conf index 6dfeddc86..c73e25c4d 100644 --- a/backend/deploy/default.conf +++ b/backend/deploy/default.conf @@ -1,14 +1,26 @@ upstream active_server { - server chongdae_backend:8080; + server chongdae_backend:8080; } server { listen 80; + server_name chongdae.site; + location / { - proxy_pass http://active_server; + proxy_pass http://active_server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } +server { + listen 80; + server_name image.chongdae.site; + + root /uploads; + + location / { + try_files $uri $uri/ =404; + } +} diff --git a/backend/deploy/dev.default.conf b/backend/deploy/dev.default.conf new file mode 100644 index 000000000..00d3bb12d --- /dev/null +++ b/backend/deploy/dev.default.conf @@ -0,0 +1,26 @@ +upstream active_server { + server chongdae_backend:8080; +} + +server { + listen 80; + server_name dev.chongdae.site; + + location / { + proxy_pass http://active_server; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } +} + +server { + listen 80; + server_name image.dev.chongdae.site; + + root /uploads; + + location / { + try_files $uri $uri/ =404; + } +} diff --git a/backend/deploy/launch_next_container.sh b/backend/deploy/launch_next_container.sh index 287d02326..d36eb1d7a 100755 --- a/backend/deploy/launch_next_container.sh +++ b/backend/deploy/launch_next_container.sh @@ -73,6 +73,7 @@ docker run -d \ --network ${INITIAL_BLUE_GREEN_NETWORK_NAME} \ --name ${NEXT_CONTAINER} \ -v /logs:/logs \ + -v /uploads:/uploads \ -e SPRING_PROFILES_ACTIVE=${PROFILE_ACTIVE} \ ${DOCKERHUB_USER_NAME}/${DOCKER_IMAGE_NAME}:${GITHUB_SHA:0:7} diff --git a/backend/deploy/setup.sh b/backend/deploy/setup.sh index e9812c79c..34ccbad11 100755 --- a/backend/deploy/setup.sh +++ b/backend/deploy/setup.sh @@ -3,9 +3,11 @@ GITHUB_SHA=$1 PROFILE_ACTIVE=$2 DOCKERHUB_USER_NAME=$3 DOCKER_IMAGE_NAME=$4 +NGINX_DEFAULT_CONF_NAME=$5 + # parameter check -if [ -z "$GITHUB_SHA" ] || [ -z "$PROFILE_ACTIVE" ] || [ -z "$DOCKERHUB_USER_NAME" ] || [ -z "$DOCKER_IMAGE_NAME" ]; then +if [ -z "$GITHUB_SHA" ] || [ -z "$PROFILE_ACTIVE" ] || [ -z "$DOCKERHUB_USER_NAME" ] || [ -z "$DOCKER_IMAGE_NAME" ] || [ -z "$NGINX_DEFAULT_CONF_NAME" ]; then echo "사용법: $0 " exit 1 fi @@ -13,7 +15,6 @@ fi # intialize blue & gren INITIAL_INSTANCE_NAME="chongdae_backend_green" INITIAL_BLUE_GREEN_NETWORK_NAME="blue_green_network" -NGINX_DEFAULT_CONF_PATH="default.conf" NGINX_NEW_CONF_PATH="new-default.conf" # 1. ADD DOCKER NETWORK @@ -31,6 +32,7 @@ docker run -d \ --network ${INITIAL_BLUE_GREEN_NETWORK_NAME} \ --name ${INITIAL_INSTANCE_NAME} \ -v /logs:/logs \ + -v /uploads:/uploads \ -e SPRING_PROFILES_ACTIVE=${PROFILE_ACTIVE} \ ${DOCKERHUB_USER_NAME}/${DOCKER_IMAGE_NAME}:${GITHUB_SHA:0:7} @@ -39,7 +41,7 @@ if [ $? -ne 0 ]; then fi # 3. CHANGE INITIAL UP STREAM SERVER -cp ${NGINX_DEFAULT_CONF_PATH} ${NGINX_NEW_CONF_PATH} +cp ${NGINX_DEFAULT_CONF_NAME} ${NGINX_NEW_CONF_PATH} if grep -q "server chongdae_backend:" "${NGINX_NEW_CONF_PATH}"; then sed -i "s/server chongdae_backend:/server ${INITIAL_INSTANCE_NAME}:/" "${NGINX_NEW_CONF_PATH}" @@ -51,6 +53,7 @@ docker run -d \ --network ${INITIAL_BLUE_GREEN_NETWORK_NAME} \ --name nginx \ -p 80:80 \ + -v /uploads:/uploads \ nginx:latest # 5. setup proxy in nginx container diff --git a/backend/deploy/switch_blue_green_container.sh b/backend/deploy/switch_blue_green_container.sh index 25402f9b0..1859661a9 100755 --- a/backend/deploy/switch_blue_green_container.sh +++ b/backend/deploy/switch_blue_green_container.sh @@ -1,8 +1,16 @@ #!/bin/bash +NGINX_DEFAULT_CONF=$1 + +# parameter check +if [ -z "$NGINX_DEFAULT_CONF" ]; then + echo "사용법: $0 " + exit 1 +fi + + NGINX_CONTAINER_NAME="nginx" BLUE_CONTAINER="chongdae_backend_blue" GREEN_CONTAINER="chongdae_backend_green" -NGINX_DEFAULT_CONF="default.conf" NGINX_CHANGED_DEFAULT_CONF="new-default.conf" get_active_container() { diff --git a/backend/src/main/java/com/zzang/chongdae/offering/service/dto/OfferingMetaResponse.java b/backend/src/main/java/com/zzang/chongdae/offering/service/dto/OfferingMetaResponse.java index 460c3cef9..5832acec1 100644 --- a/backend/src/main/java/com/zzang/chongdae/offering/service/dto/OfferingMetaResponse.java +++ b/backend/src/main/java/com/zzang/chongdae/offering/service/dto/OfferingMetaResponse.java @@ -3,7 +3,8 @@ import com.zzang.chongdae.offering.repository.entity.OfferingEntity; public record OfferingMetaResponse(String title, String thumbnailUrl) { - private static final String DEFAULT_THUMBNAIL_URL = "https://d3a5rfnjdz82qu.cloudfront.net/chongdae-market/images/common/no-image.png"; + + private static final String DEFAULT_THUMBNAIL_URL = "https://image.chongdae.site/common/no-image.png"; public OfferingMetaResponse(OfferingEntity offering) { this(offering.getTitle(), getOrDefault(offering.getThumbnailUrl())); diff --git a/backend/src/main/java/com/zzang/chongdae/storage/config/StorageConfig.java b/backend/src/main/java/com/zzang/chongdae/storage/config/StorageConfig.java index b5727959b..4c852e895 100644 --- a/backend/src/main/java/com/zzang/chongdae/storage/config/StorageConfig.java +++ b/backend/src/main/java/com/zzang/chongdae/storage/config/StorageConfig.java @@ -4,7 +4,7 @@ import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; -import com.zzang.chongdae.storage.service.AmazonS3StorageService; +import com.zzang.chongdae.storage.service.LocalStorageService; import com.zzang.chongdae.storage.service.StorageService; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -14,7 +14,7 @@ public class StorageConfig { @Bean public StorageService storageService() { - return new AmazonS3StorageService(amazonS3()); + return new LocalStorageService(); } private AmazonS3 amazonS3() { diff --git a/backend/src/main/java/com/zzang/chongdae/storage/service/LocalStorageService.java b/backend/src/main/java/com/zzang/chongdae/storage/service/LocalStorageService.java index e4da968f7..3f32605c5 100644 --- a/backend/src/main/java/com/zzang/chongdae/storage/service/LocalStorageService.java +++ b/backend/src/main/java/com/zzang/chongdae/storage/service/LocalStorageService.java @@ -25,16 +25,25 @@ public class LocalStorageService implements StorageService { @Value("${storage.path}") private String storagePath; + LocalStorageService(String redirectUrl, String storagePath) { + this.redirectUrl = redirectUrl; + this.storagePath = storagePath; + } + @Override public String uploadFile(MultipartFile file) { + String extension = getFileExtension(file); + validateFileExtension(extension); + String newFilename = UUID.randomUUID().toString(); + storeFile(file, newFilename); + return createUri(newFilename); + } + + private void storeFile(MultipartFile file, String newFilename) { try { - String extension = getFileExtension(file); - validateFileExtension(extension); - String newFilename = UUID.randomUUID() + "." + extension; Path uploadPath = Paths.get(storagePath); Path filePath = uploadPath.resolve(newFilename); Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING); - return createUri(filePath.toString()); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/backend/src/main/resources/application-dev.yml b/backend/src/main/resources/application-dev.yml index 7bee33ae5..db8e5b7cd 100644 --- a/backend/src/main/resources/application-dev.yml +++ b/backend/src/main/resources/application-dev.yml @@ -14,3 +14,7 @@ security: token: access-secret-key: ${JWT_ACCESS_SECRET_KEY} refresh-secret-key: ${JWT_REFRESH_SECRET_KEY} + +storage: + path: /uploads + redirectUrl: image.dev.chongdae.site \ No newline at end of file diff --git a/backend/src/main/resources/application-prod.yml b/backend/src/main/resources/application-prod.yml index ce19cf6ee..ae2396cca 100644 --- a/backend/src/main/resources/application-prod.yml +++ b/backend/src/main/resources/application-prod.yml @@ -19,3 +19,7 @@ security: token: access-secret-key: ${JWT_ACCESS_SECRET_KEY} refresh-secret-key: ${JWT_REFRESH_SECRET_KEY} + +storage: + path: /uploads + redirectUrl: image.chongdae.site \ No newline at end of file diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index ffeab0a95..164854d5d 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -46,10 +46,6 @@ amazon: redirectUrl: d3a5rfnjdz82qu.cloudfront.net storagePath: chongdae-market/images/offerings/product/ -storage: - path: /uploads - redirectUrl: image.chongdae.site - security: jwt: token: diff --git a/backend/src/test/java/com/zzang/chongdae/member/service/NicknameGeneratorTest.java b/backend/src/test/java/com/zzang/chongdae/member/service/NicknameGeneratorTest.java index 42e9f7a23..156c582de 100644 --- a/backend/src/test/java/com/zzang/chongdae/member/service/NicknameGeneratorTest.java +++ b/backend/src/test/java/com/zzang/chongdae/member/service/NicknameGeneratorTest.java @@ -7,7 +7,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.ActiveProfiles; +@ActiveProfiles("test") @SpringBootTest(webEnvironment = WebEnvironment.NONE, classes = {TestNicknameWordPickerConfig.class}) public class NicknameGeneratorTest { diff --git a/backend/src/test/resources/application-test.yml b/backend/src/test/resources/application-test.yml index 47e4f02e4..abe554500 100644 --- a/backend/src/test/resources/application-test.yml +++ b/backend/src/test/resources/application-test.yml @@ -11,6 +11,7 @@ spring: properties: hibernate: format_sql: true + security: jwt: token: @@ -22,3 +23,7 @@ security: fcm: secret-key: path: /fcm/chongdaemarket-fcm-key.json + +storage: + path: /uploads + redirectUrl: fake.image.chongdae.site \ No newline at end of file