LikeLion🦁

뛰슈 NGINX+Docker+Spring boot 설정

potatoo 2023. 11. 5. 18:52
728x90

2주간의 시도 끝에 드디어 프런트 서버와 연결을 하여 통신이 가능하게 되었다!

우리가 가지고 있는 서버는 1대이기 때문에 3-tier를 구성하기는 힘들었다. 그래서 docker에 올려서 조금 부담을 줄여보고자 하였고, nginx 또한 올리려고 했으나 하는 과정에서 어려움이 있어서 기존에 통신이 가능했던 서버 로컬에서 spring과 NGINX를 구동하기로 했다.

NGINX 설정

먼저 NGINX는 이전에 SSL을 인증할 때는 아는 것이 거의 1도 없었지만 이번 과정을 통해서 어느 정도 감각은 익힐 수 있었다.

그래서 먼저 서버 블록 설정을 보자.

nginx/nginx.conf

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"';

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

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;
    include /etc/nginx/conf.d/*.conf;
}

위의 서버 설정 블록을 보면. default.conf를 include한다는 것을 알 수 있다. 그래서 default.conf에 설정한 서버 블록들이 작동한다.

nginx/conf.d/default.conf

server {
    # https(ssl) 접속에 대한 설정.
    listen       443 ssl http2;
    server_name  likelion-running.store www.likelion-running.store;

    # 기본 웹 콘텐츠 디렉토리 설정
    root /var/www/html;

    # 발급 받은 인증서 파일에 대한 경로 설정.
    ssl_certificate /etc/letsencrypt/live/likelion-running.store/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/likelion-running.store/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-RSA-AES128-GCM-SHA256';

    # SSL 세션 캐시 설정
    ssl_session_cache shared:SSL:10m;

    # SSL 세션 타임아웃 설정
    ssl_session_timeout 1d;


    charset utf-8;
    access_log  /var/log/nginx/access.log  main;
    error_log   /var/log/nginx/error.log   warn;

    add_header X-Content-Type-Options "nosniff";
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    location / {
         proxy_http_version 1.1;
         proxy_set_header Upgrade $http_upgrade;
         proxy_set_header Connection 'upgrade';
         proxy_set_header Host $host;
         proxy_cache_bypass $http_upgrade;
         proxy_pass http://localhost:8080;
    }

    # redirect server error pages to the static page /50x.html
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
# http로 접속 시에 (일반적으로 80포트) https로 리다이렉트 되도록 설정.
server {
    listen        80;
    server_name   likelion-running.store www.likelion-running.store;

    location / {
        include /etc/nginx/proxy_params;
        proxy_pass http://127.0.0.1:8080;

    if ($http_x_forwarded_proto = 'http') {
         return 301 https://$host$request_uri;
    }
    }
}

이 default.conf파일은 HTTP로 들어오는 요청을 HTTPS로 리다이렉트 시켜주는 설정이다. 본인은 이 부분에서 만은 삽질을 했는데 그 이유는 proxy_pass과정에서 localhost가 아닌 서버의 공인 IP로 잘못 proxy_pass를 하여서 nginx가 인식하지 못하여 아래와 같은 에러가 발생했었다.

[error] 23836#23836: *5 connect() failed (111: Connection refused) while connecting to upstream

 

추가적으로 세부적인 설정들을 추가했는데, 아직 정확한 기능을 몰라서 학습이 필요하다.

/nginx/proxy_params

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;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;

client_max_body_size 256M;
client_body_buffer_size 1m;

proxy_buffering on;
proxy_buffers 4 256k;
proxy_buffer_size 128k;
proxy_busy_buffers_size 256k;

proxy_temp_file_write_size 256k;
proxy_max_temp_file_size 1024m;

proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_intercept_errors on;

 

그 다음으로는 docker에 mysqlDB를 올리는 작업을 했다.

도커 컨테이너 생성

docker run -d --name lion-container -e MYSQL_ROOT_PASSWORD=my-secret-pw -p 3306:3306 mysql:5.7

도커 내부 mysql 접근

docker exec -it lion-container mysql -uroot -p

도커 내부 mysql에서 Database 생성

CREATE DATABASE your_database_name CHARACTER SET utf8 COLLATE utf8_general_ci;

처음에는 추가 조건없이 데이터 베이스를 만들었다가, 아래와 같은 문자집합 오류를 만나서 수정하였다.

java.sql.SQLException: Incorrect string value: '\xEA\xB0\x95\xEB\xB3\x91...' for column 'name' at row 1 at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) ~[mysql-connector-j-

 

이렇게 NGINX와 Docker 설정을 마치고 다시 spring의 application.yml파일을 보았다.

 

Spring boot application.yml설정

아래와 같이 jpa와 datasource를 설정하고 server의 주소와 포트를 설정했다. 처음에는 주소와 포트를 지정해두지 않았었다.

그런데 계속 nginx에서 인식을 못했고 proxy_pass와 포트가 일치해야한다는 것도 알았다. 그래서 설정을 추가하였다.

spring:
  jpa:
    show_sql: true
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        format_sql: true
    open-in-view: true

  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/lion?useUnicode=yes&characterEncoding=UTF-8
    username: root
    password: ?????
(생략)
server:
  address: 127.0.0.1
  port: 8080
(생략)

이런 과정을 통해서 nginx는 설정을 한 후 재시작하였고, 도커의 DB도 켜놓은 상태에서 Spring build파일을 서버에 올려서 구동시켰더니 이제는 DB link 실패나 nginx에서의 502 Bad Gateway없이 정상적으로 서버가 작동하기 시작했다.

 

 

728x90