[AWS/Docker/Nginx] 단일 서버에서 도메인별 서비스 제공하기
분명 세팅 잘 했는데도 서브도메인이 모두 같은 포트로 넘어가서
하루 종일 끙끙대다가 도움을 받아서 겨우 해결한 문제
사실 설정값 문제는 없었지만
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 서버에서 여러 서비스를 제공할 수 있으니
알아두면 많은 도움이 될 거 같다