AWS ec2 에 djangon app을 공개 하기 위해 공부하다 알게된 내용을 정리한다. 

 

처음 app 운영을 위해 nginx를 설정 할때 80번 포트로 들어오는 요청을 8000번 포트로 redirect 하도록 설정했다. 

즉 아래와 같이 nginx 와 docker-compose.yml 을 설정했다. 

nginx configuration

upstream myapp{
        server myapp.com:8000;
}
server {
        listen 80;
        server_name myapp.com; ##client 가 접속하는 도메인네임, 장고 app 의 서버 주소
        # redirect https setting
  
        location = /favicon.ico { access_log off; log_not_found off; }

        location /static {
                alias /home/nginx/www/static;
        }

        location / {
                include proxy_params;
                proxy_pass http://myapp;
        }
}

docker compose

version: "3.7"
services:
  nginx:                 
    container_name: nginx
    restart: on-failure
    image: nginx:stable
    volumes:
      - ${PWD}/etc/jnbdrive_nginx:/etc/nginx/sites-enabled/default
      - ${PWD}/etc/nginx.conf:/etc/nginx/nginx.conf:ro
      - ${PWD}/etc/proxy_params:/etc/nginx/proxy_params
      - ${PWD}/staticfiles:/home/nginx/www/static
       
    ports:
      - 80:80

  app_server:
    container_name: app_server
    build: .
    image: app_image:latest
    ports:
      - 8000:8000
    restart: always
    environment:
      DB_PORT: 3306
      DB_HOST_ADDRESS: cie6nasdfnblb.ap-northeast-2.rds.amazonaws.com
    volumes: 
      - ${PWD}:/home/docker/workspace/app
    networks:
      - backend

    command: gunicorn --workers 1 --bind 0.0.0.0:8000 config.wsgi:application

이렇게 설정하면 80번 포트로 들어오는 요청이 8000 번으로 redirect되기는 하지만  AWS ec2 인스턴스의 보안 정책에서 8000 번포트를 오픈해야만 app_server 가 요청을 정상적으로 받을 수 있었다. 

즉 아래 Fig 1의 붉은 선 처럼 nginx 가 요청을 외부에서 들어오는 8000번으로의 요청 처럼 리다이렉트 하는 것으로 보인다. 

Fig 1. nginx 동작

이렇게 하면 ec2 인스턴스의 8000번 포트를 오픈해야 해서 불필요하게 보안 위험이 증가하고 nginx 가 app server 로 들어가는 모든 요청을 관리하게 하는 계획과는 많이 달라진다. 

 

 

 목표 아키텍쳐

원래의 내 계획은 app server 로의 요청은 반드시 80 번 포트로 들어와 nginx를 거쳐 app server 로 가게 하는 것이었다.  이를 위해 docker network를 이용해 nginx continer 와 app container 사이의 일종의 private network 를 구성했다. 전체 아키텍쳐는 아래 Fig 2 와 같다. Fig 1과 비교해 보면 redirect to port 8000 을 의미 하는 붉은 색 선이 ec2 인스턴스 밖으로 나가지 않고 nginx container 와 app container 사이에 존재 한다. 이렇게 하면 ec2 인스턴스의 보안 그룹에서는 8000port 를 오픈할 필요가 없어 보안 위험을 줄일 수도 있고 계획 대로 80번 포트로 들어오는 요청만 nginx를 거쳐 app server 에 전달하는 것이 가능해 진다. 

Fig 2. 목표 요청 처리 아키텍쳐

이를 위한 nginx 및 docker compose.yml 예시를 아래 추가 했다. 주석과 함께 보면 이해하기 쉽다. 간단히 말하면 docker-compose.yml 에서는 nginx container 와 app server conatiner 간의 private network 구성을 위해 networks 예약어를 이용해 backend 라는 네트워크를 추가했다. 이렇게 하면 docker의 네트워크 기능을 이용해 두 컨테이너 간 통신이 가능해 진다. 그리고 nginx 에서는 myapp.com의 80 번 포트로 오는 요청 만 app 이 동작하는  app server 서비스의 8000 번 포트로 redirect 하도록 설정 했다. 이때 nginx 의 upstream 의 server 에는 app이 동작하는 서비스의 이름 (docker-compose.yml 에서 app을 실핸 하기 위해 설정 한 service 이름)을 입력해야 한다. 

 

new nginx 설정 

upstream jnbdrive_app{
        server app_server:8000; ## docker-compose.yml의 app_server 서비스 네임
}
server {
        listen 80;
        server_name myapp.com; ##client 가 접속하는 도메인네임, 장고 app 의 서버 주소
        # redirect https setting
  
        location = /favicon.ico { access_log off; log_not_found off; }

        location /static {
                alias /home/nginx/www/static;
        }

        location / {
                include proxy_params;
                proxy_pass http://myapp.com;
        }
}

new docker compose 파일 설정

version: "3.7"
services:
  nginx:                 
    container_name: nginx
    restart: on-failure
    image: nginx:stable
    volumes:
      - ${PWD}/etc/jnbdrive_nginx:/etc/nginx/sites-enabled/default
      - ${PWD}/etc/nginx.conf:/etc/nginx/nginx.conf:ro
      - ${PWD}/etc/proxy_params:/etc/nginx/proxy_params
      - ${PWD}/staticfiles:/home/nginx/www/static
       
    ports:
      - 80:80
    depends_on: 
      - app_server
    networks:  # app_server와 private network를 구성해 통신하기 위해 필요한 설정
      - backend

  app_server:
    container_name: app_server
    build: .
    image: app_server:latest
    ports:
      - 8000:8000
    restart: always
    environment:
      DB_PORT: 3306
      DB_HOST_ADDRESS: cie6nasdfnblb.ap-northeast-2.rds.amazonaws.com
    volumes: 
      - ${PWD}:/home/docker/workspace/myapp
    networks:  # nginx와 private network를 구성해 통신하기 위해 필요한 설정
      - backend

    command: gunicorn --workers 1 --bind 0.0.0.0:8000 config.wsgi:application 

networks:
  backend:
    # Use a custom driver
    driver: bridge

- 끝 -

+ Recent posts