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번으로의 요청 처럼 리다이렉트 하는 것으로 보인다.
이렇게 하면 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 에 전달하는 것이 가능해 진다.
이를 위한 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
- 끝 -
'Common' 카테고리의 다른 글
opencv: libSM.so.6: cannot open shared object file: No such file or directory (0) | 2023.08.11 |
---|---|
[Django] nginx 와 django container 분리 에러 해결 (0) | 2023.01.18 |
[django] nginx 와 django app 분리 (0) | 2023.01.16 |
[Docker] time zone user input (0) | 2023.01.10 |
[ubuntu] Conflicting values set for option Signed-By regarding source ~ 에러 (0) | 2023.01.09 |