🏭 Infra/🥑 AWS

[AWS/Docker/Nginx] 단일 서버에서 도메인별 서비스 제공하기

gengminy 2022. 8. 10. 16:17

처음엔 뭔 괴상한 기둥이 있길래 놀랐었다 AWS는 늘 이런 이미지를 쓴다

 

 

분명 세팅 잘 했는데도 서브도메인이 모두 같은 포트로 넘어가서

하루 종일 끙끙대다가 도움을 받아서 겨우 해결한 문제

사실 설정값 문제는 없었지만

docker-compose 로 이미지 빌드가 제대로 안되어서

이전 설정값으로 계속 사용중이었음 ^^;;;

아무튼 고쳤으니까 블로그 정리하는 김에 적어봅니다

 

 

📌 작업 환경

AWS EC2 + ELB
Docker
Nginx
Spring boot
React

 

📁 프로젝트 구조

 

🔨 도커 컴포즈 세팅

📝 docker-compose.yml

version: "3.7"
services:

# redis 설정
  redis:
    image: "redis:alpine"
    network_mode: "host"

# 서버 설정
  backend:
    image: gengminy/hifi-dev:dev
    container_name: backend
    network_mode: "host"
    env_file:
      - .env

# 리액트 설정
  frontend:
    image: gengminy/hififront:main
    container_name: frontend
    network_mode: "host"

# nginx 설정
  nginx:
    depends_on:
      - backend
      - frontend
      - redis
    network_mode: "host"
    restart: always
    build:
      dockerfile: Dockerfile
      context: ./nginx

EC2 서버에 배포용으로 올라가있는 도커 컴포즈 파일

네트워크 모드를 기본 브릿지가 아닌 호스트 모드로 사용하여

EC2 인스턴스에서 localhost로도 각 컨테이너에 접근할 수 있다

각 컨테이너의 포트는 이미지를 만들었을 때 사용한 포트 설정을 따라간다

 

예를 들어 리액트 이미지를 만들때 포트가 3000번으로 세팅되어 있다면

EC2 인스턴스에서도 localhost:3000 으로 리액트 컨테이너에 접근할 수 있다

 

Nginx는 배포 레포지토리에 default.conf 파일과 도커파일을 내장시켜서

도커 컴포즈가 수행될 때 빌드되도록 했다

 

여담으로 이 Nginx 빌드하는 과정 때문에 장장 한나절을 삽질해버렸다

이런식으로 세팅했을 때, Nginx 설정 파일을 건드렸다면

docker-compose up --build 를 통해 이미지를 다시 생성해주자 ^^

 

 

 

🔨 Nginx 세팅

📝 default.conf

server{
    listen 80;
    server_name hifihifi.site;
    location / {
        proxy_pass http://localhost:3000;
        proxy_redirect     off;
        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 api.hifihifi.site;
    access_log  /var/log/nginx/access.log  backend;

    location / {
        proxy_pass http://localhost:8000;
        proxy_redirect     off;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

server{
    listen 80;
    server_name admin.hifihifi.site;
    location / {
        proxy_pass http://localhost:3100;
        proxy_redirect     off;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

모든 요청은 EC2 인스턴스의 80번 포트로 들어오게 된다

443번 포트를 사용하는 HTTPS 요청도 ELB 앞단에서 80번 포트로 포워딩 해주었다

 

각 요청은 호스트 헤더에 포함된 도메인 이름을 통해

EC2의 각 서비스별 포트로 포워딩 시켜준다

 

이렇게 하면 장점이 인바운드 규칙에

3000, 8000, 3100번 포트와 같은 애들을 노출시키지 않아도 되어서

보안 설정에 유리한 점도 있고 무엇보다도 찝찝하지 않다

(인바운드는 서버에 들어오는 요청, 아웃바운드는 서버에서 나가는 응답)

 

이렇게 설정한 다음에 꼭 도커 빌드를 통해 이미지를 새로 만들어주자

까먹었다가 또 삽질하지 말구,,,

 

 

🔨 Route 53 세팅

이미 Route 53에 도메인 등록을 했다고 가정하고

생성했던 레코드에 들어가서 서브도메인 자리에 서브도메인 입력

 

서브 도메인을 등록해주면 하나의 도메인을 가지고

****.com

api.****.com

admin.****.com

이런 식으로 사용할 수 있다

 

만약 다른 사이트로 단순 라우팅을 해주는거라면

값에다가 해당 서비스의 CNAME 이나 IP 등을 입력

 

필자 같은 경우는 서버 설정에 로드 밸런서가 앞단에 있기 때문에

해당 로드 밸런서로 라우팅 해주면 된다

 

 

별칭 켜주고 로드 밸런서 등록

레코드 생성을 눌러서 등록 완료하고 몇 분 기다리면 라우팅이 된다

 

이렇게 하면 단일 EC2 서버에서 여러 서비스를 제공할 수 있으니

알아두면 많은 도움이 될 거 같다