๐Ÿ–ฅ๏ธ Github-actions, Code-Deploy, Docker, Nginx, EC2, RDS, S3, ALB ์„œ๋ฒ„ ๋ฐฐํฌ

yeopยท2023๋…„ 5์›” 24์ผ

๐ŸŒ€ Deploy Flow

  1. Github main branch Push
  2. Github Actions workflow ์‹คํ–‰
    • Github Secrets๋ฅผ ํ†ตํ•œ application.properties ํŒŒ์ผ ์ƒ์„ฑ
    • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋นŒ๋“œ
    • S3์— ํŒŒ์ผ ์—…๋กœ๋“œ(๋นŒ๋“œ ํŒŒ์ผ, ๋„์ปค ํŒŒ์ผ, appspec, sh ํŒŒ์ผ ๋“ฑ)
    • CodeDeploy์— ๋ฐฐํฌ ์š”์ฒญ
  3. EC2 ๋‚ด๋ถ€์˜ CodeDeploy Agent์—๊ฒŒ ๋ฐฐํฌ ์š”์ฒญ์ด ์˜ค๋ฉด appspec.yml ํŒŒ์ผ ์‹คํ–‰
    • deploy.sh ํŒŒ์ผ ์‹คํ–‰
      - ๋ธ”๋ฃจ, ๊ทธ๋ฆฐ ์—ฌ๋ถ€์— ๋”ฐ๋ผ์„œ docker-compose.blue.yml ๋˜๋Š” docker-compose.green.yml ์‹คํ–‰
      • docker-compose ํŒŒ์ผ์— ์˜ํ•ด์„œ Dockerfile์„ ๋ฐ”ํƒ•์œผ๋กœ build ํ›„ ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰
      • ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰์‹œ ENTRYPOINT๋กœ ์„ ์–ธํ•ด๋†“์€ ๋ช…๋ น์–ด๊ฐ€ ์‹คํ–‰๋˜๋ฉด์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰

๐ŸŒ€ Request Flow

  1. ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์ด ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ์— ์ „๋‹ฌ
    • ํด๋ผ์ด์–ธํŠธ๊ฐ€ Http๋กœ ์š”์ฒญํ•  ๋•Œ
      • ๊ธฐ์กด : ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ๊ฐ€ Https๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ํ•œ ๋‹ค์Œ ์›น ์„œ๋ฒ„(Nginx)์—๊ฒŒ Https๋ฅผ ํ•ด์ œํ•ด์„œ Http๋กœ ๋„˜๊ธด๋‹ค

      • ์ˆ˜์ • ํ›„ : ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ์—์„œ๋Š” ์ƒํƒœ ์ฝ”๋“œ 301๋กœ๋งŒ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ๋˜์–ด Get๋ฉ”์„œ๋“œ๋กœ ์žฌ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉฐ ์ด๋Š” 415 Method Not Allowed ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

        -> ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ๋Š” Http ๊ทธ๋Œ€๋กœ ํ†ต๊ณผํ•œ ํ›„ Nginx์—์„œ 308 Https๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•œ๋‹ค.

    • ํด๋ผ์ด์–ธํŠธ๊ฐ€ Https๋กœ ์š”์ฒญํ•  ๋•Œ
      • ์›น ์„œ๋ฒ„์—๊ฒŒ Https๋ฅผ ํ•ด์ œํ•ด์„œ Http๋กœ ๋„˜๊ธด๋‹ค.

์›น ์„œ๋ฒ„์— Http๋กœ ๋„˜๊ธฐ๋Š” ์ด์œ 

  • ๋กœ๋“œ ๋ฐธ๋Ÿฐ์„œ์™€ ํด๋ผ์ด์–ธํŠธ์™€์˜ ํ†ต์‹ ์—์„œ ๋ณด์•ˆ์„ ์œ ์ง€ํ•˜๋ฉด์„œ๋„ ๋‚ด๋ถ€ ์›น ์„œ๋ฒ„์™€์˜ ํ†ต์‹ ์—์„œ๋Š” ์•”ํ˜ธํ™” ๋น„์šฉ์„ ์ ˆ๊ฐํ•  ์ˆ˜ ์žˆ์–ด ํšจ์œจ์ ์ด๋‹ค.
  1. Nginx๋กœ Http ์š”์ฒญ ์ „๋‹ฌ
  2. ๋„์ปค ์ปจํ…Œ์ด๋„ˆ 8081 ๋˜๋Š” 8082 ํฌํŠธ๋กœ ์ „๋‹ฌ
    • ๋ถˆํ•„์š”ํ•œ 3, 4-way-handshake๊ฐ€ ๊ณ„์†ํ•ด์„œ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด keepalive, keepalive_timeout ๊ณ ๋ คํ•˜๊ธฐ
  3. ๋„์ปค์—์„œ 8080์œผ๋กœ ์—ฐ๊ฒฐ

โ“ ์—๋Ÿฌ ์ •๋ฆฌ

โœ”๏ธ ๊นƒํ—ˆ๋ธŒ ์›Œํฌ ํ”Œ๋กœ์šฐ ์—๋Ÿฌ

syntax error near unexpected token '('

  • application.properties ํŒŒ์ผ ๋‚ด์—์„œ ์ฃผ์„ ์ฒ˜๋ฆฌํ•œ ๋ถ€๋ถ„์— '('๊ฐ€ ์žˆ์–ด๋„ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

contextLoads() FAILED
    java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:98
        Caused by: org.springframework.beans.factory.BeanCreationException at AbstractAutowireCapableBeanFactory.java:1804
            Caused by: javax.persistence.PersistenceException at AbstractEntityManagerFactoryBean.java:421
                Caused by: org.hibernate.exception.JDBCConnectionException at SQLStateConversionDelegate.java:112
                    Caused by: com.mysql.cj.jdbc.exceptions.CommunicationsException at SQLError.java:174
                        Caused by: com.mysql.cj.exceptions.CJCommunicationsException at NativeConstructorAccessorImpl.java:-2
                            Caused by: java.net.ConnectException at PlainSocketImpl.java:-2
  • build ์ง„ํ–‰ ์ค‘ test์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ
  • build.gradle ํŒŒ์ผ์— Junit์„ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ์„ ์–ธ ํ›„ test ์ฝ”๋“œ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ๋ฐœ์ƒ
  • ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•
    • build.gradle์— test task ์„ ์–ธํ•œ ํŒŒํŠธ ์ œ๊ฑฐ
    • Github action workflow์— ./gradlew build -x test ์™€ ๊ฐ™์ด ํ…Œ์ŠคํŠธ ๋ฌด์‹œ ์ปค๋ฉ˜๋“œ ์ถ”๊ฐ€

An error occurred (DeploymentLimitExceededException) when calling the CreateDeployment operation: The Deployment Group '~~~' already has an active Deployment 'd-6USSQTOMN'
  • CodeDeploy์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ
  • ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ ์ž ํ•˜๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์ด๋ฏธ ๊ฐ™์€ ํŒŒ์ผ์ด ์กด์žฌํ•  ๊ฒฝ์šฐ ํ•ด๋‹น ์—๋Ÿฌ ๋ฐœ์ƒ
  • ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•
    • appspec.yml ํŒŒ์ผ์— ๋ฎ์–ด์“ฐ๊ธฐ ์„ค์ • ์ถ”๊ฐ€
    • file_exists_behavior: OVERWRITE

  • ๋Œ€๋ถ€๋ถ„์˜ ์—๋Ÿฌ๋Š” ์˜คํƒ€!! ํŒŒ์ผ๋ช…, ํฌํŠธ ๋ถˆ์ผ์น˜!!

โœ”๏ธ NGINX ์—๋Ÿฌ

502 BadGateway

  • ๋‹ค์–‘ํ•œ ์ด์œ ๊ฐ€ ์žˆ์ง€๋งŒ ๋‚˜์˜ ๊ฒฝ์šฐ์—๋Š” ํ•˜๋‚˜์˜ server ๋ธ”๋ก ์•ˆ์—์„œ location ๋ธ”๋ก์ด ์„ ์–ธ๋˜์–ด์žˆ๋Š” cond.f/default.conf ์„ include ํ•˜๊ณ  location ๋ธ”๋ก์„ ํ•˜๋‚˜ ๋” ์„ ์–ธํ•˜๋ฉด์„œ proxy_pass ๊ฐ€ ๋น„์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•ด ๋ฐœ์ƒํ–ˆ๋‹ค.
  • ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•
    • cond.f/default.conf๊ณผ nginx.conf ํŒŒ์ผ ํ†ตํ•ฉ

415 Method Not Allowed

  • CORS ๋ฌธ์ œ
  • ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•
    • Server ๋ธ”๋ก ๋‚ด location ๋ธ”๋ก์— ๋‹ค์Œ ์ฝ”๋“œ ์ถ”๊ฐ€
    location / {
            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PATCH, OPTIONS';
                add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
                add_header 'Access-Control-Max-Age' 86400;
            }
            add_header 'Access-Control-Allow-Origin' '*' always;
        }

Post Request๊ฐ€ Get Request๋กœ ๋ฐ”๋€Œ์–ด์„œ ๋‚˜๊ฐ€๋Š” ๋ฌธ์ œ

  • https๊ฐ€ ์•„๋‹Œ ์š”์ฒญ์ด ๋“ค์–ด์™”์„ ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™์ด 301 redirect ๋˜๋„๋ก ์„ ์–ธํ•ด๋†จ๋Š”๋ฐ 301๋ฒˆ Moved Permanetly๋Š” redirect์‹œํ‚ฌ ๋•Œ method๋ฅผ GET์œผ๋กœ ๋ฐ”๊พธ์–ด์„œ ์ „์†กํ•œ๋‹ค.
  • ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•
    • 308 Permanent Redirect๋Š” ์ „์†ก ๋ฐ›์€ Http Method๋ฅผ ์œ ์ง€ํ•œ๋‹ค.

โ— ๋‚จ์€ ๋ฌธ์ œ

  • EC2 ๋ณด์•ˆ ๊ทธ๋ฃน ์„ค์ • ์—๋Ÿฌ
  • uri: /.env์™€ ๊ฐ™์€ ๋ถˆํŠน์ • URL๋กœ์˜ ์š”์ฒญ(ํ•ดํ‚น ์‹œ๋„)์„ ๋ง‰์„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•

0๊ฐœ์˜ ๋Œ“๊ธ€