[CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ฃ NGINX Server Docker Job (โ‘  NGINX ๊ฐ ์ข… ์„ค์ •)

2023. 7. 6. 18:47ใ†System ์ž‘์—…์‹ค/DevOps

728x90
๋ฐ˜์‘ํ˜•

 

 

 

 

 

 

 



๐Ÿ—‚ ๋ชฉ์ฐจ

โš ๏ธ ์•„๋ž˜ ๋ชฉ์ฐจ ์ค‘ ๋ช‡๋ช‡๊ฐœ์˜ ๋งํฌ๊ฐ€ ๊ฑธ๋ฆฌ์ง€ ์•Š๋Š” ๋ฌธ์ œ๋กœ ๊ธ€ ๋งจ ํ•˜๋‹จ์— ๋‹ค์Œ ๊ธ€๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

โœ… [CI/CD] Jenkins์™€ Gitea ์—ฐ๋™
โœ… [CI/CD] Jenkins Trigger ์ •๋ณด Discord๋กœ ๋ณด๋‚ด๊ธฐ
โœ… [CI/CD] ์ •์  ์ฝ”๋“œ ๋ถ„์„ ํˆด SonarQube์™€ Jenkins ์—ฐ๋™
โœ… [CI/CD] SonarQube๋ฅผ ํ†ตํ•ด Code Convention ์ ์šฉ
โœ… [DevOps] JAVA Gradle JaCoCo (Code coverage) ์„ค์ •ํ•˜๊ธฐ 
โœ… [DevOps] JAVA Gradle JaCoCo (Code coverage) ์„ค์ •ํ•˜๊ธฐ (์ถ”๊ฐ€)(https://junyharang.tistory.com/392)

โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘  Application Linuxt(Ubuntu)์— SSH๋ฅผ ์ด์šฉํ•œ ํŒŒ์ผ ์ „์†ก
โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ก Create Docker Image And BackUp
โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ข Application Server Docker Job (โ‘  Application ๋„์ปค ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ)
โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ข Application Server Docker Job (โ‘ก Application Docker Run)(https://junyharang.tistory.com/406)
โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ข Application Server Docker Job (โ‘ข Application Docker Health Check)
โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ฃ NGINX Server Docker Job (โ‘  NGINX ๊ฐ ์ข… ์„ค์ •) 
โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ฃ NGINX Server Docker Job (โ‘ก NGINX Docker ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ) 
โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ฃ NGINX Server Docker Job (โ‘ข NGINX Docker Run & Health Check)
โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ฃ NGINX Server Docker Job (โ‘ข NGINX ์žฌ ์„ค์ •)



๐Ÿค” ๋‚ด๊ฐ€ ๋งŒ๋‚œ ๋ฌธ์ œ

โ›”๏ธ [Jenkins] java.lang.OutOfMemoryError: Java heap space

 




 

 

๋ฐฐํฌ ์ž๋™ํ™”์™€ ์ง€์†์  ์ธ๋„:๋„์ปค์™€ ์  ํ‚จ์Šค ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋กœ ๋งŒ๋“œ๋Š”

COUPANG

www.coupang.com

"์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค."

 

 

 

 

๐Ÿš€ NGINX ๊ฐ ์ข… ์„ค์ •

    ๐Ÿ”ฝ ๊ฐœ์š”

        ๐Ÿ“ฆ ๊ตฌ์„ฑ๋„

CI/CD ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ ๊ตฌ์„ฑ๋„

 

 

deploy Directory Path

 

 

 

 

        ๐Ÿ“ฆ ์†Œ๊ฐœ

์ง€๋‚œ ๊ธ€์—์„œ Application(Spring Boot) Docker Container๋ฅผ ๋‘ ๊ฐœ ์˜ฌ๋ฆฌ๊ณ ,
Health Check๊นŒ์ง€ ํ•˜์—ฌ ์ •์ƒ ๊ตฌ๋™ ์ค‘์ด๋ผ๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜์˜€์–ด์š”.

์ด๋ฒˆ์—๋Š” NGINX Docker Container ๊ธฐ๋™ํ•˜๊ธฐ ์ „ NGINX ์„ค์ • ๊ด€๋ จ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋ ค๊ณ  ํ•ด์š”.

NGINX๊ฐ€ ๋ฌด์—‡์ด๊ณ , ๊ธฐ๋ณธ์ ์ธ ์‚ฌํ•ญ์— ๋Œ€ํ•ด์„œ๋Š” ์ด ๊ณณ์— ์ •์„ฑ์Šค๋Ÿฝ๊ฒŒ ์ •๋ฆฌํ•ด ๋‘์—ˆ์–ด์š”.

 

[DevOps] NGINX๋ž€?

๐Ÿš€ NGINX ๐Ÿ”ฝ NGINX๋ž€? ๐Ÿ“ฆ ๊ฐœ์š” NGINX๋Š” ๋งŽ์€ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” Software๋กœ Revers Proxy, Load balancer, Cache ๋“ฑ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” Software์—์š”. ๋˜ํ•œ NGINX๋Š” ๋ฐ๋ชฌ์œผ๋กœ ๋™์ž‘ํ•˜๋Š”๋ฐ, ๋ฐ๋ชฌ์ด๋ž€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ

junyharang.tistory.com

 

 

 

    ๐Ÿ”ฝ Jenkins

        ๐Ÿ“ฆ Jenkinsfile

       stage('์šด์˜ ํ™˜๊ฒฝ DMZ ์„œ๋ฒ„ NGINX ๊ด€๋ จ File ์ „๋‹ฌ ๋ฐ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ') {
            when {
                expression { env.GIT_BRANCH == 'master' | env.GIT_BRANCH == 'main' }
            }

            steps([$class: 'BapSshPromotionPublisherPlugin']) {
                script {
                    def startTimeMillis = System.currentTimeMillis()

                    sshPublisher(
                            continueOnError: false, failOnError: true,

                            publishers: [
                                    sshPublisherDesc(
                                            configName: "op-total-back-office-nginx",
                                            verbose: true,
                                            transfers: [
                                                    sshTransfer(
                                                            remoteDirectory: "deploy/",
                                                            execCommand: "rm -rf *;"),
                                                    sshTransfer(
                                                            sourceFiles: "deploy/prod/nginx/**",
                                                            execCommand: "chmod +x $DOCKER_SERVER_BASE_DIRECTORY/deploy/prod/nginx/shell-script/nginxContainerExistenceStatusCheck.sh; \
                                                                          chmod +x $DOCKER_SERVER_BASE_DIRECTORY/deploy/prod/nginx/shell-script/nginxDockerContainerRun.sh; \
                                                                          chmod +x $DOCKER_SERVER_BASE_DIRECTORY/deploy/prod/nginx/shell-script/nginxServiceSetting.sh; \
                                                                          chmod +x $DOCKER_SERVER_BASE_DIRECTORY/deploy/prod/nginx/shell-script/nginxHealthCheck.sh"),
                                            ]
                                    )
                            ]
                    )

                    def endTimeMillis = System.currentTimeMillis()
                    def requiredTimeMillis = endTimeMillis - startTimeMillis
                    def requiredTimeSecond = requiredTimeMillis / 1000

                    echo '์šด์˜ ํ™˜๊ฒฝ DMZ ์„œ๋ฒ„ NGINX ๊ด€๋ จ File ์ „๋‹ฌ ๋ฐ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ ์ž‘์—… ์†Œ์š” ์‹œ๊ฐ„ : ' + requiredTimeSecond + ' ์ดˆ'
                }
            }

            post {
                success {
                    script {
                        sendSuccessAlarmToDiscord('์šด์˜ ํ™˜๊ฒฝ DMZ ์„œ๋ฒ„ NGINX ๊ด€๋ จ File ์ „๋‹ฌ ๋ฐ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ')
                    }
                }

                failure {
                    sendFailedAlarmToDiscord('์šด์˜ ํ™˜๊ฒฝ DMZ ์„œ๋ฒ„ NGINX ๊ด€๋ จ File ์ „๋‹ฌ ๋ฐ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ')
                }
            } // Discord Send Post ๋
        } // stage('์šด์˜ ํ™˜๊ฒฝ DMZ ์„œ๋ฒ„ NGINX ๊ด€๋ จ File ์ „๋‹ฌ ๋ฐ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ') ๋

        stage('์šด์˜ ํ™˜๊ฒฝ DMZ ์„œ๋ฒ„ NGINX Docker ๊ด€๋ จ ์ž‘์—…') {
            when {
                expression { env.GIT_BRANCH == 'master' | env.GIT_BRANCH == 'main' }
            }
            steps([$class: 'BapSshPromotionPublisherPlugin']) {
                script {
                    def startTimeMillis = System.currentTimeMillis()

                    sshPublisher(
                            continueOnError: false, failOnError: true,
                            publishers: [
                                    sshPublisherDesc(
                                            configName: "op-total-back-office-nginx",
                                            verbose: true,
                                            transfers: [
                                                    sshTransfer(execCommand: "$DOCKER_SERVER_BASE_DIRECTORY/deploy/prod/nginx/shell-script/nginxContainerExistenceStatusCheck.sh")
                                            ]
                                    )
                            ]
                    )

                    def endTimeMillis = System.currentTimeMillis()
                    def requiredTimeMillis = endTimeMillis - startTimeMillis
                    def requiredTimeSecond = requiredTimeMillis / 1000

                    echo '์šด์˜ ํ™˜๊ฒฝ DMZ ์„œ๋ฒ„ NGINX Docker ๊ด€๋ จ ์ž‘์—… ์†Œ์š” ์‹œ๊ฐ„ : ' + requiredTimeSecond + ' ์ดˆ'
                }
            }

            post {
                success {
                    script {
                        sendSuccessAlarmToDiscord('์šด์˜ ํ™˜๊ฒฝ DMZ ์„œ๋ฒ„ NGINX Docker ๊ด€๋ จ ์ž‘์—…')
                    }
                }

                failure {
                    sendFailedAlarmToDiscord('์šด์˜ ํ™˜๊ฒฝ DMZ ์„œ๋ฒ„ NGINX Docker ๊ด€๋ จ ์ž‘์—…')
                }
            } // Discord Send Post ๋
        } // stage("์šด์˜ ํ™˜๊ฒฝ Docker ๊ด€๋ จ ์ž‘์—…") ๋


NGINX๊ฐ€ ๊ธฐ๋™๋  ํ™˜๊ฒฝ์€ ์œ„์˜ CI/CD ๊ตฌ์„ฑ๋„์™€ ๊ฐ™์ด WAS๊ฐ€ ๊ตฌ๋™๋  ์„œ๋ฒ„์™€ ๋‹ค๋ฅธ ์œ„์น˜์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์—
configName์ด ๋‹ฌ๋ผ์š”.


๊ทธ๋ฆฌ๊ณ , ์ด ์ „ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ž‘์—…๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ SSH๋ฅผ ํ†ตํ•ด ํ•„์š”ํ•œ ํŒŒ์ผ์„ ์˜ฎ๊ธฐ๊ณ ,
Shell Script๊ฐ€ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.

 

 

 

 

 

 

    ๐Ÿ”ฝ ์„ค์ •

        ๐Ÿ“ฆ default.conf

NGINX Docker Container ์•ˆ์— /etc/nginx/conf.d ์—๋Š” default.conf๊ฐ€ ์œ„์น˜ํ•˜๊ณ  ์žˆ์–ด์š”.

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
#         root   /usr/share/nginx/html;
        root /usr/local/www/html;
        index  index.html index.htm;

        # ๋””๋ ‰ํ„ฐ๋ฆฌ ๋ฆฌ์ŠคํŒ… ์ทจ์•ฝ์  ์ œ๊ฑฐ
        autoindex off;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page 400 401 403 404 500 /error.html;
    location = /error.html {
#         root   /usr/share/nginx/html;
        root /usr/local/www/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}


์—ฌ๊ธฐ์„œ ๋ช‡๊ฐ€์ง€ ๋ณด์•ˆ ์‚ฌํ•ญ์— ์œ„๋ฐฐ๋  ๋ถ€๋ถ„์„ ์ˆ˜์ •ํ•ด ์ฃผ์—ˆ๋Š”๋ฐ,
๋จผ์ € ๋””๋ ‰ํ„ฐ๋ฆฌ ๋ฆฌ์ŠคํŒ… ์ทจ์•ฝ์  ์ œ๊ฑฐ๋ฅผ ์œ„ํ•ด autoindex off;๋ฅผ ์„ค์ •ํ•ด ์ฃผ์—ˆ์–ด์š”.



๐Ÿ’ก ์ฐธ๊ณ  ์‚ฌํ•ญ
๋””๋ ‰ํ† ๋ฆฌ ๋ฆฌ์ŠคํŒ… ์ทจ์•ฝ์ 

  → WAS์˜ ํ™˜๊ฒฝ ์„ค์ • ๋ฏธํก์œผ๋กœ ์›น ๋””๋ ‰ํ† ๋ฆฌ ํ˜ธ์ถœ ์‹œ ํ•ด๋‹น WAS์˜ ๋””๋ ‰ํ† ๋ฆฌ ๋ชฉ๋ก์ด ์™ธ๋ถ€์— ๋…ธ์ถœ๋˜๋Š” ์ทจ์•ฝ์ 

๊ณต๊ฒฉ ๋‹นํ–ˆ์„ ์‹œ

  → ๋ธŒ๋ผ์šฐ์ง•ํ•˜๋Š” ๋ชจ๋“  ํŒŒ์ผ์„ ๋ณด์—ฌ์คŒ

  → ๋ฐฑ์—…ํŒŒ์ผ ๋ฐ ์†Œ์Šค์ฝ”๋“œ, ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์˜ ์œ ์ถœ๋กœ ์ธํ•ด ๊ณ„์ • ์ •๋ณด๊ฐ€ ์œ ์ถœ ๊ฐ€๋Šฅ

โ€ป ์ตœ๊ทผ์—๋Š” ์›น ์„œ๋ฒ„ ๊ณต๊ฒฉ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋Œ€๋ถ€๋ถ„ ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ โ€ป

๊ณต๊ฒฉ ๋ฐฉ๋ฒ•?

   → ์ด๋ฏธ์ง€ ํŒŒ์ผ ๋“ฑ ๊ฒฝ๋กœ๋ฅผ ์•Œ ์ˆ˜ ์žˆ์„ ๋•Œ, URL ๋ถ€๋ถ„์— ํŒŒ์ผ๋ช…์„ ์ง€์šฐ๊ณ  ์ž…๋ ฅํ•˜๋ฉด ํŒŒ์ผ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Œ

   → ๋ฌด์ž‘์œ„๋กœ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ๋””๋ ‰ํ† ๋ฆฌ๋ช… ๋Œ€์ž…

         ex) http://nxxxxxx.com/admin ๋“ฑ

 

๋Œ€์‘ ๋ฐฉ๋ฒ•?

  → ์„œ๋ฒ„์˜ ์„ค์ •์„ ๋ณ€๊ฒฝํ•ด์„œ ๊ธฐ๋ณธ ํŽ˜์ด์ง€๊ฐ€ ์—†์„ ๊ฒฝ์šฐ ๋””๋ ‰ํ† ๋ฆฌ ๋ชฉ๋ก์ด ๋…ธ์ถœ๋˜์ง€ ์•Š๋„๋ก ํ•จ

 

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ๋‹ˆ์˜ ์›น ์„œ๋น„์Šค์—์„œ ์œ„์™€ ๊ฐ™์ด ๊ณต๊ฒฉ ์‹œ๋„๋ฅผ ํ•ด๋ณด๋ฉด


์œ„์™€ ๊ฐ™์ด Error Page๋กœ ๋„˜์–ด๊ฐ€๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.







        ๐Ÿ“ฆ nginx.conf

# ์›น ํ”„๋กœ์Šค์„ธ ๊ถŒํ•œ ์ œํ•œ์„ ์œ„ํ•œ Nginx Deamon ์†Œ์œ ์ž nginx๋กœ ์„ค์ •
user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

# ๋กœ๊ทธ ํฌ๋งท ์„ค์ • (์›น ์„œ๋ฒ„์˜ ๋กœ๊ทธ ํฌ๋งท์„ Combined๋กœ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด, ๊ณต๊ฒฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํŒŒ์•…, ๊ณต๊ฒฉ ๋Œ€์ƒ ์‚ฌ์šฉ ํˆด ํŒŒ์•…, ๊ณต๊ฒฉ ๋Œ€์ƒ ์œ„์น˜ ํŒŒ์•…์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ๋ฐ˜๋“œ์‹œ Combined ํฌ๋งท ๋˜๋Š” ๊ทธ์— ์ค€ํ•˜๋Š” ํฌ๋งท ์ŠคํŠธ๋ง์œผ๋กœ ์„ค์ •)
    access_log  /var/log/nginx/access.log  combined;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    # hide nginx version
    server_tokens off;

    #์‹ฌ๋ณผ๋ฆญ ๋งํฌ ์ œํ•œ
    disable_symlinks on;

    # File Upload & Download ์ œํ•œ
    client_max_body_size 20M;

    include /etc/nginx/conf.d/*.conf;

    # ์šด์˜ ํ™˜๊ฒฝ
    upstream prod-backend {
        #prod blue
        server 192.168.20.12:1001;
        #prod green
        server 192.168.20.12:1011;
    } # upstream prod-backend ๋

    server {
        listen 80;
        server_name 192.168.30.3 211.109.XXX.XXX;

        # ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๊ฐ€ ๋ณด๋‚ด์˜ค๋Š” ๋ชจ๋“  ์—๋Ÿฌ ํŽ˜์ด์ง€๋ฅผ ์—”์ง„์—‘์Šค๊ฐ€ ์ง์ ‘ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ํšŒ์‹ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ง€์‹œ์–ด ๊ฐ’์„ on์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ์—๋Ÿฌ ์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•ด error_page ์ง€์‹œ์–ด์—์„œ ์ง€์ •ํ•œ ๊ฐ’๊ณผ ๋น„๊ต ํ•ฉ๋‹ˆ๋‹ค. (https://12bme.tistory.com/367)
        proxy_intercept_errors on;

        error_page 400 401 403 404 500 502 503 504 /error.html;
        location = /error.html {
                root /var/www/html;
                internal;
        }

        location / {
            proxy_http_version 1.1;
            proxy_pass http://prod-backend;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            # X-Frame-Options: ์•…์˜ ์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ๋ณธ์ธ์˜ ์‚ฌ์ดํŠธ์— nginx server์˜ embedding ํ•˜๋Š” ๊ฒƒ์„ ์ œํ•œํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. - ํด๋ฆญ์žฌํ‚น ๊ณต๊ฒฉ ๊ธฐ๋ฒ• ๋ฐฉ์–ด
            add_header X-Frame-Options "SAMEORIGIN";

            # X-XSS-Protection: ์•…์˜ ์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ๋ณธ์ธ์˜ ์‚ฌ์ดํŠธ๋กœ XSS ๊ณต๊ฒฉ์„ ํ•˜๋Š” ๊ฒƒ์„ ์ œํ•œํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.
            add_header X-XSS-Protection "1; mode=block";

            proxy_connect_timeout 600;
            proxy_send_timeout 600;
            proxy_read_timeout 600;
            send_timeout 600;

            # ๋””๋ ‰ํ„ฐ๋ฆฌ ๋ฆฌ์ŠคํŒ… ์ทจ์•ฝ์  ์ œ๊ฑฐ
            autoindex off;
        }
    } # sever ๋
} #http ๋


nginx.conf์˜ ๊ฒฝ์šฐ NGINX ๋„์ปค ์ปจํ…Œ์ด๋„ˆ /etc/nginx์— ์œ„์น˜ํ•˜๊ณ  ์žˆ์–ด์š”.

๊ธฐ๋ณธ์ ์œผ๋กœ ๋งŒ๋“ค์–ด์ ธ ์žˆ๋Š” nginx.conf ํŒŒ์ผ์„ ์ง€์šฐ๊ณ , ์œ„ ๋‚ด์šฉ์ด ์ฒจ๊ฐ€ ๋˜๋„๋ก ์‰˜ ์Šคํฌ๋ฆฝํŠธ ์ž‘์—…์„ ํ•ด ์ฃผ์—ˆ์–ด์š”.

์—ฌ๊ธฐ์„œ ์ฃผ์š”ํ•œ ๋ถ€๋ถ„์„ ๋ถ„์„ํ•ด ๋ณด๋ฉด ์ตœ์ดˆ 2๋ฒˆ์งธ ์ค„์— user ๋ถ€๋ถ„์€ ์›น ํ”„๋กœ์„ธ์Šค ๊ถŒํ•œ ์ œํ•œ์„ ์œ„ํ•ด
NGINX Deamon ์†Œ์œ ์ž๋ฅผ nginx๋กœ ์„ค์ •ํ•ด ์ค€ ๊ฒƒ์ด์—์š”.


nginx ๊ณ„์ •์€ ๋กœ๊ทธ์ธ์ด ๋˜์ง€ ์•Š๋„๋ก ์„ค์ • ๋˜์–ด ์žˆ๋Š”๋ฐ, 


์ด๋ ‡๊ฒŒ NGINX ์ปจํ…Œ์ด๋„ˆ์—์„œ ํ•ด๋‹น ๊ณ„์ • ์ •๋ณด๋ฅผ ํ™•์ธํ•ด ๋ณด๋ฉด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์‰˜ ์Šคํฌ๋ฆฝํŠธ ๋ถ€๋ถ„์ด /bin/false๋กœ ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ณ , ์ด๋Š” ๊ณ„์ • ๋กœ๊ทธ์ธ์ด ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์˜๋ฏธ์—์š”.

์ด ์™ธ์—๋„ /sbin/nologin์œผ๋กœ ๋˜์–ด ์žˆ์–ด๋„ ๋กœ๊ทธ์ธ์ด ๋˜์ง€ ์•Š์•„์š”.


nginx.conf


๊ทธ๋ฆฌ๊ณ  21๋ฒˆ์งธ ์ค„์— ์ ‘์† ๋กœ๊ทธ ํฌ๋งท ์„ค์ • ๋ถ€๋ถ„์„ combined๋กœ ํ•ด ์ฃผ์—ˆ๋Š”๋ฐ, ์ด๋Š” ์›น ์„œ๋ฒ„์˜ ๋กœ๊ทธ ํฌ๋งท์„ combined๋กœ ์„ค์ •ํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ๊ณต๊ฒฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€, ๊ณต๊ฒฉ ๋Œ€์ƒ ์‚ฌ์šฉ ํˆด, ๊ณต๊ฒฉ ๋Œ€์ƒ ์œ„์น˜ ํŒŒ์•…์ด ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— Combined Format ๋˜๋Š” ๊ทธ์— ์ค€ํ•˜๋Š” Format String์„ ์„ค์ •ํ•ด ์ฃผ๋Š” ๊ฒƒ์ด ์ข‹๊ธฐ ๋•Œ๋ฌธ์— ํ•ด ์ฃผ์—ˆ์–ด์š”.

๋˜ํ•œ Combined๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๋กœ๊ทธ ํฌ๋งท ์ค‘ ํ•˜๋‚˜๋กœ, IP ์ฃผ์†Œ, ์ ‘๊ทผ ์‹œ๊ฐ„, ์š”์ฒญ ์ •๋ณด, ์‘๋‹ต ์ƒํƒœ ์ฝ”๋“œ, ์ „์†ก๋œ ๋ฐ”์ดํŠธ ์ˆ˜ ๋“ฑ์„ ํฌํ•จํ•˜์—ฌ ์ ‘๊ทผ ๋กœ๊ทธ์— ๋‚จ๊ธธ ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ค€ ๋ถ€๋ถ„์ด์—์š”.


31๋ฒˆ์งธ ์ค„์—๋Š” Error๊ฐ€ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜, ๊ธฐํƒ€ ๋ฌธ์ œ ๋ฐœ์ƒ ์‹œ ํ•ด๋‹น Page์— NGINX Version์ด
๋…ธ์ถœ๋˜์ง€ ์•Š๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์ ์–ด์ฃผ์—ˆ์–ด์š”.

๊ทธ๋ฆฌ๊ณ , 34๋ฒˆ์งธ ์ค„์—๋Š” ์‹ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ์ œํ•œํ•ด ์ค€ ๊ฒƒ์ด๊ณ , 37๋ฒˆ์งธ ์ค„์—๋Š” ํŒŒ์ผ ์—…/๋‹ค์šด๋กœ๋“œ์˜ ํฌ๊ธฐ๋ฅผ 20M๋กœ ์ œํ•œํ•˜์—ฌ
Web Shell ๋“ฑ๋“ฑ์˜ ํŒŒ์ผ ๊ด€๋ จ ๊ณต๊ฒฉ์„ ๋ง‰๊ธฐ ์œ„ํ•ด ์„ค์ •ํ•ด ์ฃผ์—ˆ์–ด์š”.



nginx.conf

728x90


Server Block์—์„œ ์ตœ์ดˆ 50๋ฒˆ์งธ ์ค„์„ ํ†ตํ•ด NGINX ๋„์ปค ์ปจํ…Œ์ด๋„ˆ์˜ NGINX ์„œ๋น„์Šค Port ๋ฒˆํ˜ธ๋ฅผ 80์œผ๋กœ ์„ค์ •ํ•ด ์ฃผ์—ˆ์–ด์š”.
์ด๋Š” ๋„์ปค ์ปจํ…Œ์ด๋„ˆ ์™ธ๋ถ€ ํ˜ธ์ŠคํŠธ ์„œ๋ฒ„์™€ port mapping์„ ํ†ตํ•ด ๋‹ค๋ฅธ port๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.

server_name์—๋Š” NGINX์—๊ฒŒ ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ IP ์ฃผ์†Œ ํ˜น์€ ๋„๋ฉ”์ธ ์ฃผ์†Œ๋ฅผ ๋„ฃ์–ด์ฃผ๋ฉด ๋˜๋Š”๋ฐ,
์ฃผ๋‹ˆ๋Š” ๋‚ด๋ถ€๋ง๊ณผ ์™ธ๋ถ€๋ง์„ NAT๋กœ ์—ฐ๊ฒฐํ•˜์—ฌ ํ•ด๋‹น ์„œ๋น„์Šค๊ฐ€ ์™ธ๋ถ€์—์„œ๋„ ํ†ต์‹ ๋  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•ด ์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ณต๋ฐฑ์„
๊ธฐ์ค€์œผ๋กœ ๋‘ ๊ฐœ์˜ ๋‚ด๋ถ€๋ง๊ณผ ์™ธ๋ถ€๋ง IP๋ฅผ ๋„ฃ์–ด์ฃผ์—ˆ์–ด์š”.

์Šคํ”„๋ง ๋ถ€ํŠธ ์ฆ‰, Back End๋ผ๋ฉด ๋‚ด๋ถ€๋ง์œผ๋กœ ์ˆจ๊ฒจ๋„ ๋˜์ง€๋งŒ
ํ•ด๋‹น ์„œ๋น„์Šค๋Š” ์™ธ๋ถ€์—์„œ ์ง์ ‘ ํ†ต์‹ ํ•ด์•ผ ํ•˜๋Š” ์„œ๋น„์Šค๋ฅผ ๋‹ด๊ณ  ์žˆ์–ด์„œ
์™ธ๋ถ€๋ง์œผ๋กœ ํ†ต์‹  ๋˜๋„๋ก ์„ค์ •ํ•ด ์ค€ ๋ถ€๋ถ„์ด์—์š”.

56๋ฒˆ์งธ ๋ถ€ํ„ฐ 60๋ฒˆ์งธ ์ค„๊นŒ์ง€๋Š” ๋ฌธ์ œ ๋ฐœ์ƒ ์‹œ ํ‘œ์‹œํ•  Error Page ์„ค์ •์„ ํ•ด ์ค€ ๋ถ€๋ถ„์ด์—์š”.

์œ„์™€ ๊ฐ™์ด 400 ~ 504 ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด error.html์„ ๋ณด์—ฌ์ค˜๋ผํ•˜๋Š” ๊ฑฐ๊ณ ,

57๋ฒˆ์งธ ์ค„ Location Block์„ ํ†ตํ•ด error.html์€ /var/www/html์— ์žˆ๋‹ค๊ณ  ์•Œ๋ ค์ฃผ์—ˆ์–ด์š”.



62๋ฒˆ์งธ Location Block์— / ๋Š” server_name ๋’ค์— URL์ด /๋ผ๋ฉด proxy_pass์— ์„ค์ •๋œ ๊ณณ
์ฆ‰, 42๋ฒˆ์งธ ์ค„์— upstream์— ์ž‘์„ฑ๋œ server๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ค€ ๋ถ€๋ถ„์ด์—์š”.



๐Ÿ’ก ์ฐธ๊ณ  ์‚ฌํ•ญ
NGINX Location ์„ค์ •

- proxy_http_verion 1.1 : Proxy Request์— ๋Œ€ํ•ด ์‚ฌ์šฉํ•  HTTP Version ๋ช…์‹œ.

- proxy_pass : Request๋ฅผ ์ „๋‹ฌํ•œ Upstream Server ์ฃผ์†Œ ์„ค์ •.
   ์œ„ ๋‚ด์šฉ์—์„œ๋Š” http:prod-backend๋กœ ์„ค์ •๋˜์–ด ์žˆ๊ณ , ์‹ค์ œ๋กœ๋Š” prod-backend๋ผ๋Š” ์ด๋ฆ„์˜ upstream Block์— ์ •์˜๋œ
   Sever Group ์ฐธ์กฐ.

- proxy_set_header X-Real-IP : Request Header์— X-Real-IP Filed๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ ,
   ๊ทธ ๊ฐ’์„ Client์˜ ์‹ค์ œ IP ์ฃผ์†Œ๋กœ ์„ค์ •.

- proxy_set_header X-Forwarded-For : Request Header์— X-Forwarded-For Filed๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , ๊ทธ ๊ฐ’์„ ์ด ์ „์—
   ์ถ”๊ฐ€๋œ Proxy Server IP ์ฃผ์†Œ์™€ Client IP ์ฃผ์†Œ๋ฅผ ํฌํ•จํ•œ ํ˜•ํƒœ๋กœ ์„ค์ •. ์ด๋Š” ์›๊ฒฉ Client IP๋ฅผ Upstream
   Server(Application Server)์— ์ „๋‹ฌํ•˜๋Š”๋ฐ ์‚ฌ์šฉ.

- proxy_set_header Host : Reqeust Header์— Host Filed๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , ๊ทธ ๊ฐ’์„ ์›๋ณธ ์š”์ฒญ์—์„œ ๋ฐ›์€ Host Header
   ๊ฐ’์œผ๋กœ ์„ค์ •.

- add_header X-frame-Options "SAMORIGINS"; : Response Header์— X-Frame-Options Filed๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ ,
   ๊ทธ ๊ฐ’์„ SAMEORIGIN์œผ๋กœ ์„ค์ •. ์ด๋Š” ํด๋ฆญ์žฌํ‚น ๊ณต๊ฒฉ ๋ฐฉ์–ด๋ฅผ ์œ„ํ•œ ์„ค์ •์œผ๋กœ ์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์ดํŠธ๋ฅผ Iframe์œผ๋กœ ํฌํ•จํ•˜๋Š”
   ๊ฒƒ์„ ๋ง‰๊ธฐ ์œ„ํ•œ ๋ฐฉ์–ด ์„ค์ •.

- add_header X-Xss-Protection "1; mode=block"; : Response Header์— X-XSS-Protection Filed๋ฅผ
   ์ถ”๊ฐ€ํ•˜๊ณ , ๊ทธ ๊ฐ’์„ "1; mode=block"์œผ๋กœ ์„ค์ •ํ•˜์—ฌ ์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์ดํŠธ๋กœ์˜ XSS(Cross-Site Scripting) ๊ณต๊ฒฉ
    ์ œํ•œ ์„ค์ •.

- proxy_connect_timeout 600; proxy_send_timeout 600; proxy_read_timeout 600; send_time out 600; :
   Proxy ์—ฐ๊ฒฐ, ์†ก์‹  ๋ฐ ์ˆ˜์‹  ์‹œ๊ฐ„ ์ดˆ๊ณผ๋ฅผ 600์ดˆ๋กœ ์„ค์ •. ์ด ์„ค์ •์„ ํ†ตํ•ด Proxy Server์™€์˜ ์—ฐ๊ฒฐ์ด๋‚˜, Data ์ „์†ก์— ๋Œ€ํ•œ
   Timeout ์‹œ๊ฐ„ ์ง€์ •.

- autoindex off; : ๋””๋ ‰ํ„ฐ๋ง ๋ฆฌ์ŠคํŒ… ๋น„ํ™œ์„ฑํ™” ์„ค์ •. ์ฆ‰, Web Server๊ฐ€ Directory ๋‚ด์˜ File List๋ฅผ ์ž๋™์œผ๋กœ ํ‘œ์‹œํ•˜์ง€ ์•Š๋„๋ก
   ํ•˜๊ธฐ ์œ„ํ•œ ์„ค์ •์œผ๋กœ Directory ๋‚ด File์— ์ง์ ‘ ์ ‘๊ทผํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•˜์—ฌ ๋””๋ ‰ํ„ฐ๋ง ๋ฆฌ์ŠคํŒ… ์ทจ์•ฝ์  ๋ฐฉ์–ด.
   

 






        ๐Ÿ“ฆ errror.html


Error Page๋Š” ์œ„์™€ ๊ฐ™์ด ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•ด ์ฃผ์—ˆ์–ด์š”.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style type=text/css>

        * {
            -webkit-box-sizing: border-box;
            box-sizing: border-box;
        }

        body {
            padding: 0;
            margin: 0;
        }

        #notfound {
            position: relative;
            height: 100vh;
        }

        #notfound .notfound {
            position: absolute;
            left: 50%;
            top: 50%;
            -webkit-transform: translate(-50%, -50%);
            -ms-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);
        }

        .notfound {
            max-width: 520px;
            width: 100%;
            line-height: 1.4;
            text-align: center;
        }

        .notfound .notfound-error {
            position: relative;
            height: 200px;
            margin: 0px auto 20px;
            z-index: -1;
        }

        .notfound .notfound-error h1 {
            font-family: 'Montserrat', sans-serif;
            font-size: 200px;
            font-weight: 300;
            margin: 0px;
            color: #211b19;
            position: absolute;
            left: 50%;
            top: 50%;
            -webkit-transform: translate(-50%, -50%);
            -ms-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);
        }

        @media only screen and (max-width: 767px) {
            .notfound .notfound-error h1 {
                font-size: 148px;
            }
        }

        @media only screen and (max-width: 480px) {
            .notfound .notfound-error {
                height: 148px;
                margin: 0px auto 10px;
            }

            .notfound .notfound-error h1 {
                font-size: 120px;
                font-weight: 200px;
            }

            .notfound .notfound-error h2 {
                font-size: 30px;
            }

            .notfound a {
                padding: 7px 15px;
                font-size: 24px;
            }

            .h2 {
                font-size: 148px;
            }
        }
    </style>
</head>
<body>
<div id="notfound">
    <div class="notfound">
        <h1>โ›”๏ธ ๊ธฐ๊น”๋‚˜๋Š” ์‚ฌ๋žŒ๋“ค ํ†ตํ•ฉ ๊ด€๋ฆฌ ์„œ๋น„์Šค โ›”๏ธ</a></h1>
        <div class="notfound-error">
            <p>๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์–ด์š” ๐Ÿ˜ข</p>
        </div>
    </div>
</div>
</body>
</html>
๋ฐ˜์‘ํ˜•






์ด๋ฒˆ ๊ธ€์—๋Š” ์—ฌ๊ธฐ๊นŒ์ง€ ์ •๋ฆฌํ•˜๊ณ , ๋‹ค์Œ ๊ธ€์—์„œ๋Š” NGINX ๋„์ปค ๊ด€๋ จ ์ž‘์—… ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด ๋ณผ๊ฒŒ์š”.



 

NGINX ์ฟก๋ถ : 115๊ฐ€์ง€ ๋ ˆ์‹œํ”ผ๋กœ ๋ฐฐ์šฐ๋Š” ๊ณ ์„ฑ๋Šฅ ๋ถ€ํ•˜๋ถ„์‚ฐ ๋ณด์•ˆ ์„œ๋ฒ„ ๋ฐฐํฌ์™€ ๊ด€๋ฆฌ 2ํŒ

COUPANG

www.coupang.com

"์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค."

 

 

์ด์ „ ๊ธ€: [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ข Application Server Docker Job (โ‘ข Application Docker Health Check)

๋‹ค์Œ ๊ธ€: [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ฃ NGINX Server Docker Job (โ‘ก NGINX Docker ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ)

 

 

 

 

 

728x90
๋ฐ˜์‘ํ˜•