Django 탭의 Celery on Nginx 을 기초로 앞에서 작업한 Django & Vite.js 내용을 서버에서 배포하는 과정을 살펴보겠습니다. 이번 페이지는 HTTP 주소로 배포하는 과정 입니다. 이 과정을 마친 뒤 다음 페이지에서 certbot 을 활용한 SSL 배포과정을 살펴보겠습니다.


Procss Map

Django 와 Vite.js 로 빌드된 React.js 프로젝트를 배포하는 경우, 다음 1장의 그림으로 전체적인 Process 를 요약할 수 있습니다.

Django Vite & Nginx

Vite.js 에서 작성한 프론트엔드 빌드된 파일은 WhiteNoise 모듈을 통해서 Django 에서 관리하는 Static files 중 하나로 포함하게 됩니다. WhiteNoise 모듈을 사용함으로써 배포시 압축 및 캐시 활용등의 내용을 Django 에서 관리할 수 있습니다.

이로써 Nginx 에서는 Uvicorn 으로 배포된 Django 설정만 연결하면 서버에서 배포작업의 대부분이 완료 됩니다. 나머지 작업은 Media 폴더들은 용량이 많고 외부 서버에서 관리하는 형태도 많은만큼 이에대한 설정내용을 추가하면 모든 작업이 완료 됩니다. 가장 간단한 작업방법은 배포작업 서버 용량을 어느정도 확보한 뒤, Nginx 의 Reverse Proxy 를 활용하여 배포파일을 관리하는 폴더 및 사용자를 추가하는 방법을 사용하고 있습니다. 이로써 Http 주소로 배포하는 과정을 마무리 했습니다.

도메인 주소를 생성한 뒤 인증서를 추가하여 Https 로 배포하는 과정을 남겨두었습니다. 이 과정은 certbot 을 활용하면 자동으로 인증서를 관리하고, Nginx 에서 Http 주소관리 설정을 입력하면 이를 기초로 자동으로 Https 와 연결하는 설정을 추가해 주기 때문에 앞의 단계에서 SSL 과 관련한 설정들은 모두 비 활성화를 해 주어야 합니다.

Django keeps Redirecting to Https in Local Environment.

Django 에서 SECURE_SSL_REDIRECT = True 설정을 추가한 뒤, 개발환경에서 실행을 1번이라도 하고나면, 배포 사이트 에서 실행한 결과 Localhost 로 Https 가 Redirect 되는 경험을 하게 됩니다. 이는 브라우저 Cache 에 localhost 에서 배포작업이 진행되었던 기록이 남아있어서 강제로 이동하는 것인만큼, 이 설정을 비활성화 하고 그래도 같은 현상이 반복되는 경우 브라우저 Cache 정보를 삭제후 실행 하여야 합니다.

이처럼 SECURE_SSL_REDIRECT 설정값을 개발 작업시 활성화 하지 않도록 주의해야 합니다.

# settings.py
# SECURE_SSL_REDIRECT = True
SECURE_SSL_REDIRECT = False


Nginx 기본

Install

Nginx 를 Ubuntu Apt 으로 설치하면 버전이 Nginx 1.18 로 계속 동일함을 알 수 있습니다. 우분투 저장소에 이 버젼만 올려져 있기 때문인데, 최신버젼을 설치하고 싶은 분들은 ubuntu 22.04 , nginx nginx/1.23.1 내용을 참고 하면 됩니다. 우선은 작업의 일관성을 위해 1.18 버젼으로 진행하도록 하겠습니다.

$ nginx -v                  
nginx version: nginx/1.18.0 (Ubuntu)

Structure

Nginx 의 파일 및 폴더 구조는 다음과 같습니다.

/etc/nginx » tree .
.
├── conf.d <folder>
├── sites-available
│   └── default
├── sites-enabled
│   └── default -> /etc/nginx/sites-available/default
└── nginx.conf

Nginx 의 권한설정 내용Nginx.conf 파일에서 관리를 하고, 가상 호스트 서버 블록 내용은 conf.dsite-available 폴더에서 관리를 합니다. 두 폴더의 구체적인 차이는 Difference in sites-available vs sites-enabled vs conf.d directories 를 참고 합니다.

nginx.conf (Nginx 의 권한설정)

nginx.conf 파일에서는 user 이름값이 중요한데 root 가 아닌 다른 사용자 이름을 추가 합니다. nginx 가 최고권리자에 접근하지 못하도록 설정값을 지정 해야 합니다. 개별 설정 값들에 대한 설명은 nginx 환경 설정 conf 을 참고 합니다.

sites-available/default (Nginx 의 가상 호스트 등록)

localhost 인 http://127.0.0.1 내부 url 주소와 Python Django, Celery, Flower 의 기본 포트 값을 참고하여 다음과 같이 작성하였습니다. flower 설정과 관련된 내용은 링크를 참고 합니다. flower 앱이 업데이트 되면서 celery flower --url_prefix=flower 옵션을 활용하면, Nginx 의 redirect 설정과 flower.js 파일의 수정이 불필요해 졌습니다. 2023-01-23 Changed the url_prefix to rewrite the handlers regex patterns

server {
  listen 80;
  listen [::]:80;
  server_name <사이트.이름>;
  charset utf-8;

  location / {
    proxy_pass http://127.0.0.1:8000;
  }

  # location /static/ {
  #   autoindex on;
  #   alias /home/user/Source/django/staticfiles/;
  #   expires 1d;
  # }

  location /media/ {
    autoindex on;
    alias /home/user/Source/media/;
    expires 1d;
  }

  location /flower/ {
      proxy_pass http://localhost:5555;
  }

  # location ~ ^/flower/? {
  #   sub_filter_last_modified on;
  #   sub_filter_once off;

  #   proxy_pass http://127.0.0.1:5555;
  #   proxy_redirect off;
  #   proxy_set_header Host $host;
  #   proxy_set_header Upgrade $http_upgrade;
  #   proxy_set_header Connection "upgrade";
  #   proxy_http_version 1.1;
  # }
}

Flower Running behine Nginx Reverse Proxy (2023.07)

23년 6월에 flower 2.0.0 이 릴리즈 되면서 배포를 할 때 설정값이 훨씬 쉽게 운영할 수 있게 보완 되었습니다.

server {
    listen 80;
    server_name flower.example.com;

    location /flower/ {
        proxy_pass http://localhost:5555;
    }
}

HTTP

지금까지 설정 내용은 Http 로 배포하는 것을 목표로 작업 하였습니다. 설정 내용 중 HTTPS 와 관련된 내용들은 모두 비 활성화를 해 주었고, 다음 과정에서 SSL 인증서 설치 및 HTTP 주소 요청시 HTTPS 로 ReDirect 실행 등 관련 내용들을 한꺼번에 추가해 보도록 하겠습니다.


Service 등록하기

proxy_pass http://127.0.0.1:8000; 로 연결되는 서비스를 등록해 보도록 하겠습니다. 8000 번 포트 에서 서비스를 배포해야 하는데 서비스가 시작 할 때마다 (우분투 서버가 실행 될 때마다) 자동으로 필요한 명령을 자동으로 실행하도록 예약하는 내용 입니다.

Running with Gunicorn

Django 공식문서 에서도 서버 실행을 위한 미들웨어로 Uvicorn 를 언급하고 있습니다. 아래의 명령어 하나만 실행하면 127.0.0.1:8000 에서 실행되는 내용을 로그에서 확인 가능합니다.

$ gunicorn mysite.asgi:application -w 2 -k uvicorn.workers.UvicornWorker

실행이 확인되었으면 서비스 실행 내용을 다음과 같이 작성 합니다.

  1. User 는 스크립트를 실행하는 우분투 User 의 이름을 입력합니다.
  2. Groupnginx.confuser 이름을 입력 합니다.
$ sudo vi /etc/systemd/system/gunicorn.service
[Unit]
Description=HomePage
After=network.target

[Service]
User=USERNAME
Group=www-data
WorkingDirectory=/home/USERNAME/Source
ExecStart=/home/USERNAME/Python/venv/bin/gunicorn myproject.asgi:application -k uvicorn.workers.UvicornWorker

[Install]
WantedBy=multi-user.target

Daemon Service 등록하기

  1. daemon 과 연결작업을 먼저 한 뒤
  2. System 자동실행 등록 절차를 진행 합니다
  3. 재설정 하는 경우, 서비스를 종료를 한 뒤 새로 연결작업을 진행 해야 합니다.
$ sudo systemctl -h
$ sudo systemctl enable gunicorn
  Created symlink 
  /etc/systemd/system/multi-user.target.wants/gunicorn.service
   /etc/systemd/system/gunicorn.service.

$ sudo systemctl start gunicorn   # 서비스 시작
$ sudo systemctl status gunicorn  # 상태확인
$ sudo systemctl -f stop gunicorn # 멈춤 (재부팅시 재실행 된다)
$ sudo systemctl disable gunicorn # 재부팅시 실행 안함

Daemon Service 삭제하기

서비스 실행에 문제가 있는경우, 다음내용에 따라 등록된 서비스를 삭제 합니다. 보다 상세한 내용은 How to remove systemd services 을 참고 합니다.

$ systemctl stop [servicename]
$ systemctl disable [servicename]
$ rm /etc/systemd/system/[servicename]
$ rm /etc/systemd/system/[servicename] # and symlinks that might be related
$ rm /usr/lib/systemd/system/[servicename] 
$ rm /usr/lib/systemd/system/[servicename] # and symlinks that might be related
$ systemctl daemon-reload
$ systemctl reset-failed


Nginx ETC

Nginx WebDAV

nginx로 WebDAV 서버 구축하기 내용을 참고하여 실행을 해본결과 정상적으로 잘 작동했습니다.

역방향 프록시 설정

Nginx 역방향 프록시 설정


참고사이트

Nginx 와 Multiple Domain

DevOps of Djagno